diff --git a/.circleci/config.yml b/.circleci/config.yml index 22539912268..dcf2ba804c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ aliases: - &environment docker: # specify the version you desire here - - image: cimg/node:16.20-browsers + - image: cimg/node:20.14.0-browsers resource_class: xlarge # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images @@ -18,8 +18,6 @@ aliases: - &restore_dep_cache keys: - v1-dependencies-{{ checksum "package.json" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - &save_dep_cache paths: diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 69e13850258..9b1bb6e39cf 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -ARG VARIANT="12" +ARG VARIANT="20" FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:${VARIANT} RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor > /usr/share/keyrings/yarn-archive-keyring.gpg diff --git a/.eslintrc.js b/.eslintrc.js index f17c7a0063d..5b69afa019f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -61,6 +61,7 @@ module.exports = { 'no-useless-escape': 'off', 'no-console': 'error', 'jsdoc/check-types': 'off', + 'jsdoc/no-defaults': 'off', 'jsdoc/newline-after-description': 'off', 'jsdoc/require-jsdoc': 'off', 'jsdoc/require-param': 'off', @@ -89,11 +90,48 @@ module.exports = { name: 'require', message: 'use import instead' } + ], + 'prebid/no-global': [ + 'error', + ...['localStorage', 'sessionStorage'].map(name => ({name, message: 'use storageManager instead'})), + { + name: 'XMLHttpRequest', + message: 'use ajax.js instead' + }, + ], + 'prebid/no-member': [ + 'error', + { + name: 'cookie', + target: 'document', + message: 'use storageManager instead' + }, + { + name: 'sendBeacon', + target: 'navigator', + message: 'use ajax.js instead' + }, + ...['outerText', 'innerText'].map(name => ({ + name, + message: 'use .textContent instead' + })) ] } })).concat([{ // code in other packages (such as plugins/eslint) is not "seen" by babel and its parser will complain. files: 'plugins/*/**/*.js', parser: 'esprima' + }, { + files: '**BidAdapter.js', + rules: { + 'no-restricted-imports': [ + 'error', { + patterns: [ + '**/src/events.js', + '**/src/adloader.js' + ] + } + ] + } }]) }; diff --git a/.github/workflows/jscpd.yml b/.github/workflows/jscpd.yml new file mode 100644 index 00000000000..315fbb2ff09 --- /dev/null +++ b/.github/workflows/jscpd.yml @@ -0,0 +1,124 @@ +name: Check for Duplicated Code + +on: + pull_request_target: + branches: + - master + +jobs: + check-duplication: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for all branches + ref: ${{ github.event.pull_request.head.sha }} + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: | + npm install -g jscpd diff-so-fancy + + - name: Create jscpd config file + run: | + echo '{ + "threshold": 20, + "minTokens": 50, + "reporters": [ + "json" + ], + "output": "./", + "pattern": "**/*.js", + "ignore": "**/*spec.js" + }' > .jscpd.json + + - name: Run jscpd on entire codebase + run: jscpd + + - name: Fetch base and target branches + run: | + git fetch origin +refs/heads/${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }} + git fetch origin +refs/pull/${{ github.event.pull_request.number }}/merge:refs/remotes/pull/${{ github.event.pull_request.number }}/merge + + - name: Get the diff + run: git diff --name-only origin/${{ github.event.pull_request.base.ref }}...refs/remotes/pull/${{ github.event.pull_request.number }}/merge > changed_files.txt + + - name: List generated files (debug) + run: ls -l + + - name: Upload unfiltered jscpd report + if: always() + uses: actions/upload-artifact@v4 + with: + name: unfiltered-jscpd-report + path: ./jscpd-report.json + + - name: Filter jscpd report for changed files + run: | + if [ ! -f ./jscpd-report.json ]; then + echo "jscpd-report.json not found" + exit 1 + fi + echo "Filtering jscpd report for changed files..." + CHANGED_FILES=$(jq -R -s -c 'split("\n")[:-1]' changed_files.txt) + echo "Changed files: $CHANGED_FILES" + jq --argjson changed_files "$CHANGED_FILES" ' + .duplicates | map(select( + (.firstFile?.name as $fname | $changed_files | any(. == $fname)) or + (.secondFile?.name as $sname | $changed_files | any(. == $sname)) + )) + ' ./jscpd-report.json > filtered-jscpd-report.json + cat filtered-jscpd-report.json + + - name: Check if filtered jscpd report exists + id: check_filtered_report + run: | + if [ $(wc -l < ./filtered-jscpd-report.json) -gt 1 ]; then + echo "filtered_report_exists=true" >> $GITHUB_ENV + else + echo "filtered_report_exists=false" >> $GITHUB_ENV + fi + + - name: Upload filtered jscpd report + if: env.filtered_report_exists == 'true' + uses: actions/upload-artifact@v4 + with: + name: filtered-jscpd-report + path: ./filtered-jscpd-report.json + + - name: Post GitHub comment + if: env.filtered_report_exists == 'true' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const filteredReport = JSON.parse(fs.readFileSync('filtered-jscpd-report.json', 'utf8')); + let comment = "Whoa there, partner! 🌵🤠 We wrangled some duplicated code in your PR:\n\n"; + function link(dup) { + return `https://github.com/${{ github.event.repository.full_name }}/blob/${{ github.event.pull_request.head.sha }}/${dup.name}#L${dup.start + 1}-L${dup.end - 1}` + } + filteredReport.forEach(duplication => { + const firstFile = duplication.firstFile; + const secondFile = duplication.secondFile; + const lines = duplication.lines; + comment += `- [\`${firstFile.name}\`](${link(firstFile)}) has ${lines} duplicated lines with [\`${secondFile.name}\`](${link(secondFile)})\n`; + }); + comment += "\nReducing code duplication by importing common functions from a library not only makes our code cleaner but also easier to maintain. Please move the common code from both files into a library and import it in each. We hate that we have to mention this, however, commits designed to hide from this utility by renaming variables or reordering an object are poor conduct. We will not look upon them kindly! Keep up the great work! 🚀"; + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: comment + }); + + - name: Fail if duplications are found + if: env.filtered_report_exists == 'true' + run: | + echo "Duplications found, failing the check." + exit 1 diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml new file mode 100644 index 00000000000..034e0eddee7 --- /dev/null +++ b/.github/workflows/linter.yml @@ -0,0 +1,107 @@ +name: Check for linter warnings / exceptions + +on: + pull_request_target: + branches: + - master + +jobs: + check-linter: + runs-on: ubuntu-latest + + steps: + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.base.sha }} + + - name: Fetch base and target branches + run: | + git fetch origin +refs/heads/${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }} + git fetch origin +refs/pull/${{ github.event.pull_request.number }}/merge:refs/remotes/pull/${{ github.event.pull_request.number }}/merge + + - name: Install dependencies + run: npm ci + + - name: Get the diff + run: git diff --name-only origin/${{ github.event.pull_request.base.ref }}...refs/remotes/pull/${{ github.event.pull_request.number }}/merge | grep '^\(modules\|src\|libraries\|creative\)/.*\.js$' > __changed_files.txt || true + + - name: Run linter on base branch + run: npx eslint --no-inline-config --format json $(cat __changed_files.txt | xargs stat --printf '%n\n' 2> /dev/null) > __base.json || true + + - name: Check out PR + run: git checkout ${{ github.event.pull_request.head.sha }} + + - name: Run linter on PR + run: npx eslint --no-inline-config --format json $(cat __changed_files.txt | xargs stat --printf '%n\n' 2> /dev/null) > __pr.json || true + + - name: Compare them and post comment if necessary + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = require('path'); + const process = require('process'); + + function parse(fn) { + return JSON.parse(fs.readFileSync(fn)).reduce((memo, data) => { + const file = path.relative(process.cwd(), data.filePath); + if (!memo.hasOwnProperty(file)) { memo[file] = { errors: 0, warnings: 0} } + data.messages.forEach(({severity}) => { + memo[file][severity > 1 ? 'errors' : 'warnings']++; + }); + return memo; + }, {}) + } + + function mkDiff(old, new_) { + const files = Object.fromEntries( + Object.entries(new_) + .map(([file, {errors, warnings}]) => { + const {errors: oldErrors, warnings: oldWarnings} = old[file] || {}; + return [file, {errors: Math.max(0, errors - (oldErrors ?? 0)), warnings: Math.max(0, warnings - (oldWarnings ?? 0))}] + }) + .filter(([_, {errors, warnings}]) => errors > 0 || warnings > 0) + ) + return Object.values(files).reduce((memo, {warnings, errors}) => { + memo.errors += errors; + memo.warnings += warnings; + return memo; + }, {errors: 0, warnings: 0, files}) + } + + function mkComment({errors, warnings, files}) { + function pl(noun, number) { + return noun + (number === 1 ? '' : 's') + } + if (errors === 0 && warnings === 0) return; + const summary = []; + if (errors) summary.push(`**${errors}** linter ${pl('error', errors)}`) + if (warnings) summary.push(`**${warnings}** linter ${pl('warning', warnings)}`) + let cm = `Tread carefully! This PR adds ${summary.join(' and ')} (possibly disabled through directives):\n\n`; + Object.entries(files).forEach(([file, {errors, warnings}]) => { + const summary = []; + if (errors) summary.push(`+${errors} ${pl('error', errors)}`); + if (warnings) summary.push(`+${warnings} ${pl('warning', warnings)}`) + cm += ` * \`${file}\` (${summary.join(', ')})\n` + }) + return cm; + } + + const [base, pr] = ['__base.json', '__pr.json'].map(parse); + const comment = mkComment(mkDiff(base, pr)); + + if (comment) { + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: comment + }); + } diff --git a/.nvmrc b/.nvmrc index 66df3b7ab2d..f203ab89b79 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -12.16.1 +20.13.1 diff --git a/PR_REVIEW.md b/PR_REVIEW.md index 9deac9963fb..f6a2c157d2d 100644 --- a/PR_REVIEW.md +++ b/PR_REVIEW.md @@ -23,10 +23,11 @@ General gulp commands include separate commands for serving the codebase on a bu - Checkout the branch (these instructions are available on the GitHub PR page as well). - Verify PR is a single change type. Example, refactor OR bugfix. If more than 1 type, ask submitter to break out requests. - Verify code under review has at least 80% unit test coverage. If legacy code doesn't have enough unit test coverage, require that additional unit tests to be included in the PR. -- Verify tests are green in Travis-ci + local build by running `gulp serve` | `gulp test` +- Verify tests are green in circle-ci + local build by running `gulp serve` | `gulp test` - Verify no code quality violations are present from linting (should be reported in terminal) - Make sure the code is not setting cookies or localstorage directly -- it must use the `StorageManager`. - Review for obvious errors or bad coding practice / use best judgement here. +- Don't allow needless code duplication with other js files; require both files import common code. Do not allow commits designed to fool the code duplication checker. - If the change is a new feature / change to core prebid.js - review the change with a Tech Lead on the project and make sure they agree with the nature of change. - If the change results in needing updates to docs (such as public API change, module interface etc), add a label for "needs docs" and inform the submitter they must submit a docs PR to update the appropriate area of Prebid.org **before the PR can merge**. Help them with finding where the docs are located on prebid.org if needed. - If all above is good, add a `LGTM` comment and, if the change is in PBS-core or is an important module like the prebidServerBidAdapter, request 1 additional core member to review. @@ -51,20 +52,21 @@ Follow steps above for general review process. In addition, please verify the fo - If the adapter being submitted is an alias type, check with the bidder contact that is being aliased to make sure it's allowed. - All bidder parameter conventions must be followed: - Video params must be read from AdUnit.mediaTypes.video when available; however bidder config can override the ad unit. - - First party data must be read from [getConfig('ortb2');](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd). + - First party data must be read from the bid request object: bidrequest.ortb2 - Adapters that accept a floor parameter must also support the [floors module](https://docs.prebid.org/dev-docs/modules/floors.html) -- look for a call to the `getFloor()` function. - Adapters cannot accept an schain parameter. Rather, they must look for the schain parameter at bidRequest.schain. - The bidderRequest.refererInfo.referer must be checked in addition to any bidder-specific parameter. - Page position must come from bidrequest.mediaTypes.banner.pos or bidrequest.mediaTypes.video.pos - - Global OpenRTB fields should come from [getConfig('ortb2');](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd): + - Eids object is to be preferred to Userids object in the bid request, as the userid object may be removed in a future version + - Global OpenRTB fields should come from bidrequest.ortb2 - bcat, battr, badv - Impression-specific OpenRTB fields should come from bidrequest.ortb2imp - instl - Below are some examples of bidder specific updates that should require docs update (in their dev-docs/bidders/BIDDER.md file): - - If they support the GDPR consentManagement module and TCF1, add `gdpr_supported: true` - - If they support the GDPR consentManagement module and TCF2, add `tcf2_supported: true` + - If they support the TCF consentManagementTcf module and TCF2, add `tcf2_supported: true` - If they support the US Privacy consentManagementUsp module, add `usp_supported: true` - - If they support one or more userId modules, add `userId: (list of supported vendors)` + - If they support the GPP consentManagementGpp module, add `gpp_supported: true` + - If they support one or more userId modules, add `userId: (list of supported vendors) or (all)` - If they support video and/or native mediaTypes add `media_types: video, native`. Note that display is added by default. If you don't support display, add "no-display" as the first entry, e.g. `media_types: no-display, native` - If they support COPPA, add `coppa_supported: true` - If they support SChain, add `schain_supported: true` @@ -100,7 +102,7 @@ Follow steps above for general review process. In addition: - modules/userId/userId.md - tests can go either within the userId_spec.js file or in their own _spec file if they wish - GVLID is recommended in the *IdSystem file if they operate in EU -- make sure example configurations align to the actual code (some modules use the userId storage settings and allow pub configuration, while others handle reading/writing cookies on their own, so should not include the storage params in examples) +- make sure example configurations align to the actual code (some modules use the userId storage settings and allow pub configuration, while others handle reading/writing cookies on their own, so should not include the storage params in examples). This ability to write will be removed in a future version, see https://github.com/prebid/Prebid.js/issues/10710 - the 3 available methods (getId, extendId, decode) should be used as they were intended - decode (required method) should not be making requests to retrieve a new ID, it should just be decoding a response - extendId (optional method) should not be making requests to retrieve a new ID, it should just be adding additional data to the id object @@ -121,6 +123,7 @@ Follow steps above for general review process. In addition: - Confirm that the module - is not loading external code. If it is, escalate to the #prebid-js Slack channel. - is reading `config` from the function signature rather than calling `getConfig`. + - Is practicing reasonable data minimization, eg not sending all eids over the wire without publisher whitelisting - is sending data to the bid request only as either First Party Data or in bidRequest.rtd.RTDPROVIDERCODE. - is making HTTPS requests as early as possible, but not more often than needed. - doesn't force bid adapters to load additional code. diff --git a/allowedModules.js b/allowedModules.js index bc9ada39571..dbcae2db2cc 100644 --- a/allowedModules.js +++ b/allowedModules.js @@ -1,7 +1,6 @@ module.exports = { 'modules': [ - 'criteo-direct-rsa-validate', 'crypto-js', 'live-connect' // Maintained by LiveIntent : https://github.com/liveintent-berlin/live-connect/ ], diff --git a/browsers.json b/browsers.json index bd6bd5772d6..0649a13e873 100644 --- a/browsers.json +++ b/browsers.json @@ -1,39 +1,39 @@ { - "bs_edge_latest_windows_10": { + "bs_edge_latest_windows_11": { "base": "BrowserStack", - "os_version": "10", + "os_version": "11", "browser": "edge", "browser_version": "latest", "device": null, "os": "Windows" }, - "bs_chrome_latest_windows_10": { + "bs_chrome_latest_windows_11": { "base": "BrowserStack", - "os_version": "10", + "os_version": "11", "browser": "chrome", "browser_version": "latest", "device": null, "os": "Windows" }, - "bs_chrome_87_windows_10": { + "bs_chrome_107_windows_10": { "base": "BrowserStack", "os_version": "10", "browser": "chrome", - "browser_version": "87.0", + "browser_version": "107.0", "device": null, "os": "Windows" }, - "bs_firefox_latest_windows_10": { + "bs_firefox_latest_windows_11": { "base": "BrowserStack", - "os_version": "10", + "os_version": "11", "browser": "firefox", "browser_version": "latest", "device": null, "os": "Windows" }, - "bs_safari_latest_mac_bigsur": { + "bs_safari_latest_mac": { "base": "BrowserStack", - "os_version": "Big Sur", + "os_version": "Sonoma", "browser": "safari", "browser_version": "latest", "device": null, @@ -41,11 +41,11 @@ }, "bs_safari_15_catalina": { "base": "BrowserStack", - "os_version": "Catalina", + "os_version": "Monterey", "browser": "safari", - "browser_version": "13.1", + "browser_version": "15.6", "device": null, "os": "OS X" } - + } diff --git a/creative/constants.js b/creative/constants.js index d02c4c9d5e4..5f807c69f87 100644 --- a/creative/constants.js +++ b/creative/constants.js @@ -1,6 +1,7 @@ // eslint-disable-next-line prebid/validate-imports -import { AD_RENDER_FAILED_REASON, EVENTS, MESSAGES } from '../src/constants.js'; +import {AD_RENDER_FAILED_REASON, EVENTS, MESSAGES} from '../src/constants.js'; +export {PB_LOCATOR} from '../src/constants.js'; export const MESSAGE_REQUEST = MESSAGES.REQUEST; export const MESSAGE_RESPONSE = MESSAGES.RESPONSE; export const MESSAGE_EVENT = MESSAGES.EVENT; diff --git a/creative/crossDomain.js b/creative/crossDomain.js index a851885bfc0..d3524f61d4b 100644 --- a/creative/crossDomain.js +++ b/creative/crossDomain.js @@ -1,9 +1,11 @@ import { ERROR_EXCEPTION, - EVENT_AD_RENDER_FAILED, EVENT_AD_RENDER_SUCCEEDED, + EVENT_AD_RENDER_FAILED, + EVENT_AD_RENDER_SUCCEEDED, MESSAGE_EVENT, MESSAGE_REQUEST, - MESSAGE_RESPONSE + MESSAGE_RESPONSE, + PB_LOCATOR } from './constants.js'; const mkFrame = (() => { @@ -24,14 +26,27 @@ const mkFrame = (() => { }; })(); +function isPrebidWindow(win) { + return !!win.frames[PB_LOCATOR]; +} + export function renderer(win) { + let target = win.parent; + try { + while (target !== win.top && !isPrebidWindow(target)) { + target = target.parent; + } + if (!isPrebidWindow(target)) target = win.parent; + } catch (e) { + } + return function ({adId, pubUrl, clickUrl}) { const pubDomain = new URL(pubUrl, window.location).origin; function sendMessage(type, payload, responseListener) { const channel = new MessageChannel(); channel.port1.onmessage = guard(responseListener); - win.parent.postMessage(JSON.stringify(Object.assign({message: type, adId}, payload)), pubDomain, [channel.port2]); + target.postMessage(JSON.stringify(Object.assign({message: type, adId}, payload)), pubDomain, [channel.port2]); } function onError(e) { @@ -77,7 +92,7 @@ export function renderer(win) { W.Promise.resolve(W.render(data, {sendMessage, mkFrame}, win)).then( () => sendMessage(MESSAGE_EVENT, {event: EVENT_AD_RENDER_SUCCEEDED}), onError - ) + ); }); win.document.body.appendChild(renderer); } diff --git a/gulpfile.js b/gulpfile.js index 86c1b7fe509..a32a2d11ce6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -147,6 +147,17 @@ function makeVerbose(config = webpackConfig) { }); } +function prebidSource(webpackCfg) { + var externalModules = helpers.getArgModules(); + + const analyticsSources = helpers.getAnalyticsSources(); + const moduleSources = helpers.getModulePaths(externalModules); + + return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js')) + .pipe(helpers.nameModules(externalModules)) + .pipe(webpackStream(webpackCfg, webpack)); +} + function makeDevpackPkg(config = webpackConfig) { return function() { var cloned = _.cloneDeep(config); @@ -163,14 +174,7 @@ function makeDevpackPkg(config = webpackConfig) { .filter((use) => use.loader === 'babel-loader') .forEach((use) => use.options = Object.assign({}, use.options, babelConfig)); - var externalModules = helpers.getArgModules(); - - const analyticsSources = helpers.getAnalyticsSources(); - const moduleSources = helpers.getModulePaths(externalModules); - - return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js')) - .pipe(helpers.nameModules(externalModules)) - .pipe(webpackStream(cloned, webpack)) + return prebidSource(cloned) .pipe(gulp.dest('build/dev')) .pipe(connect.reload()); } @@ -183,14 +187,7 @@ function makeWebpackPkg(config = webpackConfig) { } return function buildBundle() { - var externalModules = helpers.getArgModules(); - - const analyticsSources = helpers.getAnalyticsSources(); - const moduleSources = helpers.getModulePaths(externalModules); - - return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js')) - .pipe(helpers.nameModules(externalModules)) - .pipe(webpackStream(cloned, webpack)) + return prebidSource(cloned) .pipe(gulp.dest('build/dist')); } } @@ -413,7 +410,9 @@ function runKarma(options, done) { // the karma server appears to leak memory; starting it multiple times in a row will run out of heap // here we run it in a separate process to bypass the problem options = Object.assign({browsers: helpers.parseBrowserArgs(argv)}, options) - const child = fork('./karmaRunner.js'); + const child = fork('./karmaRunner.js', null, { + env: Object.assign({}, options.env, process.env) + }); child.on('exit', (exitCode) => { if (exitCode) { done(new Error('Karma tests failed with exit code ' + exitCode)); @@ -426,7 +425,15 @@ function runKarma(options, done) { // If --file "" is given, the task will only run tests in the specified file. function testCoverage(done) { - runKarma({coverage: true, browserstack: false, watch: false, file: argv.file}, done); + runKarma({ + coverage: true, + browserstack: false, + watch: false, + file: argv.file, + env: { + NODE_OPTIONS: '--max-old-space-size=8096' + } + }, done); } function coveralls() { // 2nd arg is a dependency: 'test' must be finished diff --git a/integrationExamples/gpt/creative_rendering.html b/integrationExamples/gpt/creative_rendering.html deleted file mode 100644 index 04d4736c631..00000000000 --- a/integrationExamples/gpt/creative_rendering.html +++ /dev/null @@ -1,15 +0,0 @@ - - diff --git a/integrationExamples/gpt/idward_segments_example.html b/integrationExamples/gpt/idward_segments_example.html deleted file mode 100644 index 9bc06124c77..00000000000 --- a/integrationExamples/gpt/idward_segments_example.html +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
-
First Party Data (ortb2) Sent to Bidding Adapter
-
- - diff --git a/integrationExamples/gpt/fledge_example.html b/integrationExamples/gpt/paapi_example.html similarity index 97% rename from integrationExamples/gpt/fledge_example.html rename to integrationExamples/gpt/paapi_example.html index 5a6ab7a5fef..860d7c22edf 100644 --- a/integrationExamples/gpt/fledge_example.html +++ b/integrationExamples/gpt/paapi_example.html @@ -3,7 +3,7 @@ diff --git a/integrationExamples/gpt/prebidServer_fledge_example.html b/integrationExamples/gpt/prebidServer_paapi_example.html similarity index 91% rename from integrationExamples/gpt/prebidServer_fledge_example.html rename to integrationExamples/gpt/prebidServer_paapi_example.html index eb2fc438997..d138d2b7753 100644 --- a/integrationExamples/gpt/prebidServer_fledge_example.html +++ b/integrationExamples/gpt/prebidServer_paapi_example.html @@ -3,7 +3,7 @@ @@ -44,8 +44,8 @@ pbjs.que.push(function() { pbjs.setConfig({ - fledgeForGpt: { - enabled: true + paapi: { + enabled: true, }, s2sConfig: [{ accountId : '1', @@ -57,13 +57,6 @@ }] }); - pbjs.setBidderConfig({ - bidders: ['openx'], - config: { - fledgeEnabled: true - } - }); - pbjs.addAdUnits(adUnits); pbjs.requestBids({ diff --git a/integrationExamples/gpt/raynRtdProvider_example.html b/integrationExamples/gpt/raynRtdProvider_example.html index 2d43c37513a..7965daa6e85 100644 --- a/integrationExamples/gpt/raynRtdProvider_example.html +++ b/integrationExamples/gpt/raynRtdProvider_example.html @@ -6,6 +6,7 @@ "3": ["264", "267", "261"], "4": ["438"] }, + "103015": ['agdv23', 'avscg3'], "903555595": { "7": { "2": ["51", "246"] diff --git a/integrationExamples/gpt/x-domain/creative.html b/integrationExamples/gpt/x-domain/creative.html index 0d0f63cbf1b..63842b00882 100644 --- a/integrationExamples/gpt/x-domain/creative.html +++ b/integrationExamples/gpt/x-domain/creative.html @@ -2,7 +2,7 @@ // creative will be rendered, e.g. GAM delivering a SafeFrame // this code is autogenerated, also available in 'build/creative/creative.js' - + + +
+ + + + `; +} + +export function getAd(bid) { + let ad, adUrl, vastXml, vastUrl; + + switch (deepAccess(bid, 'ext.prebid.type')) { + case VIDEO: + if (bid.adm.substr(0, 4) === 'http') { + vastUrl = bid.adm; + } else { + vastXml = bid.adm; + }; + break; + default: + if (bid.adm && bid.nurl) { + ad = bid.adm; + ad += createTrackPixelHtml(decodeURIComponent(bid.nurl)); + } else if (bid.adm) { + ad = bid.adm; + } else if (bid.nurl) { + adUrl = bid.nurl; + }; + } + + return {ad, adUrl, vastXml, vastUrl}; +} + +export function getSiteObj() { + const refInfo = (getRefererInfo && getRefererInfo()) || {}; + + return { + page: refInfo.page, + ref: refInfo.ref, + domain: refInfo.domain + } +} diff --git a/libraries/targetVideoUtils/constants.js b/libraries/targetVideoUtils/constants.js new file mode 100644 index 00000000000..8ce94c0eaeb --- /dev/null +++ b/libraries/targetVideoUtils/constants.js @@ -0,0 +1,23 @@ +const SOURCE = 'pbjs'; +const GVLID = 786; +const MARGIN = 1.35; +const BIDDER_CODE = 'targetVideo'; + +const TIME_TO_LIVE = 300; +const BANNER_ENDPOINT_URL = 'https://ib.adnxs.com/ut/v3/prebid'; +const VIDEO_ENDPOINT_URL = 'https://pbs.prebrid.tv/openrtb2/auction'; +const VIDEO_PARAMS = [ + 'api', 'linearity', 'maxduration', 'mimes', 'minduration', + 'plcmt', 'playbackmethod', 'protocols', 'startdelay' +]; + +export { + SOURCE, + GVLID, + MARGIN, + BIDDER_CODE, + TIME_TO_LIVE, + BANNER_ENDPOINT_URL, + VIDEO_ENDPOINT_URL, + VIDEO_PARAMS +} diff --git a/libraries/teqblazeUtils/bidderUtils.js b/libraries/teqblazeUtils/bidderUtils.js new file mode 100644 index 00000000000..ce061ac7f3c --- /dev/null +++ b/libraries/teqblazeUtils/bidderUtils.js @@ -0,0 +1,257 @@ +import { BANNER, NATIVE, VIDEO } from '../../src/mediaTypes.js'; +import { deepAccess } from '../../src/utils.js'; +import { config } from '../../src/config.js'; + +const PROTOCOL_PATTERN = /^[a-z0-9.+-]+:/i; + +const isBidResponseValid = (bid) => { + if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { + return false; + } + + switch (bid.mediaType) { + case BANNER: + return Boolean(bid.width && bid.height && bid.ad); + case VIDEO: + return Boolean(bid.vastUrl || bid.vastXml); + case NATIVE: + return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); + default: + return false; + } +}; + +const getBidFloor = (bid) => { + try { + const bidFloor = bid.getFloor({ + currency: 'USD', + mediaType: '*', + size: '*', + }); + + return bidFloor.floor; + } catch (err) { + return 0; + } +}; + +const createBasePlacement = (bid) => { + const { bidId, mediaTypes, transactionId, userIdAsEids } = bid; + const schain = bid.schain || {}; + const bidfloor = getBidFloor(bid); + + const placement = { + bidId, + schain, + bidfloor + }; + + if (mediaTypes && mediaTypes[BANNER]) { + placement.adFormat = BANNER; + placement.sizes = mediaTypes[BANNER].sizes; + } else if (mediaTypes && mediaTypes[VIDEO]) { + placement.adFormat = VIDEO; + placement.playerSize = mediaTypes[VIDEO].playerSize; + placement.minduration = mediaTypes[VIDEO].minduration; + placement.maxduration = mediaTypes[VIDEO].maxduration; + placement.mimes = mediaTypes[VIDEO].mimes; + placement.protocols = mediaTypes[VIDEO].protocols; + placement.startdelay = mediaTypes[VIDEO].startdelay; + placement.placement = mediaTypes[VIDEO].placement; + placement.plcmt = mediaTypes[VIDEO].plcmt; + placement.skip = mediaTypes[VIDEO].skip; + placement.skipafter = mediaTypes[VIDEO].skipafter; + placement.minbitrate = mediaTypes[VIDEO].minbitrate; + placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; + placement.delivery = mediaTypes[VIDEO].delivery; + placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; + placement.api = mediaTypes[VIDEO].api; + placement.linearity = mediaTypes[VIDEO].linearity; + } else if (mediaTypes && mediaTypes[NATIVE]) { + placement.native = mediaTypes[NATIVE]; + placement.adFormat = NATIVE; + } + + if (transactionId) { + placement.ext = placement.ext || {}; + placement.ext.tid = transactionId; + } + + if (userIdAsEids && userIdAsEids.length) { + placement.eids = userIdAsEids; + } + + return placement; +}; + +const defaultPlacementType = (bid, bidderRequest, placement) => { + const { placementId, endpointId } = bid.params; + + if (placementId) { + placement.placementId = placementId; + placement.type = 'publisher'; + } else if (endpointId) { + placement.endpointId = endpointId; + placement.type = 'network'; + } +}; + +const checkIfObjectHasKey = (keys, obj, mode = 'some') => { + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = obj[key]; + + if (mode === 'some' && val) return true; + if (!val) return false; + } + + return mode === 'every'; +} + +export const isBidRequestValid = (keys = ['placementId', 'endpointId'], mode) => (bid = {}) => { + const { params, bidId, mediaTypes } = bid; + let valid = Boolean(bidId && params && checkIfObjectHasKey(keys, params, mode)); + + if (mediaTypes && mediaTypes[BANNER]) { + valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); + } else if (mediaTypes && mediaTypes[VIDEO]) { + valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); + } else if (mediaTypes && mediaTypes[NATIVE]) { + valid = valid && Boolean(mediaTypes[NATIVE]); + } else { + valid = false; + } + + return valid; +}; + +/** + * @param {{ adUrl, validBidRequests, bidderRequest, placementProcessingFunction }} config + * @returns {function} + */ +export const buildRequestsBase = (config) => { + const { adUrl, validBidRequests, bidderRequest } = config; + const placementProcessingFunction = config.placementProcessingFunction || buildPlacementProcessingFunction(); + const device = deepAccess(bidderRequest, 'ortb2.device'); + const page = deepAccess(bidderRequest, 'refererInfo.page', ''); + + const proto = PROTOCOL_PATTERN.exec(page); + const protocol = proto?.[0]; + + const placements = []; + const request = { + deviceWidth: device?.w || 0, + deviceHeight: device?.h || 0, + language: device?.language?.split('-')[0] || '', + secure: protocol === 'https:' ? 1 : 0, + host: deepAccess(bidderRequest, 'refererInfo.domain', ''), + page, + placements, + coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0, + tmax: bidderRequest.timeout + }; + + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + + if (bidderRequest.gdprConsent) { + request.gdpr = { + consentString: bidderRequest.gdprConsent.consentString + }; + } + + if (bidderRequest.gppConsent) { + request.gpp = bidderRequest.gppConsent.gppString; + request.gpp_sid = bidderRequest.gppConsent.applicableSections; + } else if (bidderRequest.ortb2?.regs?.gpp) { + request.gpp = bidderRequest.ortb2.regs.gpp; + request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; + } + + const len = validBidRequests.length; + for (let i = 0; i < len; i++) { + const bid = validBidRequests[i]; + placements.push(placementProcessingFunction(bid, bidderRequest)); + } + + return { + method: 'POST', + url: adUrl, + data: request + }; +}; + +export const buildRequests = (adUrl) => (validBidRequests = [], bidderRequest = {}) => { + const placementProcessingFunction = buildPlacementProcessingFunction(); + + return buildRequestsBase({ adUrl, validBidRequests, bidderRequest, placementProcessingFunction }); +}; + +export function interpretResponseBuilder({addtlBidValidation = (bid) => true} = {}) { + return function (serverResponse) { + let response = []; + for (let i = 0; i < serverResponse.body.length; i++) { + let resItem = serverResponse.body[i]; + if (isBidResponseValid(resItem) && addtlBidValidation(resItem)) { + const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; + resItem.meta = { ...resItem.meta, advertiserDomains }; + + response.push(resItem); + } + } + + return response; + } +} + +export const interpretResponse = interpretResponseBuilder(); + +export const getUserSyncs = (syncUrl) => (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => { + const type = syncOptions.iframeEnabled ? 'iframe' : 'image'; + let url = syncUrl + `/${type}?pbjs=1`; + + if (gdprConsent && gdprConsent.consentString) { + if (typeof gdprConsent.gdprApplies === 'boolean') { + url += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; + } else { + url += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; + } + } + + if (uspConsent && uspConsent.consentString) { + url += `&ccpa_consent=${uspConsent.consentString}`; + } + + if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { + url += '&gpp=' + gppConsent.gppString; + url += '&gpp_sid=' + gppConsent.applicableSections.join(','); + } + + const coppa = config.getConfig('coppa') ? 1 : 0; + url += `&coppa=${coppa}`; + + return [{ + type, + url + }]; +}; + +/** + * + * @param {{ addPlacementType?: function, addCustomFieldsToPlacement?: function }} [config] + * @returns {function(object, object): object} + */ +export const buildPlacementProcessingFunction = (config) => (bid, bidderRequest) => { + const addPlacementType = config?.addPlacementType ?? defaultPlacementType; + + const placement = createBasePlacement(bid); + + addPlacementType(bid, bidderRequest, placement); + + if (config?.addCustomFieldsToPlacement) { + config.addCustomFieldsToPlacement(bid, bidderRequest, placement); + } + + return placement; +}; diff --git a/libraries/userAgentUtils/index.js b/libraries/userAgentUtils/index.js new file mode 100644 index 00000000000..7300bbd519a --- /dev/null +++ b/libraries/userAgentUtils/index.js @@ -0,0 +1,58 @@ +import { deviceTypes, browserTypes, osTypes } from './userAgentTypes.enums.js'; + +/** + * Get the approximate device type enum from the user agent + * @returns {number} + */ +export const getDeviceType = () => { + if ( + /ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test( + navigator.userAgent.toLowerCase() + ) + ) return deviceTypes.TABLET; + if ( + /iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test( + navigator.userAgent.toLowerCase() + ) + ) return deviceTypes.MOBILE; + return deviceTypes.DESKTOP; +}; + +/** + * Get the approximate browser type enum from the user agent (or vendor + * if available) + * @returns {number} + */ +export const getBrowser = () => { + if (/Edg/.test(navigator.userAgent)) return browserTypes.EDGE; + else if ( + /Chrome/.test(navigator.userAgent) && + /Google Inc/.test(navigator.vendor) + ) return browserTypes.CHROME; + else if (navigator.userAgent.match('CriOS')) return browserTypes.CHROME; + else if (/Firefox/.test(navigator.userAgent)) return browserTypes.FIREFOX; + else if ( + /Safari/.test(navigator.userAgent) && + /Apple Computer/.test(navigator.vendor) + ) return browserTypes.SAFARI; + else if ( + /Trident/.test(navigator.userAgent) || + /MSIE/.test(navigator.userAgent) + ) return browserTypes.INTERNET_EXPLORER; + else return browserTypes.OTHER; +}; + +/** + * Get the approximate OS enum from the user agent (or app version, + * if available) + * @returns {number} + */ +export const getOS = () => { + if (navigator.userAgent.indexOf('Android') != -1) return osTypes.ANDROID; + if (navigator.userAgent.indexOf('like Mac') != -1) return osTypes.IOS; + if (navigator.userAgent.indexOf('Win') != -1) return osTypes.WINDOWS; + if (navigator.userAgent.indexOf('Mac') != -1) return osTypes.MAC; + if (navigator.userAgent.indexOf('Linux') != -1) return osTypes.LINUX; + if (navigator.appVersion.indexOf('X11') != -1) return osTypes.UNIX; + return osTypes.OTHER; +}; diff --git a/libraries/userAgentUtils/userAgentTypes.enums.js b/libraries/userAgentUtils/userAgentTypes.enums.js new file mode 100644 index 00000000000..8a0255e88bf --- /dev/null +++ b/libraries/userAgentUtils/userAgentTypes.enums.js @@ -0,0 +1,22 @@ +export const deviceTypes = Object.freeze({ + DESKTOP: 0, + MOBILE: 1, + TABLET: 2, +}) +export const browserTypes = Object.freeze({ + CHROME: 0, + FIREFOX: 1, + SAFARI: 2, + EDGE: 3, + INTERNET_EXPLORER: 4, + OTHER: 5 +}) +export const osTypes = Object.freeze({ + WINDOWS: 0, + MAC: 1, + LINUX: 2, + UNIX: 3, + IOS: 4, + ANDROID: 5, + OTHER: 6 +}) diff --git a/libraries/vidazooUtils/bidderUtils.js b/libraries/vidazooUtils/bidderUtils.js new file mode 100644 index 00000000000..2adf5c12324 --- /dev/null +++ b/libraries/vidazooUtils/bidderUtils.js @@ -0,0 +1,480 @@ +import { + _each, + deepAccess, + formatQS, + isArray, + isFn, + parseSizesInput, + parseUrl, + triggerPixel, + uniques +} from '../../src/utils.js'; +import {chunk} from '../chunk/chunk.js'; +import {CURRENCY, DEAL_ID_EXPIRY, SESSION_ID_KEY, TTL_SECONDS, UNIQUE_DEAL_ID_EXPIRY} from './constants.js'; +import {bidderSettings} from '../../src/bidderSettings.js'; +import {config} from '../../src/config.js'; +import {BANNER, VIDEO} from '../../src/mediaTypes.js'; + +export function createSessionId() { + return 'wsid_' + parseInt(Date.now() * Math.random()); +} + +export function getTopWindowQueryParams() { + try { + const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + return parsedUrl.search; + } catch (e) { + return ''; + } +} + +export function extractCID(params) { + return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; +} + +export function extractPID(params) { + return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; +} + +export function extractSubDomain(params) { + return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; +} + +export function isBidRequestValid(bid) { + const params = bid.params || {}; + return !!(extractCID(params) && extractPID(params)); +} + +export function tryParseJSON(value) { + try { + return JSON.parse(value); + } catch (e) { + return value; + } +} + +export function setStorageItem(storage, key, value, timestamp) { + try { + const created = timestamp || Date.now(); + const data = JSON.stringify({value, created}); + storage.setDataInLocalStorage(key, data); + } catch (e) { + } +} + +export function getStorageItem(storage, key) { + try { + return tryParseJSON(storage.getDataFromLocalStorage(key, null)); + } catch (e) { + } + + return null; +} + +export function getCacheOpt(storage, useKey) { + let data = storage.getDataFromLocalStorage(useKey, null); + if (!data) { + data = String(Date.now()); + storage.setDataInLocalStorage(useKey, data, null); + } + + return data; +} + +export function getUniqueDealId(storage, key, expiry = UNIQUE_DEAL_ID_EXPIRY) { + const storageKey = `u_${key}`; + const now = Date.now(); + const data = getStorageItem(storage, storageKey); + let uniqueId; + + if (!data || !data.value || now - data.created > expiry) { + uniqueId = `${key}_${now.toString()}`; + setStorageItem(storage, storageKey, uniqueId); + } else { + uniqueId = data.value; + } + + return uniqueId; +} + +export function getNextDealId(storage, key, expiry = DEAL_ID_EXPIRY) { + try { + const data = getStorageItem(storage, key); + let currentValue = 0; + let timestamp; + + if (data && data.value && Date.now() - data.created < expiry) { + currentValue = data.value; + timestamp = data.created; + } + + const nextValue = currentValue + 1; + setStorageItem(storage, key, nextValue, timestamp); + return nextValue; + } catch (e) { + return 0; + } +} + +export function hashCode(s, prefix = '_') { + const l = s.length; + let h = 0 + let i = 0; + if (l > 0) { + while (i < l) { + h = (h << 5) - h + s.charCodeAt(i++) | 0; + } + } + return prefix + h; +} + +export function onBidWon(bid) { + if (!bid.nurl) { + return; + } + const wonBid = { + adId: bid.adId, + creativeId: bid.creativeId, + auctionId: bid.auctionId, + transactionId: bid.transactionId, + adUnitCode: bid.adUnitCode, + cpm: bid.cpm, + currency: bid.currency, + originalCpm: bid.originalCpm, + originalCurrency: bid.originalCurrency, + netRevenue: bid.netRevenue, + mediaType: bid.mediaType, + timeToRespond: bid.timeToRespond, + status: bid.status, + }; + const qs = formatQS(wonBid); + const url = bid.nurl + (bid.nurl.indexOf('?') === -1 ? '?' : '&') + qs; + triggerPixel(url); +} + +/** + * Create the spec function for getting user syncs + * + * The options object accepts the following fields: + * + * - iframeSyncUrl + * - imageSyncUrl + * + * @param options + */ +export function createUserSyncGetter(options = { + iframeSyncUrl: '', + imageSyncUrl: '' +}) { + return function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '', gppConsent = {}) { + const syncs = []; + const {iframeEnabled, pixelEnabled} = syncOptions; + const {gdprApplies, consentString = ''} = gdprConsent; + const {gppString, applicableSections} = gppConsent; + + const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); + let params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}`; + + if (gppString && applicableSections?.length) { + params += '&gpp=' + encodeURIComponent(gppString); + params += '&gpp_sid=' + encodeURIComponent(applicableSections.join(',')); + } + + if (iframeEnabled && options.iframeSyncUrl) { + syncs.push({ + type: 'iframe', + url: `${options.iframeSyncUrl}/${params}` + }); + } + if (pixelEnabled && options.imageSyncUrl) { + syncs.push({ + type: 'image', + url: `${options.imageSyncUrl}/${params}` + }); + } + return syncs; + } +} + +export function appendUserIdsToRequestPayload(payloadRef, userIds) { + let key; + _each(userIds, (userId, idSystemProviderName) => { + key = `uid.${idSystemProviderName}`; + + switch (idSystemProviderName) { + case 'lipb': + payloadRef[key] = userId.lipbid; + break; + case 'id5id': + payloadRef[key] = userId.uid; + break; + default: + payloadRef[key] = userId; + } + }); +} + +export function getVidazooSessionId(storage) { + return getStorageItem(storage, SESSION_ID_KEY) || ''; +} + +export function buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout, storage, bidderVersion, bidderCode, getUniqueRequestData) { + const { + params, + bidId, + userId, + adUnitCode, + schain, + mediaTypes, + ortb2Imp, + bidderRequestId, + bidRequestsCount, + bidderRequestsCount, + bidderWinsCount + } = bid; + const {ext} = params; + let {bidFloor} = params; + const hashUrl = hashCode(topWindowUrl); + const uniqueRequestData = isFn(getUniqueRequestData) ? getUniqueRequestData(hashUrl, bid) : {}; + const uniqueDealId = getUniqueDealId(storage, hashUrl); + const pId = extractPID(params); + const isStorageAllowed = bidderSettings.get(bidderCode, 'storageAllowed'); + + const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', ''); + const cat = deepAccess(bidderRequest, 'ortb2.site.cat', []); + const pagecat = deepAccess(bidderRequest, 'ortb2.site.pagecat', []); + const contentData = deepAccess(bidderRequest, 'ortb2.site.content.data', []); + const userData = deepAccess(bidderRequest, 'ortb2.user.data', []); + + if (isFn(bid.getFloor)) { + const floorInfo = bid.getFloor({ + currency: 'USD', + mediaType: '*', + size: '*' + }); + + if (floorInfo.currency === 'USD') { + bidFloor = floorInfo.floor; + } + } + + let data = { + url: encodeURIComponent(topWindowUrl), + uqs: getTopWindowQueryParams(), + cb: Date.now(), + bidFloor: bidFloor, + bidId: bidId, + referrer: bidderRequest.refererInfo.ref, + adUnitCode: adUnitCode, + publisherId: pId, + sizes: sizes, + uniqueDealId: uniqueDealId, + bidderVersion: bidderVersion, + prebidVersion: '$prebid.version$', + res: `${screen.width}x${screen.height}`, + schain: schain, + mediaTypes: mediaTypes, + isStorageAllowed: isStorageAllowed, + gpid: gpid, + cat: cat, + contentData, + userData: userData, + pagecat: pagecat, + transactionId: ortb2Imp?.ext?.tid, + bidderRequestId: bidderRequestId, + bidRequestsCount: bidRequestsCount, + bidderRequestsCount: bidderRequestsCount, + bidderWinsCount: bidderWinsCount, + bidderTimeout: bidderTimeout, + ...uniqueRequestData + }; + + appendUserIdsToRequestPayload(data, userId); + + const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); + + if (sua) { + data.sua = sua; + } + + if (bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.consentString) { + data.gdprConsent = bidderRequest.gdprConsent.consentString; + } + if (bidderRequest.gdprConsent.gdprApplies !== undefined) { + data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; + } + } + if (bidderRequest.uspConsent) { + data.usPrivacy = bidderRequest.uspConsent; + } + + if (bidderRequest.gppConsent) { + data.gppString = bidderRequest.gppConsent.gppString; + data.gppSid = bidderRequest.gppConsent.applicableSections; + } else if (bidderRequest.ortb2?.regs?.gpp) { + data.gppString = bidderRequest.ortb2.regs.gpp; + data.gppSid = bidderRequest.ortb2.regs.gpp_sid; + } + + if (bidderRequest.paapi?.enabled) { + const fledge = deepAccess(bidderRequest, 'ortb2Imp.ext.ae'); + if (fledge) { + data.fledge = fledge; + } + } + + _each(ext, (value, key) => { + data['ext.' + key] = value; + }); + + return data; +} + +export function createInterpretResponseFn(bidderCode, allowSingleRequest) { + return function interpretResponse(serverResponse, request) { + if (!serverResponse || !serverResponse.body) { + return []; + } + + const singleRequestMode = allowSingleRequest && config.getConfig(`${bidderCode}.singleRequest`); + const reqBidId = deepAccess(request, 'data.bidId'); + const {results} = serverResponse.body; + + let output = []; + + try { + results.forEach((result, i) => { + const { + creativeId, + ad, + price, + exp, + width, + height, + currency, + bidId, + nurl, + advertiserDomains, + metaData, + mediaType = BANNER + } = result; + if (!ad || !price) { + return; + } + + const response = { + requestId: (singleRequestMode && bidId) ? bidId : reqBidId, + cpm: price, + width: width, + height: height, + creativeId: creativeId, + currency: currency || CURRENCY, + netRevenue: true, + ttl: exp || TTL_SECONDS, + }; + + if (nurl) { + response.nurl = nurl; + } + + if (metaData) { + Object.assign(response, { + meta: metaData + }) + } else { + Object.assign(response, { + meta: { + advertiserDomains: advertiserDomains || [] + } + }) + } + + if (mediaType === BANNER) { + Object.assign(response, { + ad: ad, + }); + } else { + Object.assign(response, { + vastXml: ad, + mediaType: VIDEO + }); + } + output.push(response); + }); + + return output; + } catch (e) { + return []; + } + } +} + +export function createBuildRequestsFn(createRequestDomain, createUniqueRequestData, storage, bidderCode, bidderVersion, allowSingleRequest) { + function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { + const {params} = bid; + const cId = extractCID(params); + const subDomain = extractSubDomain(params); + const data = buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout, storage, bidderVersion, bidderCode, createUniqueRequestData); + const dto = { + method: 'POST', url: `${createRequestDomain(subDomain)}/prebid/multi/${cId}`, data: data + }; + return dto; + } + + function buildSingleRequest(bidRequests, bidderRequest, topWindowUrl, bidderTimeout) { + const {params} = bidRequests[0]; + const cId = extractCID(params); + const subDomain = extractSubDomain(params); + const data = bidRequests.map(bid => { + const sizes = parseSizesInput(bid.sizes); + return buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout, storage, bidderVersion, bidderCode, createUniqueRequestData) + }); + const chunkSize = Math.min(20, config.getConfig(`${bidderCode}.chunkSize`) || 10); + + const chunkedData = chunk(data, chunkSize); + return chunkedData.map(chunk => { + return { + method: 'POST', + url: `${createRequestDomain(subDomain)}/prebid/multi/${cId}`, + data: { + bids: chunk + } + }; + }); + } + + return function buildRequests(validBidRequests, bidderRequest) { + const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; + const bidderTimeout = config.getConfig('bidderTimeout'); + + const singleRequestMode = allowSingleRequest && config.getConfig(`${bidderCode}.singleRequest`); + + const requests = []; + + if (singleRequestMode) { + // banner bids are sent as a single request + const bannerBidRequests = validBidRequests.filter(bid => isArray(bid.mediaTypes) ? bid.mediaTypes.includes(BANNER) : bid.mediaTypes[BANNER] !== undefined); + if (bannerBidRequests.length > 0) { + const singleRequests = buildSingleRequest(bannerBidRequests, bidderRequest, topWindowUrl, bidderTimeout); + requests.push(...singleRequests); + } + + // video bids are sent as a single request for each bid + + const videoBidRequests = validBidRequests.filter(bid => bid.mediaTypes[VIDEO] !== undefined); + videoBidRequests.forEach(validBidRequest => { + const sizes = parseSizesInput(validBidRequest.sizes); + const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); + requests.push(request); + }); + } else { + validBidRequests.forEach(validBidRequest => { + const sizes = parseSizesInput(validBidRequest.sizes); + const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); + requests.push(request); + }); + } + return requests; + } +} diff --git a/libraries/vidazooUtils/constants.js b/libraries/vidazooUtils/constants.js new file mode 100644 index 00000000000..b1056c15899 --- /dev/null +++ b/libraries/vidazooUtils/constants.js @@ -0,0 +1,7 @@ +export const CURRENCY = 'USD'; +export const TTL_SECONDS = 60 * 5; +export const DEAL_ID_EXPIRY = 1000 * 60 * 15; +export const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 60; +export const SESSION_ID_KEY = 'vidSid'; +export const OPT_CACHE_KEY = 'vdzwopt'; +export const OPT_TIME_KEY = 'vdzHum'; diff --git a/libraries/video/constants/ortb.js b/libraries/video/constants/ortb.js index 6b64296500e..86e7b499774 100644 --- a/libraries/video/constants/ortb.js +++ b/libraries/video/constants/ortb.js @@ -13,7 +13,8 @@ * @property {number} w - Width of the video player in device independent pixels (DIPS). * @property {number} h - Height of the video player in device independent pixels (DIPS). * @property {number|undefined} startdelay - Indicates the offset of the ad placement. - * @property {number|undefined} placement - Placement type for the impression. + * @property {number|undefined} placement - Legacy Placement type for the impression. + * @property {number|undefined} plcmt - Modern placement type for the impression. * @property {number|undefined} linearity - Indicates if the impression must be linear, nonlinear, etc. If omitted, assume all are allowed. * @property {number} skip - Indicates if the player can allow the video to be skipped, where 0 is no, 1 is yes. * @property {number|undefined} skipmin - Only ad creatives with a duration greater than this value can be skippable; only applicable if the ad is skippable. @@ -97,6 +98,18 @@ export const PLACEMENT = { INTERSTITIAL_SLIDER_FLOATING: 5 }; +/** + * ADCOM - https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/develop/AdCOM%20v1.0%20FINAL.md#list_plcmtsubtypesvideo + * @enum OrtbVideoParams.plcmt + */ +export const PLCMT = { + INSTREAM: 1, + ACCOMPANYING_CONTENT: 2, + INTERSTITIAL: 3, + OUTSTREAM: 4, + NO_CONTENT: 4 +}; + /** * ORTB 2.5 section 5.4 - Ad Position * @enum OrtbVideoParams.pos diff --git a/modules/.submodules.json b/modules/.submodules.json index 9dfeaf910f8..126380d3631 100644 --- a/modules/.submodules.json +++ b/modules/.submodules.json @@ -6,7 +6,6 @@ "adtelligentIdSystem", "adqueryIdSystem", "amxIdSystem", - "britepoolIdSystem", "connectIdSystem", "czechAdIdSystem", "criteoIdSystem", @@ -37,7 +36,6 @@ "novatiqIdSystem", "oneKeyIdSystem", "operaadsIdSystem", - "parrableIdSystem", "pubProvidedIdSystem", "publinkIdSystem", "quantcastIdSystem", @@ -45,22 +43,24 @@ "tapadIdSystem", "teadsIdSystem", "tncIdSystem", - "utiqSystem", + "utiqIdSystem", "utiqMtpIdSystem", "uid2IdSystem", "euidIdSystem", "unifiedIdSystem", "verizonMediaIdSystem", - "zeotapIdPlusIdSystem" + "zeotapIdPlusIdSystem", + "yandexIdSystem" ], "adpod": [ "freeWheelAdserverVideo", - "dfpAdServerVideo" + "dfpAdpod" ], "rtdModule": [ "1plusXRtdProvider", "a1MediaRtdProvider", "aaxBlockmeterRtdProvider", + "adagioRtdProvider", "adlooxRtdProvider", "adnuntiusRtdProvider", "airgridRtdProvider", @@ -97,6 +97,7 @@ "reconciliationRtdProvider", "relevadRtdProvider", "sirdataRtdProvider", + "symitriDapRtdProvider", "timeoutRtdProvider", "weboramaRtdProvider" ], @@ -109,7 +110,8 @@ "videojsVideoProvider" ], "paapi": [ - "fledgeForGpt" + "paapiForGpt", + "topLevelPaapi" ] } } diff --git a/modules/33acrossAnalyticsAdapter.js b/modules/33acrossAnalyticsAdapter.js index 890c963fa71..1de986cd28e 100644 --- a/modules/33acrossAnalyticsAdapter.js +++ b/modules/33acrossAnalyticsAdapter.js @@ -629,6 +629,8 @@ function setCachedBidStatus(auctionId, bidId, status) { * @param {string} endpoint URL */ function sendReport(report, endpoint) { + // TODO FIX THIS RULES VIOLATION + // eslint-disable-next-line if (navigator.sendBeacon(endpoint, JSON.stringify(report))) { log.info(`Analytics report sent to ${endpoint}`, report); diff --git a/modules/33acrossAnalyticsAdapter.md b/modules/33acrossAnalyticsAdapter.md index c56059e5526..d093434dc97 100644 --- a/modules/33acrossAnalyticsAdapter.md +++ b/modules/33acrossAnalyticsAdapter.md @@ -49,7 +49,7 @@ by default when Prebid is downloaded. If you are compiling from source, this might look something like: ```sh -gulp bundle --modules=gptPreAuction,consentManagement,consentManagementGpp,consentManagementUsp,enrichmentFpdModule,gdprEnforcement,33acrossBidAdapter,33acrossIdSystem,33acrossAnalyticsAdapter +gulp bundle --modules=gptPreAuction,consentManagementTcf,consentManagementGpp,consentManagementUsp,tcfControl,33acrossBidAdapter,33acrossIdSystem,33acrossAnalyticsAdapter ``` Enable the 33Across Analytics Adapter in Prebid.js using the analytics provider `33across` diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index d8a32d75afc..60d732e35d3 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -15,7 +15,7 @@ import { import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {isSlotMatchingAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; -// **************************** UTILS *************************** // +// **************************** UTILS ************************** // const BIDDER_CODE = '33across'; const BIDDER_ALIASES = ['33across_mgni']; const END_POINT = 'https://ssc.33across.com/api/v1/hb'; @@ -492,7 +492,6 @@ function _buildVideoORTB(bidRequest) { // Placement Inference Rules: // - If no placement is defined then default to 2 (In Banner) // - If the old deprecated field is defined, use its value for the recent placement field - // - If product is instream (for instream context) then override placement to 1 const calculatePlacementValue = () => { const IN_BANNER_PLACEMENT_VALUE = 2; @@ -510,8 +509,6 @@ function _buildVideoORTB(bidRequest) { if (product === PRODUCT.INSTREAM) { video.startdelay = video.startdelay || 0; - video.plcmt = 1; - video.placement &&= 1; } // bidfloors diff --git a/modules/33acrossIdSystem.js b/modules/33acrossIdSystem.js index 0118408f08d..8f99846017a 100644 --- a/modules/33acrossIdSystem.js +++ b/modules/33acrossIdSystem.js @@ -26,6 +26,9 @@ const CALLER_NAME = 'pbjs'; const GVLID = 58; const STORAGE_FPID_KEY = '33acrossIdFp'; +const STORAGE_TPID_KEY = '33acrossIdTp'; +const DEFAULT_1PID_SUPPORT = true; +const DEFAULT_TPID_SUPPORT = true; export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); @@ -51,7 +54,8 @@ function calculateResponseObj(response) { return { envelope: response.data.envelope, - fp: response.data.fp + fp: response.data.fp, + tp: response.data.tp }; } @@ -88,6 +92,11 @@ function calculateQueryStringParams(pid, gdprConsentData, enabledStorageTypes) { params.fp = encodeURIComponent(fp); } + const tp = getStoredValue(STORAGE_TPID_KEY, enabledStorageTypes); + if (tp) { + params.tp = encodeURIComponent(tp); + } + return params; } @@ -130,10 +139,10 @@ function getStoredValue(key, enabledStorageTypes) { return storedValue; } -function handleFpId(fpId, storageConfig) { - fpId - ? storeValue(STORAGE_FPID_KEY, fpId, storageConfig) - : deleteFromStorage(STORAGE_FPID_KEY); +function handleSupplementalId(key, id, storageConfig) { + id + ? storeValue(key, id, storageConfig) + : deleteFromStorage(key); } /** @type {Submodule} */ @@ -166,7 +175,7 @@ export const thirthyThreeAcrossIdSubmodule = { * @param {SubmoduleConfig} [config] * @returns {IdResponse|undefined} */ - getId({ params = { }, enabledStorageTypes = [], storage: storageConfig }, gdprConsentData) { + getId({ params = { }, enabledStorageTypes = [], storage: storageConfig = {} }, gdprConsentData) { if (typeof params.pid !== 'string') { logError(`${MODULE_NAME}: Submodule requires a partner ID to be defined`); @@ -179,7 +188,7 @@ export const thirthyThreeAcrossIdSubmodule = { return; } - const { pid, storeFpid, apiUrl = API_URL } = params; + const { pid, storeFpid = DEFAULT_1PID_SUPPORT, storeTpid = DEFAULT_TPID_SUPPORT, apiUrl = API_URL } = params; return { callback(cb) { @@ -198,7 +207,14 @@ export const thirthyThreeAcrossIdSubmodule = { } if (storeFpid) { - handleFpId(responseObj.fp, { + handleSupplementalId(STORAGE_FPID_KEY, responseObj.fp, { + enabledStorageTypes, + expires: storageConfig.expires + }); + } + + if (storeTpid) { + handleSupplementalId(STORAGE_TPID_KEY, responseObj.tp, { enabledStorageTypes, expires: storageConfig.expires }); diff --git a/modules/33acrossIdSystem.md b/modules/33acrossIdSystem.md index 5f5e7805ff9..e983c8ab871 100644 --- a/modules/33acrossIdSystem.md +++ b/modules/33acrossIdSystem.md @@ -51,4 +51,5 @@ The following settings are available in the `params` property in `userSync.userI | Param name | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | | pid | Required | String | Partner ID provided by 33Across | `"0010b00002GYU4eBAH"` | -| storeFpid | Optional | Boolean | Indicates whether a supplemental first-party ID may be stored to improve addressability | `false` (default) or `true` | +| storeFpid | Optional | Boolean | Indicates whether a supplemental first-party ID may be stored to improve addressability, this feature is enabled by default | `true` (default) or `false` | +| storeTpid | Optional | Boolean | Indicates whether a supplemental third-party ID may be stored to improve addressability, this feature is enabled by default | `true` (default) or `false` | diff --git a/modules/prebidmanagerAnalyticsAdapter.js b/modules/AsteriobidPbmAnalyticsAdapter.js similarity index 96% rename from modules/prebidmanagerAnalyticsAdapter.js rename to modules/AsteriobidPbmAnalyticsAdapter.js index 858e30068db..7f56f5064b7 100644 --- a/modules/prebidmanagerAnalyticsAdapter.js +++ b/modules/AsteriobidPbmAnalyticsAdapter.js @@ -1,4 +1,4 @@ -import { generateUUID, getParameterByName, logError, parseUrl, logInfo } from '../src/utils.js'; +import { deepClone, generateUUID, getParameterByName, hasNonSerializableProperty, logError, parseUrl, logInfo } from '../src/utils.js'; import {ajaxBuilder} from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; @@ -9,10 +9,10 @@ import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; /** * prebidmanagerAnalyticsAdapter.js - analytics adapter for prebidmanager */ -export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: 'prebidmanager'}); +export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: 'asteriobidpbm'}); const DEFAULT_EVENT_URL = 'https://endpt.prebidmanager.com/endpoint'; const analyticsType = 'endpoint'; -const analyticsName = 'Prebid Manager Analytics'; +const analyticsName = 'Asteriobid PBM Analytics'; let ajax = ajaxBuilder(0); @@ -199,10 +199,10 @@ function trimBidderRequest(bidderRequest) { } function handleEvent(eventType, eventArgs) { - try { - eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {}; - } catch (e) { - // keep eventArgs as is + if (eventArgs) { + eventArgs = hasNonSerializableProperty(eventArgs) ? eventArgs : deepClone(eventArgs) + } else { + eventArgs = {} } const pmEvent = {}; diff --git a/modules/AsteriobidPbmAnalyticsAdapter.md b/modules/AsteriobidPbmAnalyticsAdapter.md new file mode 100644 index 00000000000..0331a71b17c --- /dev/null +++ b/modules/AsteriobidPbmAnalyticsAdapter.md @@ -0,0 +1,9 @@ +# Overview + +Module Name: Asteriobid PBM Analytics Adapter +Module Type: Analytics Adapter +Maintainer: admin@prebidmanager.com + +# Description + +Analytics adapter for Asteriobid PBM. Contact admin@prebidmanager.com for information. diff --git a/modules/acuityadsBidAdapter.js b/modules/acuityadsBidAdapter.js index 5b12eb2133b..bd85d2b3cc0 100644 --- a/modules/acuityadsBidAdapter.js +++ b/modules/acuityadsBidAdapter.js @@ -1,216 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'acuityads'; const AD_URL = 'https://prebid.admanmedia.com/pbjs'; const SYNC_URL = 'https://cs.admanmedia.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - placement.placementId = placementId; - placement.type = 'publisher'; - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && params.placementId); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - // Add GPP consent - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/adagioAnalyticsAdapter.js b/modules/adagioAnalyticsAdapter.js index bb5de41d3ce..033809e7f1b 100644 --- a/modules/adagioAnalyticsAdapter.js +++ b/modules/adagioAnalyticsAdapter.js @@ -2,12 +2,13 @@ * Analytics Adapter for Adagio */ +import { _ADAGIO, getBestWindowForAdagio } from '../libraries/adagioUtils/adagioUtils.js'; +import { deepAccess, logError, logInfo, logWarn } from '../src/utils.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { EVENTS } from '../src/constants.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; -import { EVENTS } from '../src/constants.js'; import { ajax } from '../src/ajax.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { getWindowTop, getWindowSelf, deepAccess, logInfo, logError } from '../src/utils.js'; import { getGlobal } from '../src/prebidGlobal.js'; const emptyUrl = ''; @@ -19,6 +20,13 @@ const PREBID_VERSION = '$prebid.version$'; const ENDPOINT = 'https://c.4dex.io/pba.gif'; const CURRENCY_USD = 'USD'; const ADAGIO_CODE = 'adagio'; + +export const _internal = { + getAdagioNs: function() { + return _ADAGIO; + } +}; + const cache = { auctions: {}, getAuction: function(auctionId, adUnitCode) { @@ -48,34 +56,6 @@ const cache = { }; const enc = window.encodeURIComponent; -/** -/* BEGIN ADAGIO.JS CODE - */ - -function canAccessTopWindow() { - try { - if (getWindowTop().location.href) { - return true; - } - } catch (error) { - return false; - } -}; - -function getCurrentWindow() { - return currentWindow; -}; - -let currentWindow; - -const adagioEnqueue = function adagioEnqueue(action, data) { - getCurrentWindow().ADAGIO.queue.push({ action, data, ts: Date.now() }); -}; - -/** - * END ADAGIO.JS CODE - */ - /** * UTILS FUNCTIONS */ @@ -150,6 +130,10 @@ function getCurrencyData(bid) { * @param {Object} qp */ function sendRequest(qp) { + if (!qp.org_id || !qp.site) { + logInfo('request is missing org_id or site, skipping beacon.'); + return; + } // Removing null values qp = Object.keys(qp).reduce((acc, key) => { if (qp[key] !== null) { @@ -194,37 +178,28 @@ function getTargetedAuctionId(bid) { */ function handlerAuctionInit(event) { - const w = getCurrentWindow(); + const w = getBestWindowForAdagio(); const prebidAuctionId = event.auctionId; const adUnitCodes = removeDuplicates(event.adUnitCodes, adUnitCode => adUnitCode); // Check if Adagio is on the bid requests. - // If not, we don't need to track the auction. const adagioBidRequest = event.bidderRequests.find(bidRequest => isAdagio(bidRequest.bidderCode)); - if (!adagioBidRequest) { - logInfo(`Adagio is not on the bid requests for auction '${prebidAuctionId}'`) - return; - } + + const rtdUid = deepAccess(adagioBidRequest, 'ortb2.site.ext.data.adg_rtd.uid'); + cache.addPrebidAuctionIdRef(prebidAuctionId, rtdUid); cache.auctions[prebidAuctionId] = {}; adUnitCodes.forEach(adUnitCode => { + // event.adUnits are splitted by mediatypes const adUnits = event.adUnits.filter(adUnit => adUnit.code === adUnitCode); - // Get all bidders configures for the ad unit. - const bidders = removeDuplicates( - adUnits.map(adUnit => adUnit.bids.map(bid => ({bidder: bid.bidder, params: bid.params}))).flat(), - bidder => bidder.bidder - ); - - // Check if Adagio is configured for the ad unit. - // If not, we don't need to track the ad unit. - const adagioBidder = bidders.find(bidder => isAdagio(bidder.bidder)); - if (!adagioBidder) { - logInfo(`Adagio is not configured for ad unit '${adUnitCode}'`); - return; - } + // Get all bidders configured for the ad unit. + // AdUnits with the same code can have a different bidder list, aggregate all of them. + const biddersAggregate = adUnits.reduce((bidders, adUnit) => bidders.concat(adUnit.bids.map(bid => bid.bidder)), []) + // remove duplicates + const bidders = [...new Set(biddersAggregate)]; // Get all media types and banner sizes configured for the ad unit. const mediaTypes = adUnits.map(adUnit => adUnit.mediaTypes); @@ -239,45 +214,56 @@ function handlerAuctionInit(event) { bannerSize => bannerSize ).sort(); - // Get all Adagio bids for the ad unit from the bidRequest. - // If no bids, we don't need to track the ad unit. - const adagioAdUnitBids = adagioBidRequest.bids.filter(bid => bid.adUnitCode === adUnitCode); - if (deepAccess(adagioAdUnitBids, 'length', 0) <= 0) { - logInfo(`Adagio is not on the bid requests for ad unit '${adUnitCode}' and auction '${prebidAuctionId}'`) - return; + const sortedBidderCodes = bidders.sort() + + const bidSrcMapper = (bidder) => { + const request = event.bidderRequests.find(br => br.bidderCode === bidder) + return request ? request.bids[0].src : null } - // Get Adagio params from the first bid. - // We assume that all Adagio bids for a same adunit have the same params. - const params = adagioAdUnitBids[0].params; + const biddersSrc = sortedBidderCodes.map(bidSrcMapper).join(','); - const adagioAuctionId = params.adagioAuctionId; - cache.addPrebidAuctionIdRef(prebidAuctionId, adagioAuctionId); + // if adagio was involved in the auction we identified it with rtdUid, if not use the prebid auctionId + const auctionId = rtdUid || prebidAuctionId; - // Get all media types requested for Adagio. - const adagioMediaTypes = removeDuplicates( - adagioAdUnitBids.map(bid => Object.keys(bid.mediaTypes)).flat(), - mediaTypeKey => mediaTypeKey - ).flat().map(mediaType => getMediaTypeAlias(mediaType)).sort(); + const adgRtdSession = deepAccess(event.bidderRequests[0], 'ortb2.site.ext.data.adg_rtd.session', {}); const qp = { + org_id: adagioAdapter.options.organizationId, + site: adagioAdapter.options.site, v: 0, pbjsv: PREBID_VERSION, - org_id: params.organizationId, - site: params.site, - pv_id: params.pageviewId, - auct_id: adagioAuctionId, + pv_id: _internal.getAdagioNs().pageviewId, + auct_id: auctionId, adu_code: adUnitCode, url_dmn: w.location.hostname, - pgtyp: params.pagetype, - plcmt: params.placement, - t_n: params.testName || null, - t_v: params.testVersion || null, mts: mediaTypesKeys.join(','), ban_szs: bannerSizes.join(','), - bdrs: bidders.map(bidder => bidder.bidder).sort().join(','), - adg_mts: adagioMediaTypes.join(',') + bdrs: sortedBidderCodes.join(','), + pgtyp: deepAccess(event.bidderRequests[0], 'ortb2.site.ext.data.pagetype', null), + plcmt: deepAccess(adUnits[0], 'ortb2Imp.ext.data.placement', null), + t_n: adgRtdSession.testName || null, + t_v: adgRtdSession.testVersion || null, + s_id: adgRtdSession.id || null, + s_new: adgRtdSession.new || null, + bdrs_src: biddersSrc, }; + if (adagioBidRequest && adagioBidRequest.bids) { + const adagioAdUnitBids = adagioBidRequest.bids.filter(bid => bid.adUnitCode === adUnitCode); + if (adagioAdUnitBids.length > 0) { + // Get all media types requested for Adagio. + const adagioMediaTypes = removeDuplicates( + adagioAdUnitBids.map(bid => Object.keys(bid.mediaTypes)).flat(), + mediaTypeKey => mediaTypeKey + ).flat().map(mediaType => getMediaTypeAlias(mediaType)).sort(); + + qp.adg_mts = adagioMediaTypes.join(','); + // for backward compatibility: if we didn't find organizationId & site but we have a bid from adagio we might still find it in params + qp.org_id = qp.org_id || adagioAdUnitBids[0].params.organizationId; + qp.site = qp.site || adagioAdUnitBids[0].params.site; + } + } + cache.auctions[prebidAuctionId][adUnitCode] = qp; sendNewBeacon(prebidAuctionId, adUnitCode); }); @@ -324,13 +310,21 @@ function handlerAuctionEnd(event) { return bid ? getCurrencyData(bid).netCpm : null } + const perfNavigation = performance.getEntriesByType('navigation')[0]; + cache.updateAuction(auctionId, adUnitCode, { bdrs_bid: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidResponseMapper).join(','), - bdrs_cpm: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidCpmMapper).join(',') + bdrs_cpm: cache.getBiddersFromAuction(auctionId, adUnitCode).map(bidCpmMapper).join(','), + // check timings at the end of the auction to leave time to the browser to update it + dom_i: Math.round(perfNavigation['domInteractive']) || null, + dom_c: Math.round(perfNavigation['domComplete']) || null, + loa_e: Math.round(perfNavigation['loadEventEnd']) || null, }); + sendNewBeacon(auctionId, adUnitCode); }); } + function handlerBidWon(event) { let auctionId = getTargetedAuctionId(event); @@ -345,6 +339,8 @@ function handlerBidWon(event) { ? cache.getAdagioAuctionId(event.auctionId) : null); + const perfNavigation = performance.getEntriesByType('navigation')[0]; + cache.updateAuction(auctionId, event.adUnitCode, { win_bdr: event.bidder, win_mt: getMediaTypeAlias(event.mediaType), @@ -353,6 +349,11 @@ function handlerBidWon(event) { win_net_cpm: currencyData.netCpm, win_og_cpm: currencyData.orginalCpm, + // check timings at the end of the auction to leave time to the browser to update it + dom_i: Math.round(perfNavigation['domInteractive']) || null, + dom_c: Math.round(perfNavigation['domComplete']) || null, + loa_e: Math.round(perfNavigation['loadEventEnd']) || null, + // cache bid id auct_id_c: adagioAuctionCacheId, }); @@ -407,7 +408,11 @@ let adagioAdapter = Object.assign(adapter({ emptyUrl, analyticsType }), { try { if (typeof args !== 'undefined' && events.indexOf(eventType) !== -1) { - adagioEnqueue('pb-analytics-event', { eventName: eventType, args }); + _internal.getAdagioNs().queue.push({ + action: 'pb-analytics-event', + data: { eventName: eventType, args }, + ts: Date.now() + }); } } catch (error) { logError('Error on Adagio Analytics Adapter - adagio.js', error); @@ -418,14 +423,26 @@ let adagioAdapter = Object.assign(adapter({ emptyUrl, analyticsType }), { adagioAdapter.originEnableAnalytics = adagioAdapter.enableAnalytics; adagioAdapter.enableAnalytics = config => { - const w = (canAccessTopWindow()) ? getWindowTop() : getWindowSelf(); - currentWindow = w; + _internal.getAdagioNs().versions.adagioAnalyticsAdapter = VERSION; - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.queue = w.ADAGIO.queue || []; - w.ADAGIO.versions = w.ADAGIO.versions || {}; - w.ADAGIO.versions.adagioAnalyticsAdapter = VERSION; + let modules = getGlobal().installedModules; + if (modules && (!modules.length || modules.indexOf('adagioRtdProvider') === -1 || modules.indexOf('rtdModule') === -1)) { + logError('Adagio Analytics Adapter requires rtdModule & adagioRtdProvider modules which are not installed. No beacon will be sent'); + return; + } + adagioAdapter.options = config.options || {}; + if (!adagioAdapter.options.organizationId) { + logWarn('Adagio Analytics Adapter: organizationId is required and is missing will try to fallback on params.'); + } else { + adagioAdapter.options.organizationId = adagioAdapter.options.organizationId.toString(); // allows publisher to pass it as a number + } + if (!adagioAdapter.options.site) { + logWarn('Adagio Analytics Adapter: site is required and is missing will try to fallback on params.'); + } else if (typeof adagioAdapter.options.site !== 'string') { + logWarn('Adagio Analytics Adapter: site should be a string will try to fallback on params.'); + adagioAdapter.options.site = undefined; + } adagioAdapter.originEnableAnalytics(config); } diff --git a/modules/adagioAnalyticsAdapter.md b/modules/adagioAnalyticsAdapter.md index 9fc2cb0bb88..916f9ec9c58 100644 --- a/modules/adagioAnalyticsAdapter.md +++ b/modules/adagioAnalyticsAdapter.md @@ -13,5 +13,9 @@ Analytics adapter for Adagio ```js pbjs.enableAnalytics({ provider: 'adagio', + options: { + organizationId: '1000', // Required. Provided by Adagio + site: 'my-website', // Required. Provided by Adagio + } }); ``` diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js index b6ffc9b8d0d..9bcebf9205e 100644 --- a/modules/adagioBidAdapter.js +++ b/modules/adagioBidAdapter.js @@ -1,4 +1,4 @@ -import {find} from '../src/polyfill.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { canAccessWindowTop, cleanObj, @@ -6,53 +6,38 @@ import { deepClone, generateUUID, getDNT, - getUniqueIdentifierStr, getWindowSelf, - getWindowTop, isArray, isArrayOfNums, isFn, - inIframe, isInteger, isNumber, - isSafeFrameWindow, isStr, logError, logInfo, logWarn, - mergeDeep, } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {verify} from 'criteo-direct-rsa-validate/build/verify.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getRefererInfo, parseDomain} from '../src/refererDetection.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {OUTSTREAM} from '../src/video.js'; -import { getGlobal } from '../src/prebidGlobal.js'; +import { getRefererInfo, parseDomain } from '../src/refererDetection.js'; +import { OUTSTREAM } from '../src/video.js'; +import { Renderer } from '../src/Renderer.js'; +import { _ADAGIO } from '../libraries/adagioUtils/adagioUtils.js'; +import { config } from '../src/config.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { find } from '../src/polyfill.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { userSync } from '../src/userSync.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; const BIDDER_CODE = 'adagio'; const LOG_PREFIX = 'Adagio:'; -const FEATURES_VERSION = '1'; export const ENDPOINT = 'https://mp.4dex.io/prebid'; const SUPPORTED_MEDIA_TYPES = [BANNER, NATIVE, VIDEO]; -const ADAGIO_TAG_URL = 'https://script.4dex.io/localstore.js'; -const ADAGIO_LOCALSTORAGE_KEY = 'adagioScript'; const GVLID = 617; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); const BB_PUBLICATION = 'adagio'; const BB_RENDERER_DEFAULT = 'renderer'; export const BB_RENDERER_URL = `https://${BB_PUBLICATION}.bbvms.com/r/$RENDERER.js`; -const MAX_SESS_DURATION = 30 * 60 * 1000; -const ADAGIO_PUBKEY = 'AL16XT44Sfp+8SHVF1UdC7hydPSMVLMhsYknKDdwqq+0ToDSJrP0+Qh0ki9JJI2uYm/6VEYo8TJED9WfMkiJ4vf02CW3RvSWwc35bif2SK1L8Nn/GfFYr/2/GG/Rm0vUsv+vBHky6nuuYls20Og0HDhMgaOlXoQ/cxMuiy5QSktp'; -const ADAGIO_PUBKEY_E = 65537; const CURRENCY = 'USD'; // This provide a whitelist and a basic validation of OpenRTB 2.5 options used by the Adagio SSP. @@ -88,180 +73,10 @@ export const ORTB_VIDEO_PARAMS = { 'api': (value) => isArrayOfNums(value) }; -let currentWindow; - -export const GlobalExchange = (function() { - let features; - let exchangeData = {}; - - return { - clearFeatures: function() { - features = undefined; - }, - - clearExchangeData: function() { - exchangeData = {}; - }, - - getOrSetGlobalFeatures: function () { - if (!features) { - features = { - type: 'bidAdapter', - page_dimensions: getPageDimensions().toString(), - viewport_dimensions: getViewPortDimensions().toString(), - user_timestamp: getTimestampUTC().toString(), - dom_loading: getDomLoadingDuration().toString(), - } - } - - return { ...features }; - }, - - prepareExchangeData(storageValue) { - const adagioStorage = JSON.parse(storageValue, function(name, value) { - if (name.charAt(0) !== '_' || name === '') { - return value; - } - }); - let random = deepAccess(adagioStorage, 'session.rnd'); - let newSession = false; - - if (internal.isNewSession(adagioStorage)) { - newSession = true; - random = Math.random(); - } - - const data = { - session: { - new: newSession, - rnd: random, - } - } - - mergeDeep(exchangeData, adagioStorage, data); - - internal.enqueue({ - action: 'session', - ts: Date.now(), - data: exchangeData - }); - }, - - getExchangeData() { - return exchangeData - } - }; -})(); - /** - * @deprecated will be removed in Prebid.js 9. + * Returns the window.ADAGIO global object used to store Adagio data. + * This object is created in window.top if possible, otherwise in window.self. */ -export function adagioScriptFromLocalStorageCb(ls) { - try { - if (!ls) { - logWarn(`${LOG_PREFIX} script not found.`); - return; - } - - const hashRgx = /^(\/\/ hash: (.+)\n)(.+\n)$/; - - if (!hashRgx.test(ls)) { - logWarn(`${LOG_PREFIX} no hash found.`); - storage.removeDataFromLocalStorage(ADAGIO_LOCALSTORAGE_KEY); - } else { - const r = ls.match(hashRgx); - const hash = r[2]; - const content = r[3]; - - if (verify(content, hash, ADAGIO_PUBKEY, ADAGIO_PUBKEY_E)) { - logInfo(`${LOG_PREFIX} start script.`); - Function(ls)(); // eslint-disable-line no-new-func - } else { - logWarn(`${LOG_PREFIX} invalid script found.`); - storage.removeDataFromLocalStorage(ADAGIO_LOCALSTORAGE_KEY); - } - } - } catch (err) { - logError(LOG_PREFIX, err); - } -} - -/** - * @deprecated will be removed in Prebid.js 9. - */ -export function getAdagioScript() { - storage.getDataFromLocalStorage(ADAGIO_LOCALSTORAGE_KEY, (ls) => { - internal.adagioScriptFromLocalStorageCb(ls); - }); - - storage.localStorageIsEnabled(isValid => { - if (isValid) { - loadExternalScript(ADAGIO_TAG_URL, BIDDER_CODE); - } else { - // Try-catch to avoid error when 3rd party cookies is disabled (e.g. in privacy mode) - try { - // ensure adagio removing for next time. - // It's an antipattern regarding the TCF2 enforcement logic - // but it's the only way to respect the user choice update. - window.localStorage.removeItem(ADAGIO_LOCALSTORAGE_KEY); - // Extra data from external script. - // This key is removed only if localStorage is not accessible. - window.localStorage.removeItem('adagio'); - } catch (e) { - logInfo(`${LOG_PREFIX} unable to clear Adagio scripts from localstorage.`); - } - } - }); -} - -function getCurrentWindow() { - return currentWindow || getWindowSelf(); -} - -function initAdagio() { - currentWindow = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf(); - - const w = currentWindow; - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.adUnits = w.ADAGIO.adUnits || {}; - w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || []; - w.ADAGIO.queue = w.ADAGIO.queue || []; - w.ADAGIO.versions = w.ADAGIO.versions || {}; - w.ADAGIO.versions.pbjs = '$prebid.version$'; - w.ADAGIO.isSafeFrameWindow = isSafeFrameWindow(); - - storage.getDataFromLocalStorage('adagio', (storageData) => { - try { - if (w.ADAGIO.hasRtd !== true) { - logInfo(`${LOG_PREFIX} RTD module not found. Loading external script from adagioBidAdapter is deprecated and will be removed in Prebid.js 9.`); - - GlobalExchange.prepareExchangeData(storageData); - getAdagioScript(); - } - } catch (e) { - logError(LOG_PREFIX, e); - } - }); -} - -function enqueue(ob) { - const w = internal.getCurrentWindow(); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.queue = w.ADAGIO.queue || []; - w.ADAGIO.queue.push(ob); -}; - -function getPageviewId() { - const w = internal.getCurrentWindow(); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.pageviewId = w.ADAGIO.pageviewId || generateUUID(); - - return w.ADAGIO.pageviewId; -}; - function getDevice() { const language = navigator.language ? 'language' : 'userLanguage'; return { @@ -283,30 +98,6 @@ function getSite(bidderRequest) { }; }; -function getElementFromTopWindow(element, currentWindow) { - try { - if (getWindowTop() === currentWindow) { - if (!element.getAttribute('id')) { - element.setAttribute('id', `adg-${getUniqueIdentifierStr()}`); - } - return element; - } else { - const frame = currentWindow.frameElement; - const frameClientRect = frame.getBoundingClientRect(); - const elementClientRect = element.getBoundingClientRect(); - - if (frameClientRect.width !== elementClientRect.width || frameClientRect.height !== elementClientRect.height) { - return false; - } - - return getElementFromTopWindow(frame, currentWindow.parent); - } - } catch (err) { - logWarn(`${LOG_PREFIX}`, err); - return false; - } -}; - function autoDetectAdUnitElementIdFromGpt(adUnitCode) { const autoDetectedAdUnit = getGptSlotInfoForAdUnitCode(adUnitCode); @@ -331,49 +122,28 @@ function isRendererPreferredFromPublisher(bidRequest) { } /** - * - * @param {object} adagioStorage - * @returns {boolean} + * Check if the publisher has defined its own video player and uses it for all ad-units. + * If not or if the `backupOnly` flag is true, this means we use our own player (BlueBillywig) defined in this adapter. */ -function isNewSession(adagioStorage) { - const now = Date.now(); - const { lastActivityTime, vwSmplg } = deepAccess(adagioStorage, 'session', {}); - return ( - !isNumber(lastActivityTime) || - !isNumber(vwSmplg) || - (now - lastActivityTime) > MAX_SESS_DURATION - ) -} - -function setPlayerName(bidRequest) { - const playerName = (internal.isRendererPreferredFromPublisher(bidRequest)) ? 'other' : 'adagio'; - - if (playerName === 'other') { - logWarn(`${LOG_PREFIX} renderer.backupOnly has not been set. Adagio recommends to use its own player to get expected behavior.`); - } - - return playerName; +function getPlayerName(bidRequest) { + return _internal.isRendererPreferredFromPublisher(bidRequest) ? 'other' : 'adagio'; ; } function hasRtd() { - const w = internal.getCurrentWindow(); - - return !!(w.ADAGIO && w.ADAGIO.hasRtd); + const rtdConfigs = config.getConfig('realTimeData.dataProviders') || []; + return rtdConfigs.find(provider => provider.name === 'adagio'); }; -export const internal = { - enqueue, - getPageviewId, +export const _internal = { + canAccessWindowTop, + getAdagioNs: function() { + return _ADAGIO; + }, getDevice, getSite, - getElementFromTopWindow, getRefererInfo, - adagioScriptFromLocalStorageCb, - getCurrentWindow, - canAccessWindowTop, + hasRtd, isRendererPreferredFromPublisher, - isNewSession, - hasRtd }; function _getGdprConsent(bidderRequest) { @@ -406,17 +176,6 @@ function _getUspConsent(bidderRequest) { return (deepAccess(bidderRequest, 'uspConsent')) ? { uspConsent: bidderRequest.uspConsent } : false; } -function _getGppConsent(bidderRequest) { - let gpp = deepAccess(bidderRequest, 'gppConsent.gppString') - let gppSid = deepAccess(bidderRequest, 'gppConsent.applicableSections') - - if (!gpp || !gppSid) { - gpp = deepAccess(bidderRequest, 'ortb2.regs.gpp', '') - gppSid = deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', []) - } - return { gpp, gppSid } -} - function _getSchain(bidRequest) { return deepAccess(bidRequest, 'schain'); } @@ -447,7 +206,7 @@ function _buildVideoBidRequest(bidRequest) { }; if (videoParams.context && videoParams.context === OUTSTREAM) { - bidRequest.mediaTypes.video.playerName = setPlayerName(bidRequest); + bidRequest.mediaTypes.video.playerName = getPlayerName(bidRequest); } // Only whitelisted OpenRTB options need to be validated. @@ -688,201 +447,6 @@ function autoFillParams(bid) { setExtraParam(bid, 'category'); } -function getPageDimensions() { - if (isSafeFrameWindow() || !canAccessWindowTop()) { - return ''; - } - - // the page dimension can be computed on window.top only. - const wt = getWindowTop(); - const body = wt.document.querySelector('body'); - - if (!body) { - return ''; - } - const html = wt.document.documentElement; - const pageWidth = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth); - const pageHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); - - return `${pageWidth}x${pageHeight}`; -} - -/** - * @todo Move to prebid Core as Utils. - * @returns - */ -function getViewPortDimensions() { - if (!isSafeFrameWindow() && !canAccessWindowTop()) { - return ''; - } - - const viewportDims = { w: 0, h: 0 }; - - if (isSafeFrameWindow()) { - const ws = getWindowSelf(); - - if (typeof ws.$sf.ext.geom !== 'function') { - logWarn(LOG_PREFIX, 'Unable to compute from safeframe api.'); - return ''; - } - - const sfGeom = ws.$sf.ext.geom(); - - if (!sfGeom || !sfGeom.win) { - logWarn(LOG_PREFIX, 'Unable to compute from safeframe api. Missing `geom().win` property'); - return ''; - } - - viewportDims.w = Math.round(sfGeom.w); - viewportDims.h = Math.round(sfGeom.h); - } else { - // window.top based computing - const wt = getWindowTop(); - viewportDims.w = wt.innerWidth; - viewportDims.h = wt.innerHeight; - } - - return `${viewportDims.w}x${viewportDims.h}`; -} - -function getSlotPosition(adUnitElementId) { - if (!adUnitElementId) { - return ''; - } - - if (!isSafeFrameWindow() && !canAccessWindowTop()) { - return ''; - } - - const position = { x: 0, y: 0 }; - - if (isSafeFrameWindow()) { - const ws = getWindowSelf(); - - if (typeof ws.$sf.ext.geom !== 'function') { - logWarn(LOG_PREFIX, 'Unable to compute from safeframe api.'); - return ''; - } - - const sfGeom = ws.$sf.ext.geom(); - - if (!sfGeom || !sfGeom.self) { - logWarn(LOG_PREFIX, 'Unable to compute from safeframe api. Missing `geom().self` property'); - return ''; - } - - position.x = Math.round(sfGeom.t); - position.y = Math.round(sfGeom.l); - } else if (canAccessWindowTop()) { - try { - // window.top based computing - const wt = getWindowTop(); - const d = wt.document; - - let domElement; - - if (inIframe() === true) { - const ws = getWindowSelf(); - const currentElement = ws.document.getElementById(adUnitElementId); - domElement = internal.getElementFromTopWindow(currentElement, ws); - } else { - domElement = wt.document.getElementById(adUnitElementId); - } - - if (!domElement) { - return ''; - } - - let box = domElement.getBoundingClientRect(); - - const docEl = d.documentElement; - const body = d.body; - const clientTop = d.clientTop || body.clientTop || 0; - const clientLeft = d.clientLeft || body.clientLeft || 0; - const scrollTop = wt.pageYOffset || docEl.scrollTop || body.scrollTop; - const scrollLeft = wt.pageXOffset || docEl.scrollLeft || body.scrollLeft; - - const elComputedStyle = wt.getComputedStyle(domElement, null); - const mustDisplayElement = elComputedStyle.display === 'none'; - - if (mustDisplayElement) { - logWarn(LOG_PREFIX, 'The element is hidden. The slot position cannot be computed.'); - } - - position.x = Math.round(box.left + scrollLeft - clientLeft); - position.y = Math.round(box.top + scrollTop - clientTop); - } catch (err) { - logError(LOG_PREFIX, err); - return ''; - } - } else { - return ''; - } - - return `${position.x}x${position.y}`; -} - -function getTimestampUTC() { - // timestamp returned in seconds - return Math.floor(new Date().getTime() / 1000) - new Date().getTimezoneOffset() * 60; -} - -/** - * domLoading feature is computed on window.top if reachable. - */ -function getDomLoadingDuration() { - let domLoadingDuration = -1; - let performance; - - performance = (canAccessWindowTop()) ? getWindowTop().performance : getWindowSelf().performance; - - if (performance && performance.timing && performance.timing.navigationStart > 0) { - const val = performance.timing.domLoading - performance.timing.navigationStart; - if (val > 0) { - domLoadingDuration = val; - } - } - - return domLoadingDuration; -} - -function storeRequestInAdagioNS(bidRequest) { - const w = getCurrentWindow(); - // Store adUnits config. - // If an adUnitCode has already been stored, it will be replaced. - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits.filter((adUnit) => adUnit.code !== bidRequest.adUnitCode); - - let printNumber - if (bidRequest.features && bidRequest.features.print_number) { - printNumber = bidRequest.features.print_number; - } else if (bidRequest.params.features && bidRequest.params.features.print_number) { - printNumber = bidRequest.params.features.print_number; - } - - w.ADAGIO.pbjsAdUnits.push({ - code: bidRequest.adUnitCode, - mediaTypes: bidRequest.mediaTypes || {}, - sizes: (bidRequest.mediaTypes && bidRequest.mediaTypes.banner && Array.isArray(bidRequest.mediaTypes.banner.sizes)) ? bidRequest.mediaTypes.banner.sizes : bidRequest.sizes, - bids: [{ - bidder: bidRequest.bidder, - params: bidRequest.params // use the updated bid.params object with auto-detected params - }], - auctionId: bidRequest.auctionId, // this auctionId has been generated by adagioBidAdapter - pageviewId: internal.getPageviewId(), - printNumber, - localPbjs: '$$PREBID_GLOBAL$$', - localPbjsRef: getGlobal() - }); - - // (legacy) Store internal adUnit information - w.ADAGIO.adUnits[bidRequest.adUnitCode] = { - auctionId: bidRequest.auctionId, // this auctionId has been generated by adagioBidAdapter - pageviewId: internal.getPageviewId(), - printNumber, - }; -} - // See https://support.bluebillywig.com/developers/vast-renderer/ const OUTSTREAM_RENDERER = { bootstrapPlayer: function(bid) { @@ -954,31 +518,6 @@ const OUTSTREAM_RENDERER = { } }; -/** - * - * @param {*} bidRequest - * @returns - */ -const _getFeatures = (bidRequest) => { - const f = { ...deepAccess(bidRequest, 'ortb2.site.ext.data.adg_rtd.features', GlobalExchange.getOrSetGlobalFeatures()) } || {}; - - f.print_number = deepAccess(bidRequest, 'bidderRequestsCount', 1).toString(); - - if (f.type === 'bidAdapter') { - f.adunit_position = getSlotPosition(bidRequest.params.adUnitElementId) - } else { - f.adunit_position = deepAccess(bidRequest, 'ortb2Imp.ext.data.adg_rtd.adunit_position'); - } - - Object.keys(f).forEach((prop) => { - if (f[prop] === '') { - delete f[prop]; - } - }); - - return f; -} - export const spec = { code: BIDDER_CODE, gvlid: GVLID, @@ -992,7 +531,6 @@ export const spec = { // Note: `bid.params.placement` is not related to the video param `placement`. if (!(bid.params.organizationId && bid.params.site && bid.params.placement)) { logWarn(`${LOG_PREFIX} at least one required param is missing.`); - // internal.enqueue(debugData()); return false; } @@ -1004,26 +542,30 @@ export const spec = { validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); const secure = (location.protocol === 'https:') ? 1 : 0; - const device = internal.getDevice(); - const site = internal.getSite(bidderRequest); - const pageviewId = internal.getPageviewId(); - const hasRtd = internal.hasRtd(); + const device = _internal.getDevice(); + const site = _internal.getSite(bidderRequest); + const pageviewId = _internal.getAdagioNs().pageviewId; const gdprConsent = _getGdprConsent(bidderRequest) || {}; const uspConsent = _getUspConsent(bidderRequest) || {}; const coppa = _getCoppa(); - const gppConsent = _getGppConsent(bidderRequest) + const { gpp, gpp_sid: gppSid } = deepAccess(bidderRequest, 'ortb2.regs', {}); const schain = _getSchain(validBidRequests[0]); const eids = _getEids(validBidRequests[0]) || []; const syncEnabled = deepAccess(config.getConfig('userSync'), 'syncEnabled') - const usIfr = syncEnabled && userSync.canBidderRegisterSync('iframe', 'adagio') + const canSyncWithIframe = syncEnabled && userSync.canBidderRegisterSync('iframe', 'adagio') // We don't validate the dsa object in adapter and let our server do it. const dsa = deepAccess(bidderRequest, 'ortb2.regs.ext.dsa'); - let rtdSamplingSession = deepAccess(bidderRequest, 'ortb2.site.ext.data.adg_rtd.session'); - const dataExchange = (rtdSamplingSession) ? { session: rtdSamplingSession } : GlobalExchange.getExchangeData(); + // If no session data is provided, we always generate a new one. + const sessionData = deepAccess(bidderRequest, 'ortb2.site.ext.data.adg_rtd.session', {}); + if (!Object.keys(sessionData).length) { + logInfo(LOG_PREFIX, 'No session data provided. A new session is be generated.') + sessionData.new = true; + sessionData.rnd = Math.random() + } - const aucId = generateUUID() + const aucId = deepAccess(bidderRequest, 'ortb2.site.ext.data.adg_rtd.uid') || generateUUID() const adUnits = validBidRequests.map(rawBidRequest => { const bidRequest = deepClone(rawBidRequest); @@ -1074,21 +616,6 @@ export const spec = { } } - const features = _getFeatures(bidRequest); - bidRequest.features = features; - - if (!hasRtd) { - internal.enqueue({ - action: 'features', - ts: Date.now(), - data: { - features, - params: { ...bidRequest.params }, - adUnitCode: bidRequest.adUnitCode - } - }); - } - // Handle priceFloors module // We need to use `rawBidRequest` as param because: // - adagioBidAdapter generates its own auctionId due to transmitTid activity limitation (see https://github.com/prebid/Prebid.js/pull/10079) @@ -1142,10 +669,14 @@ export const spec = { bidRequest.gpid = gpid; } - if (!hasRtd) { - // store the whole bidRequest (adUnit) object in the ADAGIO namespace. - storeRequestInAdagioNS(bidRequest); + // features are added by the adagioRtdProvider. + const rawFeatures = { + ...deepAccess(bidRequest, 'ortb2.site.ext.data.adg_rtd.features', {}), + print_number: (bidRequest.bidderRequestsCount || 1).toString(), + adunit_position: deepAccess(bidRequest, 'ortb2Imp.ext.data.adg_rtd.adunit_position', null) } + // Clean the features object from null or undefined values. + bidRequest.features = Object.entries(rawFeatures).reduce((a, [k, v]) => (v == null ? a : (a[k] = v, a)), {}) // Remove some params that are not needed on the server side. delete bidRequest.params.siteId; @@ -1182,7 +713,6 @@ export const spec = { // Those params are not sent to the server. // They are used for further operations on analytics adapter. validBidRequests.forEach(rawBidRequest => { - rawBidRequest.params.adagioAuctionId = aucId rawBidRequest.params.pageviewId = pageviewId }); @@ -1193,19 +723,21 @@ export const spec = { url: ENDPOINT, data: { organizationId: organizationId, - hasRtd: hasRtd ? 1 : 0, + hasRtd: _internal.hasRtd() ? 1 : 0, secure: secure, device: device, site: site, pageviewId: pageviewId, adUnits: groupedAdUnits[organizationId], - data: dataExchange, + data: { + session: sessionData + }, regs: { gdpr: gdprConsent, coppa: coppa, ccpa: uspConsent, - gpp: gppConsent.gpp, - gppSid: gppConsent.gppSid, + gpp: gpp || '', + gppSid: gppSid || [], dsa: dsa // populated if exists }, schain: schain, @@ -1213,9 +745,7 @@ export const spec = { eids: eids }, prebidVersion: '$prebid.version$', - featuresVersion: FEATURES_VERSION, - usIfr: usIfr, - adgjs: storage.localStorageIsEnabled() + usIfr: canSyncWithIframe }, options: { contentType: 'text/plain' @@ -1232,11 +762,13 @@ export const spec = { const response = serverResponse.body; if (response) { if (response.data) { - internal.enqueue({ - action: 'ssp-data', - ts: Date.now(), - data: response.data - }); + if (_internal.hasRtd()) { + _internal.getAdagioNs().queue.push({ + action: 'ssp-data', + ts: Date.now(), + data: response.data + }); + } } if (response.bids) { response.bids.forEach(bidObj => { @@ -1300,6 +832,4 @@ export const spec = { }, }; -initAdagio(); - registerBidder(spec); diff --git a/modules/adagioRtdProvider.js b/modules/adagioRtdProvider.js index a901c2c489d..91f446e68fd 100644 --- a/modules/adagioRtdProvider.js +++ b/modules/adagioRtdProvider.js @@ -15,6 +15,8 @@ import { deepAccess, deepSetValue, generateUUID, + getDomLoadingDuration, + getSafeframeGeometry, getUniqueIdentifierStr, getWindowSelf, getWindowTop, @@ -24,6 +26,7 @@ import { isStr, prefixLog } from '../src/utils.js'; +import { _ADAGIO, getBestWindowForAdagio } from '../libraries/adagioUtils/adagioUtils.js'; import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; /** @@ -35,6 +38,11 @@ const ADAGIO_BIDDER_CODE = 'adagio'; const GVLID = 617; const SCRIPT_URL = 'https://script.4dex.io/a/latest/adagio.js'; const SESS_DURATION = 30 * 60 * 1000; +export const PLACEMENT_SOURCES = { + ORTB: 'ortb', // implicit default, not used atm. + ADUNITCODE: 'code', + GPID: 'gpid' +}; export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME }); const { logError, logWarn } = prefixLog('AdagioRtdProvider:'); @@ -42,23 +50,6 @@ const { logError, logWarn } = prefixLog('AdagioRtdProvider:'); // Guard to avoid storing the same bid data several times. const guard = new Set(); -/** - * Returns the window.ADAGIO global object used to store Adagio data. - * This object is created in window.top if possible, otherwise in window.self. - */ -const _ADAGIO = (function() { - const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf(); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.pageviewId = w.ADAGIO.pageviewId || generateUUID(); - w.ADAGIO.adUnits = w.ADAGIO.adUnits || {}; - w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || []; - w.ADAGIO.queue = w.ADAGIO.queue || []; - w.ADAGIO.windows = w.ADAGIO.windows || []; - - return w.ADAGIO; -})(); - /** * Store the sampling data. * This data is used to determine if beacons should be sent to adagio. @@ -82,20 +73,34 @@ const _SESSION = (function() { storage.getDataFromLocalStorage('adagio', (storageValue) => { // session can be an empty object - const { rnd, new: isNew, vwSmplg, vwSmplgNxt, lastActivityTime } = _internal.getSessionFromLocalStorage(storageValue); + const { rnd, new: isNew = false, vwSmplg, vwSmplgNxt, lastActivityTime, id, testName, testVersion, initiator } = _internal.getSessionFromLocalStorage(storageValue); + + // isNew can be `true` if the session has been initialized by the A/B test snippet (external) + const isNewSess = (initiator === 'snippet') ? isNew : isNewSession(lastActivityTime); data.session = { rnd, - new: isNew || false, // legacy: `new` was used but the choosen name is not good. + new: isNewSess, // legacy: `new` was used but the choosen name is not good. // Don't use values if they are not defined. ...(vwSmplg !== undefined && { vwSmplg }), ...(vwSmplgNxt !== undefined && { vwSmplgNxt }), - ...(lastActivityTime !== undefined && { lastActivityTime }) + ...(lastActivityTime !== undefined && { lastActivityTime }), + ...(id !== undefined && { id }), + ...(testName !== undefined && { testName }), + ...(testVersion !== undefined && { testVersion }), + ...(initiator !== undefined && { initiator }), }; - if (isNewSession(lastActivityTime)) { + // `initiator` is a pseudo flag used to know if the session has been initialized by the A/B test snippet (external). + // If the AB Test snippet has not been used, then `initiator` value is `adgjs` or `undefined`. + // The check on `testName` is used to ensure that the A/B test values are removed. + if (initiator !== 'snippet' && (isNewSess || testName)) { data.session.new = true; + data.session.id = generateUUID(); data.session.rnd = Math.random(); + // Ensure that the A/B test values are removed. + delete data.session.testName; + delete data.session.testVersion; } _internal.getAdagioNs().queue.push({ @@ -131,12 +136,14 @@ const _FEATURES = (function() { features.data = {}; }, get: function() { + const w = getBestWindowForAdagio(); + if (!features.initialized) { features.data = { page_dimensions: getPageDimensions().toString(), viewport_dimensions: getViewPortDimensions().toString(), user_timestamp: getTimestampUTC().toString(), - dom_loading: getDomLoadingDuration().toString(), + dom_loading: getDomLoadingDuration(w).toString(), }; features.initialized = true; } @@ -271,10 +278,12 @@ function onBidRequest(bidderRequest, config, _userConsent) { * @param {*} config */ function onGetBidRequestData(bidReqConfig, callback, config) { + const configParams = deepAccess(config, 'params', {}); const { site: ortb2Site } = bidReqConfig.ortb2Fragments.global; const features = _internal.getFeatures().get(); const ext = { uid: generateUUID(), + pageviewId: _ADAGIO.pageviewId, features: { ...features }, session: { ..._SESSION.get() } }; @@ -283,19 +292,40 @@ function onGetBidRequestData(bidReqConfig, callback, config) { const adUnits = bidReqConfig.adUnits || getGlobal().adUnits || []; adUnits.forEach(adUnit => { + adUnit.ortb2Imp = adUnit.ortb2Imp || {}; const ortb2Imp = deepAccess(adUnit, 'ortb2Imp'); + // A divId is required to compute the slot position and later to track viewability. // If nothing has been explicitly set, we try to get the divId from the GPT slot and fallback to the adUnit code in last resort. - if (!deepAccess(ortb2Imp, 'ext.data.divId')) { - const divId = getGptSlotInfoForAdUnitCode(adUnit.code).divId; + let divId = deepAccess(ortb2Imp, 'ext.data.divId') + if (!divId) { + divId = getGptSlotInfoForAdUnitCode(adUnit.code).divId; deepSetValue(ortb2Imp, `ext.data.divId`, divId || adUnit.code); } - const slotPosition = getSlotPosition(adUnit); + const slotPosition = getSlotPosition(divId); deepSetValue(ortb2Imp, `ext.data.adg_rtd.adunit_position`, slotPosition); - // We expect `pagetype` `category` are defined in FPD `ortb2.site.ext.data` object. - // `placement` is expected in FPD `adUnits[].ortb2Imp.ext.data` object. (Please note that this `placement` is not related to the oRTB video property.) + // It is expected that the publisher set a `adUnits[].ortb2Imp.ext.data.placement` value. + // Btw, We allow fallback sources to programmatically set this value. + // The source is defined in the `config.params.placementSource` and the possible values are `code` or `gpid`. + // (Please note that this `placement` is not related to the oRTB video property.) + if (!deepAccess(ortb2Imp, 'ext.data.placement')) { + const { placementSource = '' } = configParams; + + switch (placementSource.toLowerCase()) { + case PLACEMENT_SOURCES.ADUNITCODE: + deepSetValue(ortb2Imp, 'ext.data.placement', adUnit.code); + break; + case PLACEMENT_SOURCES.GPID: + deepSetValue(ortb2Imp, 'ext.data.placement', deepAccess(ortb2Imp, 'ext.gpid')); + break; + default: + logWarn('`ortb2Imp.ext.data.placement` is missing and `params.definePlacement` is not set in the config.'); + } + } + + // We expect that `pagetype`, `category`, `placement` are defined in FPD `ortb2.site.ext.data` and `adUnits[].ortb2Imp.ext.data` objects. // Btw, we have to ensure compatibility with publishers that use the "legacy" adagio params at the adUnit.params level. const adagioBid = adUnit.bids.find(bid => _internal.isAdagioBidder(bid.bidder)); if (adagioBid) { @@ -316,9 +346,6 @@ function onGetBidRequestData(bidReqConfig, callback, config) { if (adagioBid.params.placement) { deepSetValue(ortb2Imp, 'ext.data.placement', adagioBid.params.placement); mustWarnOrtb2Imp = true; - } else { - // If the placement is not defined, we fallback to the adUnit code. - deepSetValue(ortb2Imp, 'ext.data.placement', adUnit.code); } } @@ -420,7 +447,7 @@ function getElementFromTopWindow(element, currentWindow) { } }; -function getSlotPosition(adUnit) { +function getSlotPosition(divId) { if (!isSafeFrameWindow() && !canAccessWindowTop()) { return ''; } @@ -428,31 +455,28 @@ function getSlotPosition(adUnit) { const position = { x: 0, y: 0 }; if (isSafeFrameWindow()) { - const ws = getWindowSelf(); + const { self } = getSafeframeGeometry() || {}; - const sfGeom = (typeof ws.$sf.ext.geom === 'function') ? ws.$sf.ext.geom() : null; - - if (!sfGeom || !sfGeom.self) { + if (!self) { return ''; } - position.x = Math.round(sfGeom.self.t); - position.y = Math.round(sfGeom.self.l); + position.x = Math.round(self.t); + position.y = Math.round(self.l); } else { try { // window.top based computing const wt = getWindowTop(); const d = wt.document; - const adUnitElementId = deepAccess(adUnit, 'ortb2Imp.ext.data.divId'); let domElement; if (inIframe() === true) { const ws = getWindowSelf(); - const currentElement = ws.document.getElementById(adUnitElementId); + const currentElement = ws.document.getElementById(divId); domElement = getElementFromTopWindow(currentElement, ws); } else { - domElement = wt.document.getElementById(adUnitElementId); + domElement = wt.document.getElementById(divId); } if (!domElement) { @@ -513,16 +537,14 @@ function getViewPortDimensions() { const viewportDims = { w: 0, h: 0 }; if (isSafeFrameWindow()) { - const ws = getWindowSelf(); - - const sfGeom = (typeof ws.$sf.ext.geom === 'function') ? ws.$sf.ext.geom() : null; + const { win } = getSafeframeGeometry() || {}; - if (!sfGeom || !sfGeom.win) { + if (!win) { return ''; } - viewportDims.w = Math.round(sfGeom.win.w); - viewportDims.h = Math.round(sfGeom.win.h); + viewportDims.w = Math.round(win.w); + viewportDims.h = Math.round(win.h); } else { // window.top based computing const wt = getWindowTop(); @@ -538,22 +560,6 @@ function getTimestampUTC() { return Math.floor(new Date().getTime() / 1000) - new Date().getTimezoneOffset() * 60; } -function getDomLoadingDuration() { - const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf(); - const performance = w.performance; - - let domLoadingDuration = -1; - - if (performance && performance.timing && performance.timing.navigationStart > 0) { - const val = performance.timing.domLoading - performance.timing.navigationStart; - if (val > 0) { - domLoadingDuration = val; - } - } - - return domLoadingDuration; -} - /** * registerEventsForAdServers bind adagio listeners to ad-server events. * Theses events are used to track the viewability and attention. diff --git a/modules/adagioRtdProvider.md b/modules/adagioRtdProvider.md index f05521ec54a..a51137d571f 100644 --- a/modules/adagioRtdProvider.md +++ b/modules/adagioRtdProvider.md @@ -30,6 +30,7 @@ pbjs.setConfig({ params: { organizationId: '1000' // Required. Provided by Adagio site: 'my-site' // Required. Provided by Adagio + placementSource: 'ortb' // Optional. Where to find the "placement" value. Possible values: 'ortb' | 'code' | 'gpid' } }] } diff --git a/modules/adbookpspBidAdapter.js b/modules/adbookpspBidAdapter.js deleted file mode 100644 index cb03f2ffc17..00000000000 --- a/modules/adbookpspBidAdapter.js +++ /dev/null @@ -1,830 +0,0 @@ -import {find, includes} from '../src/polyfill.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; -import { - deepAccess, - deepSetValue, - flatten, - generateUUID, - inIframe, - isArray, - isEmptyStr, - isNumber, - isPlainObject, - isStr, - logError, - logWarn, - triggerPixel, - uniques -} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - -/** - * CONSTANTS - */ - -export const VERSION = '1.0.0'; -const EXCHANGE_URL = 'https://ex.fattail.com/openrtb2'; -const WIN_TRACKING_URL = 'https://ev.fattail.com/wins'; -const BIDDER_CODE = 'adbookpsp'; -const USER_ID_KEY = 'hb_adbookpsp_uid'; -const USER_ID_COOKIE_EXP = 2592000000; // lasts 30 days -const BID_TTL = 300; -const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO]; -const DEFAULT_CURRENCY = 'USD'; -const VIDEO_PARAMS = [ - 'mimes', - 'minduration', - 'maxduration', - 'protocols', - 'w', - 'h', - 'startdelay', - 'placement', - 'linearity', - 'skip', - 'skipmin', - 'skipafter', - 'sequence', - 'battr', - 'maxextended', - 'minbitrate', - 'maxbitrate', - 'boxingallowed', - 'playbackmethod', - 'playbackend', - 'delivery', - 'pos', - 'companionad', - 'api', - 'companiontype', - 'ext', -]; -const TARGETING_VALUE_SEPARATOR = ','; - -export const DEFAULT_BIDDER_CONFIG = { - bidTTL: BID_TTL, - defaultCurrency: DEFAULT_CURRENCY, - exchangeUrl: EXCHANGE_URL, - winTrackingEnabled: true, - winTrackingUrl: WIN_TRACKING_URL, - orgId: null, -}; - -config.setDefaults({ - adbookpsp: DEFAULT_BIDDER_CONFIG, -}); - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: SUPPORTED_MEDIA_TYPES, - - buildRequests, - getUserSyncs, - interpretResponse, - isBidRequestValid, - onBidWon, -}; - -registerBidder(spec); - -/** - * BID REQUEST - */ - -function isBidRequestValid(bidRequest) { - return ( - hasRequiredParams(bidRequest) && - (isValidBannerRequest(bidRequest) || isValidVideoRequest(bidRequest)) - ); -} - -function buildRequests(validBidRequests, bidderRequest) { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - const requests = []; - - if (validBidRequests.length > 0) { - requests.push({ - method: 'POST', - url: getBidderConfig('exchangeUrl'), - options: { - contentType: 'application/json', - withCredentials: true, - }, - data: buildRequest(validBidRequests, bidderRequest), - }); - } - - return requests; -} - -function buildRequest(validBidRequests, bidderRequest) { - const request = { - id: bidderRequest.bidderRequestId, - tmax: bidderRequest.timeout, - site: { - domain: bidderRequest.refererInfo.domain, - page: bidderRequest.refererInfo.page, - ref: bidderRequest.refererInfo.ref, - }, - source: buildSource(validBidRequests, bidderRequest), - device: buildDevice(), - regs: buildRegs(bidderRequest), - user: buildUser(bidderRequest), - imp: validBidRequests.map(buildImp), - ext: { - adbook: { - config: getBidderConfig(), - version: { - prebid: '$prebid.version$', - adapter: VERSION, - }, - }, - }, - }; - - return JSON.stringify(request); -} - -function buildDevice() { - const { innerWidth, innerHeight } = common.getWindowDimensions(); - - const device = { - w: innerWidth, - h: innerHeight, - js: true, - ua: navigator.userAgent, - dnt: - navigator.doNotTrack === 'yes' || - navigator.doNotTrack == '1' || - navigator.msDoNotTrack == '1' - ? 1 - : 0, - }; - - const deviceConfig = common.getConfig('device'); - - if (isPlainObject(deviceConfig)) { - return { ...device, ...deviceConfig }; - } - - return device; -} - -function buildRegs(bidderRequest) { - const regs = { - coppa: common.getConfig('coppa') === true ? 1 : 0, - }; - - if (bidderRequest.gdprConsent) { - deepSetValue( - regs, - 'ext.gdpr', - bidderRequest.gdprConsent.gdprApplies ? 1 : 0 - ); - deepSetValue( - regs, - 'ext.gdprConsentString', - bidderRequest.gdprConsent.consentString || '' - ); - } - - if (bidderRequest.uspConsent) { - deepSetValue(regs, 'ext.us_privacy', bidderRequest.uspConsent); - } - - return regs; -} - -function buildSource(bidRequests, bidderRequest) { - const source = { - fd: 1, - tid: bidderRequest.ortb2.source.tid, - }; - const schain = deepAccess(bidRequests, '0.schain'); - - if (schain) { - deepSetValue(source, 'ext.schain', schain); - } - - return source; -} - -function buildUser(bidderRequest) { - const user = { - id: getUserId(), - }; - - if (bidderRequest.gdprConsent) { - user.gdprConsentString = bidderRequest.gdprConsent.consentString || ''; - } - - return user; -} - -function buildImp(bidRequest) { - let impBase = { - id: bidRequest.bidId, - tagid: bidRequest.adUnitCode, - ext: buildImpExt(bidRequest), - }; - - return Object.keys(bidRequest.mediaTypes) - .filter((mediaType) => includes(SUPPORTED_MEDIA_TYPES, mediaType)) - .reduce((imp, mediaType) => { - return { - ...imp, - [mediaType]: buildMediaTypeObject(mediaType, bidRequest), - }; - }, impBase); -} - -function buildMediaTypeObject(mediaType, bidRequest) { - switch (mediaType) { - case BANNER: - return buildBannerObject(bidRequest); - case VIDEO: - return buildVideoObject(bidRequest); - default: - logWarn(`${BIDDER_CODE}: Unsupported media type ${mediaType}!`); - } -} - -function buildBannerObject(bidRequest) { - const format = bidRequest.mediaTypes.banner.sizes.map((size) => { - const [w, h] = size; - - return { w, h }; - }); - const { w, h } = format[0]; - - return { - pos: 0, - topframe: inIframe() ? 0 : 1, - format, - w, - h, - }; -} - -function buildVideoObject(bidRequest) { - const { w, h } = getVideoSize(bidRequest); - let videoObj = { - w, - h, - }; - - for (const param of VIDEO_PARAMS) { - const paramsValue = deepAccess(bidRequest, `params.video.${param}`); - const mediaTypeValue = deepAccess( - bidRequest, - `mediaTypes.video.${param}` - ); - - if (paramsValue || mediaTypeValue) { - videoObj[param] = paramsValue || mediaTypeValue; - } - } - - return videoObj; -} - -function getVideoSize(bidRequest) { - const playerSize = deepAccess(bidRequest, 'mediaTypes.video.playerSize', [[]]); - const { w, h } = deepAccess(bidRequest, 'mediaTypes.video', {}); - - if (isNumber(w) && isNumber(h)) { - return { w, h }; - } - - return { - w: playerSize[0][0], - h: playerSize[0][1], - } -} - -function buildImpExt(validBidRequest) { - const defaultOrgId = getBidderConfig('orgId'); - const { orgId, placementId } = validBidRequest.params || {}; - const effectiverOrgId = orgId || defaultOrgId; - const ext = {}; - - if (placementId) { - deepSetValue(ext, 'adbook.placementId', placementId); - } - - if (effectiverOrgId) { - deepSetValue(ext, 'adbook.orgId', effectiverOrgId); - } - - return ext; -} - -/** - * BID RESPONSE - */ - -function interpretResponse(bidResponse, bidderRequest) { - const bidderRequestBody = safeJSONparse(bidderRequest.data); - - if ( - deepAccess(bidderRequestBody, 'id') != - deepAccess(bidResponse, 'body.id') - ) { - logError( - `${BIDDER_CODE}: Bid response id does not match bidder request id` - ); - - return []; - } - - const referrer = deepAccess(bidderRequestBody, 'site.ref', ''); - const incomingBids = deepAccess(bidResponse, 'body.seatbid', []) - .filter((seat) => isArray(seat.bid)) - .reduce((bids, seat) => bids.concat(seat.bid), []) - .filter(validateBid(bidderRequestBody)); - const targetingMap = buildTargetingMap(incomingBids); - - return impBidsToPrebidBids( - incomingBids, - bidderRequestBody, - bidResponse.body.cur, - referrer, - targetingMap - ); -} - -function impBidsToPrebidBids( - incomingBids, - bidderRequestBody, - bidResponseCurrency, - referrer, - targetingMap -) { - return incomingBids - .map( - impToPrebidBid( - bidderRequestBody, - bidResponseCurrency, - referrer, - targetingMap - ) - ) - .filter((i) => i !== null); -} - -const impToPrebidBid = - (bidderRequestBody, bidResponseCurrency, referrer, targetingMap) => (bid, bidIndex) => { - try { - const bidRequest = findBidRequest(bidderRequestBody, bid); - - if (!bidRequest) { - logError(`${BIDDER_CODE}: Could not match bid to bid request`); - - return null; - } - const categories = deepAccess(bid, 'cat', []); - const mediaType = getMediaType(bid.adm); - let prebidBid = { - ad: bid.adm, - adId: bid.adid, - adserverTargeting: targetingMap[bidIndex], - adUnitCode: bidRequest.tagid, - bidderRequestId: bidderRequestBody.id, - bidId: bid.id, - cpm: bid.price, - creativeId: bid.crid || bid.id, - currency: bidResponseCurrency || getBidderConfig('defaultCurrency'), - height: bid.h, - lineItemId: deepAccess(bid, 'ext.liid'), - mediaType, - meta: { - advertiserDomains: bid.adomain, - mediaType, - primaryCatId: categories[0], - secondaryCatIds: categories.slice(1), - }, - netRevenue: true, - nurl: bid.nurl, - referrer: referrer, - requestId: bid.impid, - ttl: getBidderConfig('bidTTL'), - width: bid.w, - }; - - if (mediaType === VIDEO) { - prebidBid = { - ...prebidBid, - ...getVideoSpecificParams(bidRequest, bid), - }; - } - - if (deepAccess(bid, 'ext.pa_win') === true) { - prebidBid.auctionWinner = true; - } - return prebidBid; - } catch (error) { - logError(`${BIDDER_CODE}: Error while building bid`, error); - - return null; - } - }; - -function getVideoSpecificParams(bidRequest, bid) { - return { - height: bid.h || bidRequest.video.h, - vastXml: bid.adm, - width: bid.w || bidRequest.video.w, - }; -} - -function buildTargetingMap(bids) { - const impIds = bids.map(({ impid }) => impid).filter(uniques); - const values = impIds.reduce((result, id) => { - result[id] = { - lineItemIds: [], - orderIds: [], - dealIds: [], - adIds: [], - adAndOrderIndexes: [] - }; - - return result; - }, {}); - - bids.forEach((bid, bidIndex) => { - let impId = bid.impid; - values[impId].lineItemIds.push(bid.ext.liid); - values[impId].dealIds.push(bid.dealid); - values[impId].adIds.push(bid.adid); - - if (deepAccess(bid, 'ext.ordid')) { - values[impId].orderIds.push(bid.ext.ordid); - bid.ext.ordid.split(TARGETING_VALUE_SEPARATOR).forEach((ordid, ordIndex) => { - let adIdIndex = values[impId].adIds.indexOf(bid.adid); - values[impId].adAndOrderIndexes.push(adIdIndex + '_' + ordIndex) - }) - } - }); - - const targetingMap = {}; - - bids.forEach((bid, bidIndex) => { - let id = bid.impid; - - targetingMap[bidIndex] = { - hb_liid_adbookpsp: values[id].lineItemIds.join(TARGETING_VALUE_SEPARATOR), - hb_deal_adbookpsp: values[id].dealIds.join(TARGETING_VALUE_SEPARATOR), - hb_ad_ord_adbookpsp: values[id].adAndOrderIndexes.join(TARGETING_VALUE_SEPARATOR), - hb_adid_c_adbookpsp: values[id].adIds.join(TARGETING_VALUE_SEPARATOR), - hb_ordid_adbookpsp: values[id].orderIds.join(TARGETING_VALUE_SEPARATOR), - }; - }) - return targetingMap; -} - -/** - * VALIDATION - */ - -function hasRequiredParams(bidRequest) { - const value = - deepAccess(bidRequest, 'params.placementId') != null || - deepAccess(bidRequest, 'params.orgId') != null || - getBidderConfig('orgId') != null; - - if (!value) { - logError(`${BIDDER_CODE}: missing orgId and placementId parameter`); - } - - return value; -} - -function isValidBannerRequest(bidRequest) { - const value = validateSizes( - deepAccess(bidRequest, 'mediaTypes.banner.sizes', []) - ); - - return value; -} - -function isValidVideoRequest(bidRequest) { - const value = - isArray(deepAccess(bidRequest, 'mediaTypes.video.mimes')) && - validateVideoSizes(bidRequest); - - return value; -} - -function validateSize(size) { - return isArray(size) && size.length === 2 && size.every(isNumber); -} - -function validateSizes(sizes) { - return isArray(sizes) && sizes.length > 0 && sizes.every(validateSize); -} - -function validateVideoSizes(bidRequest) { - const { w, h } = deepAccess(bidRequest, 'mediaTypes.video', {}); - - return ( - validateSizes( - deepAccess(bidRequest, 'mediaTypes.video.playerSize') - ) || - (isNumber(w) && isNumber(h)) - ); -} - -function validateBid(bidderRequestBody) { - return function (bid) { - const mediaType = getMediaType(bid.adm); - const bidRequest = findBidRequest(bidderRequestBody, bid); - let validators = commonBidValidators; - - if (mediaType === BANNER) { - validators = [...commonBidValidators, ...bannerBidValidators]; - } - - const value = validators.every((validator) => validator(bid, bidRequest)); - - if (!value) { - logWarn(`${BIDDER_CODE}: Invalid bid`, bid); - } - - return value; - }; -} - -const commonBidValidators = [ - (bid) => isPlainObject(bid), - (bid) => isNonEmptyStr(bid.adid), - (bid) => isNonEmptyStr(bid.adm), - (bid) => isNonEmptyStr(bid.id), - (bid) => isNonEmptyStr(bid.impid), - (bid) => isNonEmptyStr(deepAccess(bid, 'ext.liid')), - (bid) => isNumber(bid.price), -]; - -const bannerBidValidators = [ - validateBannerDimension('w'), - validateBannerDimension('h'), -]; - -function validateBannerDimension(dimension) { - return function (bid, bidRequest) { - if (bid[dimension] == null) { - return bannerHasSingleSize(bidRequest); - } - - return isNumber(bid[dimension]); - }; -} - -function bannerHasSingleSize(bidRequest) { - return deepAccess(bidRequest, 'banner.format', []).length === 1; -} - -/** - * USER SYNC - */ - -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getUserSyncs(syncOptions, responses, gdprConsent, uspConsent) { - return responses - .map((response) => deepAccess(response, 'body.ext.sync')) - .filter(isArray) - .reduce(flatten, []) - .filter(validateSync(syncOptions)) - .map(applyConsents(gdprConsent, uspConsent)); -} - -const validateSync = (syncOptions) => (sync) => { - return ( - ((sync.type === 'image' && syncOptions.pixelEnabled) || - (sync.type === 'iframe' && syncOptions.iframeEnabled)) && - sync.url - ); -}; - -const applyConsents = (gdprConsent, uspConsent) => (sync) => { - const url = getUrlBuilder(sync.url); - - if (gdprConsent) { - url.set('gdpr', gdprConsent.gdprApplies ? 1 : 0); - url.set('consentString', gdprConsent.consentString || ''); - } - if (uspConsent) { - url.set('us_privacy', encodeURIComponent(uspConsent)); - } - if (common.getConfig('coppa') === true) { - url.set('coppa', 1); - } - - return { ...sync, url: url.toString() }; -}; - -function getUserId() { - const id = getUserIdFromStorage() || common.generateUUID(); - - setUserId(id); - - return id; -} - -function getUserIdFromStorage() { - const id = storage.localStorageIsEnabled() - ? storage.getDataFromLocalStorage(USER_ID_KEY) - : storage.getCookie(USER_ID_KEY); - - if (!validateUUID(id)) { - return; - } - - return id; -} - -function setUserId(userId) { - if (storage.localStorageIsEnabled()) { - storage.setDataInLocalStorage(USER_ID_KEY, userId); - } - - if (storage.cookiesAreEnabled()) { - const expires = new Date(Date.now() + USER_ID_COOKIE_EXP).toISOString(); - - storage.setCookie(USER_ID_KEY, userId, expires); - } -} - -function validateUUID(uuid) { - return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test( - uuid - ); -} - -/** - * EVENT TRACKING - */ - -function onBidWon(bid) { - if (!getBidderConfig('winTrackingEnabled')) { - return; - } - - const wurl = buildWinUrl(bid); - - if (wurl !== null) { - triggerPixel(wurl); - } - - if (isStr(bid.nurl)) { - triggerPixel(bid.nurl); - } -} - -function buildWinUrl(bid) { - try { - const url = getUrlBuilder(getBidderConfig('winTrackingUrl')); - - url.set('impId', bid.requestId); - url.set('reqId', bid.bidderRequestId); - url.set('bidId', bid.bidId); - - return url.toString(); - } catch (_) { - logError( - `${BIDDER_CODE}: Could not build win tracking URL with %s`, - getBidderConfig('winTrackingUrl') - ); - - return null; - } -} - -/** - * COMMON - */ - -const VAST_REGEXP = /VAST\s+version/; - -function getMediaType(adm) { - const videoRegex = new RegExp(VAST_REGEXP); - - if (videoRegex.test(adm)) { - return VIDEO; - } - - const markup = safeJSONparse(adm.replace(/\\/g, '')); - - if (markup && isPlainObject(markup.native)) { - return NATIVE; - } - - return BANNER; -} - -function safeJSONparse(...args) { - try { - return JSON.parse(...args); - } catch (_) { - return undefined; - } -} - -function isNonEmptyStr(value) { - return isStr(value) && !isEmptyStr(value); -} - -function findBidRequest(bidderRequest, bid) { - return find(bidderRequest.imp, (imp) => imp.id === bid.impid); -} - -function getBidderConfig(property) { - if (!property) { - return common.getConfig(`${BIDDER_CODE}`); - } - - return common.getConfig(`${BIDDER_CODE}.${property}`); -} - -const getUrlBase = function (url) { - return url.split('?')[0]; -}; - -const getUrlQuery = function (url) { - const query = url.split('?')[1]; - - if (!query) { - return; - } - - return '?' + query.split('#')[0]; -}; - -const getUrlHash = function (url) { - const hash = url.split('#')[1]; - - if (!hash) { - return; - } - - return '#' + hash; -}; - -const getUrlBuilder = function (url) { - const hash = getUrlHash(url); - const base = getUrlBase(url); - const query = getUrlQuery(url); - const pairs = []; - - function set(key, value) { - pairs.push([key, value]); - - return { - set, - toString, - }; - } - - function toString() { - if (!pairs.length) { - return url; - } - - const queryString = pairs - .map(function (pair) { - return pair.join('='); - }) - .join('&'); - - if (!query) { - return base + '?' + queryString + (hash || ''); - } - - return base + query + '&' + queryString + (hash || ''); - } - - return { - set, - toString, - }; -}; - -export const common = { - generateUUID: function () { - return generateUUID(); - }, - getConfig: function (property) { - return config.getConfig(property); - }, - getWindowDimensions: function () { - return { - innerWidth: window.innerWidth, - innerHeight: window.innerHeight, - }; - }, -}; diff --git a/modules/adbookpspBidAdapter.md b/modules/adbookpspBidAdapter.md deleted file mode 100644 index e258b1fd7c3..00000000000 --- a/modules/adbookpspBidAdapter.md +++ /dev/null @@ -1,191 +0,0 @@ -### Overview - -``` -Module Name: AdbookPSP Bid Adapter -Module Type: Bidder Adapter -Maintainer: hbsupport@fattail.com -``` - -### Description - -Prebid.JS adapter that connects to the AdbookPSP demand sources. - -*NOTE*: The AdBookPSP Bidder Adapter requires setup and approval before use. The adapter uses custom targeting keys that require a dedicated Google Ad Manager setup to work. Please reach out to your AdbookPSP representative for more details. - -### Bidder parameters - -Each adUnit with `adbookpsp` adapter has to have either `placementId` or `orgId` set. - -```js -var adUnits = [ - { - bids: [ - { - bidder: 'adbookpsp', - params: { - placementId: 'example-placement-id', - orgId: 'example-org-id', - }, - }, - ], - }, -]; -``` - -Alternatively, `orgId` can be set globally while configuring prebid.js: - -```js -pbjs.setConfig({ - adbookpsp: { - orgId: 'example-org-id', - }, -}); -``` - -*NOTE*: adUnit orgId will take precedence over the globally set orgId. - -#### Banner parameters - -Required: - -- sizes - -Example configuration: - -```js -var adUnits = [ - { - code: 'div-1', - mediaTypes: { - banner: { - sizes: [[300, 250]], - }, - } - }, -]; -``` - -#### Video parameters - -Required: - -- context -- mimes -- playerSize - -Additionaly, all `Video` object parameters described in chapter `3.2.7` of the [OpenRTB 2.5 specification](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) can be passed as bidder params. - -Example configuration: - -```js -var adUnits = [ - { - code: 'div-1', - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mp4', 'video/x-flv'], - playerSize: [400, 300], - protocols: [2, 3], - }, - }, - bids: [ - { - bidder: 'adbookpsp', - params: { - placementId: 'example-placement-id', - video: { - placement: 2, - }, - }, - }, - ], - }, -]; -``` - -*NOTE*: Supporting outstream video requires the publisher to set up a renderer as described [in the Prebid docs](https://docs.prebid.org/dev-docs/show-outstream-video-ads.html). - -#### Testing params - -To test the adapter, either `placementId: 'example-placement-id'` or `orgId: 'example-org-id'` can be used. - -*NOTE*: If any adUnit uses the testing params, all adUnits will receive testing responses. - -Example adUnit configuration: - -```js -var adUnits = [ - { - code: 'div-1', - mediaTypes: { - banner: { - sizes: [[300, 250]], - }, - }, - bids: [ - { - bidder: 'adbookpsp', - params: { - placementId: 'example-placement-id', - }, - }, - ], - }, -]; -``` - -Example google publisher tag configuration: - -```js -googletag - .defineSlot('/22094606581/example-adbookPSP', sizes, 'div-1') - .addService(googletag.pubads()); -``` - -### Configuration - -Setting of the `orgId` can be done in the `pbjs.setConfig()` call. If this is the case, both `orgId` and `placementId` become optional. Remember to only call `pbjs.setConfig()` once as each call overwrites anything set in previous calls. - -Enabling iframe based user syncs is also encouraged. - -```javascript -pbjs.setConfig({ - adbookpsp: { - orgId: 'example-org-id', - winTrackingEnabled: true, - }, - userSync: { - filterSettings: { - iframe: { - bidders: '*', - filter: 'include', - }, - }, - }, -}); -``` - -### Privacy - -GDPR and US Privacy are both supported by default. - -#### Event tracking - -This adapter tracks win events for it’s bids. This functionality can be disabled by adding `winTrackingEnabled: false` to the adapter configuration: - -```js -pbjs.setConfig({ - adbookpsp: { - winTrackingEnabled: false, - }, -}); -``` - -#### COPPA support - -COPPA support can be enabled for all the visitors by changing the config value: - -```js -config.setConfig({ coppa: true }); -``` diff --git a/modules/addefendBidAdapter.js b/modules/addefendBidAdapter.js index dbb186fdc86..a646400b083 100644 --- a/modules/addefendBidAdapter.js +++ b/modules/addefendBidAdapter.js @@ -1,5 +1,4 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getGlobal} from '../src/prebidGlobal.js'; const BIDDER_CODE = 'addefend'; @@ -17,7 +16,7 @@ export const spec = { }, buildRequests: function(validBidRequests, bidderRequest) { let bid = { - v: getGlobal().version, + v: 'v' + '$prebid.version$', auctionId: false, pageId: false, gdpr_applies: bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies ? bidderRequest.gdprConsent.gdprApplies : 'true', diff --git a/modules/adfBidAdapter.js b/modules/adfBidAdapter.js index 27fb36a225d..925c0b3500e 100644 --- a/modules/adfBidAdapter.js +++ b/modules/adfBidAdapter.js @@ -3,7 +3,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {deepAccess, deepClone, deepSetValue, mergeDeep, parseSizesInput} from '../src/utils.js'; +import {deepAccess, deepClone, deepSetValue, mergeDeep, parseSizesInput, setOnAny} from '../src/utils.js'; import {config} from '../src/config.js'; import {Renderer} from '../src/Renderer.js'; @@ -255,15 +255,6 @@ export const spec = { registerBidder(spec); -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - function flatten(arr) { return [].concat(...arr); } diff --git a/modules/adhashBidAdapter.js b/modules/adhashBidAdapter.js index 96e93883de6..7eb91dfcd52 100644 --- a/modules/adhashBidAdapter.js +++ b/modules/adhashBidAdapter.js @@ -7,6 +7,7 @@ const VERSION = '3.6'; const BAD_WORD_STEP = 0.1; const BAD_WORD_MIN = 0.2; const ADHASH_BIDDER_CODE = 'adhash'; +const storage = getStorageManager({ bidderCode: ADHASH_BIDDER_CODE }); /** * Function that checks the page where the ads are being served for brand safety. @@ -120,7 +121,7 @@ function brandSafety(badWords, maxScore) { .replaceAll(/\s\s+/g, ' ') .toLowerCase() .trim(); - const content = window.top.document.body.innerText.toLowerCase(); + const content = window.top.document.body.textContent.toLowerCase(); // \p{L} matches a single unicode code point in the category 'letter'. Matches any kind of letter from any language. const regexp = new RegExp('[\\p{L}]+', 'gu'); const wordsMatched = content.match(regexp); @@ -171,7 +172,6 @@ export const spec = { }, buildRequests: (validBidRequests, bidderRequest) => { - const storage = getStorageManager({ bidderCode: ADHASH_BIDDER_CODE }); const { gdprConsent } = bidderRequest; const bidRequests = []; const body = document.body; @@ -199,9 +199,11 @@ export const spec = { position: validBidRequests[i].adUnitCode }; let recentAds = []; + let recentAdsPrebid = []; if (storage.localStorageIsEnabled()) { const prefix = validBidRequests[i].params.prefix || 'adHash'; recentAds = JSON.parse(storage.getDataFromLocalStorage(prefix + 'recentAds') || '[]'); + recentAdsPrebid = JSON.parse(storage.getDataFromLocalStorage(prefix + 'recentAdsPrebid') || '[]'); } // Needed for the ad density calculation @@ -237,6 +239,7 @@ export const spec = { blockedCreatives: [], currentTimestamp: (new Date().getTime() / 1000) | 0, recentAds: recentAds, + recentAdsPrebid: recentAdsPrebid, GDPRApplies: gdprConsent ? gdprConsent.gdprApplies : null, GDPR: gdprConsent ? gdprConsent.consentString : null, servedAdsCount: window.adsCount, @@ -263,6 +266,19 @@ export const spec = { return []; } + if (storage.localStorageIsEnabled()) { + const prefix = request.bidRequest.params.prefix || 'adHash'; + let recentAdsPrebid = JSON.parse(storage.getDataFromLocalStorage(prefix + 'recentAdsPrebid') || '[]'); + recentAdsPrebid.push([ + (new Date().getTime() / 1000) | 0, + responseBody.creatives[0].advertiserId, + responseBody.creatives[0].budgetId, + responseBody.creatives[0].expectedHashes.length ? responseBody.creatives[0].expectedHashes[0] : '', + ]); + let recentAdsPrebidFinal = JSON.stringify(recentAdsPrebid.slice(-100)); + storage.setDataInLocalStorage(prefix + 'recentAdsPrebid', recentAdsPrebidFinal); + } + const publisherURL = JSON.stringify(request.bidRequest.params.platformURL); const bidderURL = request.bidRequest.params.bidderURL || 'https://bidder.adhash.com'; const oneTimeId = request.bidRequest.adUnitCode + Math.random().toFixed(16).replace('0.', '.'); diff --git a/modules/adkernelAdnBidAdapter.js b/modules/adkernelAdnBidAdapter.js index 81067a3efcf..ae5528f2aeb 100644 --- a/modules/adkernelAdnBidAdapter.js +++ b/modules/adkernelAdnBidAdapter.js @@ -2,6 +2,7 @@ import {deepAccess, deepSetValue, isArray, isNumber, isStr, logInfo, parseSizesI import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; +import {getBidFloor} from '../libraries/adkernelUtils/adkernelUtils.js' const DEFAULT_ADKERNEL_DSP_DOMAIN = 'tag.adkernel.com'; const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; @@ -143,18 +144,6 @@ function fillBidMeta(bid, tag) { } } -function getBidFloor(bid, mediaType, sizes) { - var floor; - var size = sizes.length === 1 ? sizes[0] : '*'; - if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({currency: 'USD', mediaType, size}); - if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { - floor = parseFloat(floorInfo.floor); - } - } - return floor; -} - export const spec = { code: 'adkernelAdn', gvlid: GVLID, diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index 151e08bd2bb..20cd9233391 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -20,6 +20,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {find} from '../src/polyfill.js'; import {config} from '../src/config.js'; import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; +import {getBidFloor} from '../libraries/adkernelUtils/adkernelUtils.js' /** * In case you're AdKernel whitelable platform's client who needs branded adapter to @@ -95,7 +96,9 @@ export const spec = { {code: 'headbidder'}, {code: 'digiad'}, {code: 'monetix'}, - {code: 'hyperbrainz'} + {code: 'hyperbrainz'}, + {code: 'globalsun'}, + {code: 'voisetech'} ], supportedMediaTypes: [BANNER, VIDEO, NATIVE], @@ -246,18 +249,6 @@ function groupImpressionsByHostZone(bidRequests, refererInfo) { ); } -function getBidFloor(bid, mediaType, sizes) { - var floor; - var size = sizes.length === 1 ? sizes[0] : '*'; - if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({currency: 'USD', mediaType, size}); - if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { - floor = parseFloat(floorInfo.floor); - } - } - return floor; -} - /** * Builds rtb imp object(s) for single adunit * @param bidRequest {BidRequest} diff --git a/modules/adlooxAnalyticsAdapter.js b/modules/adlooxAnalyticsAdapter.js index e31ea290e11..f18c9e72337 100644 --- a/modules/adlooxAnalyticsAdapter.js +++ b/modules/adlooxAnalyticsAdapter.js @@ -232,6 +232,7 @@ analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = function(auctionDetails) { link.setAttribute('href', `${uri.protocol}://${uri.host}${uri.pathname}`); link.setAttribute('rel', 'preload'); link.setAttribute('as', 'script'); + // TODO fix rules violation insertElement(link); } diff --git a/modules/adlooxRtdProvider.js b/modules/adlooxRtdProvider.js index 727dc84e399..1545588676d 100644 --- a/modules/adlooxRtdProvider.js +++ b/modules/adlooxRtdProvider.js @@ -106,7 +106,7 @@ function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) { // buildUrl creates PHP style multi-parameters and includes undefined... (╯°□°)╯ ┻━┻ const url = buildUrl(mergeDeep(parseUrl(`${API_ORIGIN}/q`), { search: { - 'v': `pbjs-${getGlobal().version}`, + 'v': 'pbjs-v' + '$prebid.version$', 'c': config.params.clientid, 'p': config.params.platformid, 't': config.params.tagid, diff --git a/modules/admanBidAdapter.js b/modules/admanBidAdapter.js index b78737722bd..6778e536a1b 100644 --- a/modules/admanBidAdapter.js +++ b/modules/admanBidAdapter.js @@ -1,207 +1,51 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { isFn, deepAccess, logMessage } from '../src/utils.js'; -import {config} from '../src/config.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { deepAccess } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { + isBidRequestValid, + buildRequestsBase, + interpretResponse, + getUserSyncs, + buildPlacementProcessingFunction +} from '../libraries/teqblazeUtils/bidderUtils.js'; const GVLID = 149; const BIDDER_CODE = 'adman'; const AD_URL = 'https://pub.admanmedia.com/?c=o&m=multi'; -const URL_SYNC = 'https://sync.admanmedia.com'; +const SYNC_URL = 'https://sync.admanmedia.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid['mediaType']) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} +const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => { + placement.traffic = placement.adFormat; -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); + if (placement.adFormat === VIDEO) { + placement.wPlayer = placement.playerSize?.[0]?.[0]; + placement.hPlayer = placement.playerSize?.[0]?.[1]; } +}; - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} +const placementProcessingFunction = buildPlacementProcessingFunction({ addCustomFieldsToPlacement }); + +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + const request = buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction }); + const content = deepAccess(bidderRequest, 'ortb2.site.content', config.getAnyConfig('ortb2.site.content')); -function getUserId(eids, id, source, uidExt) { - if (id) { - var uid = { id }; - if (uidExt) { - uid.ext = uidExt; - } - eids.push({ - source, - uids: [ uid ] - }); + if (content) { + request.data.content = content; } -} + + return request; +}; export const spec = { code: BIDDER_CODE, gvlid: GVLID, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(bid.params.placementId)); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - const content = deepAccess(bidderRequest, 'ortb2.site.content', config.getAnyConfig('ortb2.site.content')); - - let winTop = window; - let location; - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page) - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - request.language.indexOf('-') != -1 && (request.language = request.language.split('-')[0]) - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - if (content) { - request.content = content; - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - const { params, bidId, mediaTypes } = bid; - - const placement = { - placementId: params.placementId, - bidId, - eids: [], - bidFloor: getBidFloor(bid) - } - - if (bid.transactionId) { - placement.ext = placement.ext || {}; - placement.ext.tid = bid.transactionId; - } - - if (bid.schain) { - placement.schain = bid.schain; - } - - if (bid.userId) { - getUserId(placement.eids, bid.userId.uid2 && bid.userId.uid2.id, 'uidapi.com'); - getUserId(placement.eids, bid.userId.lotamePanoramaId, 'lotame.com'); - getUserId(placement.eids, bid.userId.idx, 'idx.lat'); - } - - if (mediaTypes?.[BANNER]) { - placement.traffic = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes?.[VIDEO]) { - placement.traffic = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } - - placements.push(placement); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - serverResponse = serverResponse.body; - for (let i = 0; i < serverResponse.length; i++) { - let resItem = serverResponse[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = URL_SYNC + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } - + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests, + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/admixerBidAdapter.js b/modules/admixerBidAdapter.js index de7b941d614..e979bd07b51 100644 --- a/modules/admixerBidAdapter.js +++ b/modules/admixerBidAdapter.js @@ -13,7 +13,7 @@ const ALIASES = [ {code: 'futureads', endpoint: 'https://ads.futureads.io/prebid.1.2.aspx'}, {code: 'smn', endpoint: 'https://ads.smn.rs/prebid.1.2.aspx'}, {code: 'admixeradx', endpoint: 'https://inv-nets.admixer.net/adxprebid.1.2.aspx'}, - {code: 'admixerwl', endpoint: 'https://inv-nets-adxwl.admixer.com/adxwlprebid.aspx'}, + 'rtbstack' ]; export const spec = { code: BIDDER_CODE, @@ -23,8 +23,8 @@ export const spec = { * Determines whether or not the given bid request is valid. */ isBidRequestValid: function (bid) { - return bid.bidder === 'admixerwl' - ? !!bid.params.clientId && !!bid.params.endpointId + return bid.bidder === 'rtbstack' + ? !!bid.params.tagId : !!bid.params.zone; }, /** @@ -51,8 +51,12 @@ export const spec = { }; let endpointUrl; if (bidderRequest) { - const {bidderCode} = bidderRequest; - endpointUrl = config.getConfig(`${bidderCode}.endpoint_url`); + // checks if there is specified any endpointUrl in bidder config + endpointUrl = config.getConfig('bidderURL'); + if (!endpointUrl && bidderRequest.bidderCode === 'rtbstack') { + logError('The bidderUrl config is required for RTB Stack bids. Please set it with setBidderConfig() for "rtbstack".'); + return; + } // TODO: is 'page' the right value here? if (bidderRequest.refererInfo?.page) { payload.referrer = encodeURIComponent(bidderRequest.refererInfo.page); @@ -82,7 +86,7 @@ export const spec = { let urlForRequest = endpointUrl || getEndpointUrl(bidderRequest.bidderCode) return { method: 'POST', - url: bidderRequest.bidderCode === 'admixerwl' ? `${urlForRequest}?client=${payload.imps[0]?.params?.clientId}` : urlForRequest, + url: urlForRequest, data: payload, }; }, diff --git a/modules/admixerBidAdapter.md b/modules/admixerBidAdapter.md index 64f8dd64ee4..097e7feb95e 100644 --- a/modules/admixerBidAdapter.md +++ b/modules/admixerBidAdapter.md @@ -51,7 +51,7 @@ Please use ```admixer``` as the bidder code. ]; ``` -### AdmixerWL Test Parameters +### RTB Stack Test Parameters ``` var adUnits = [ { @@ -59,10 +59,9 @@ Please use ```admixer``` as the bidder code. sizes: [[300, 250]], // a display size bids: [ { - bidder: "admixer", + bidder: "rtbstack", params: { - endpointId: 41512, - clientId: 62 + tagId: 41512 } } ] @@ -71,10 +70,9 @@ Please use ```admixer``` as the bidder code. sizes: [[300, 50]], // a mobile size bids: [ { - bidder: "admixer", + bidder: "rtbstack", params: { - endpointId: 41512, - clientId: 62 + tagId: 41512 } } ] @@ -84,10 +82,9 @@ Please use ```admixer``` as the bidder code. mediaType: 'video', bids: [ { - bidder: "admixer", + bidder: "rtbstack", params: { - endpointId: 41512, - clientId: 62 + tagId: 41512 } } ] diff --git a/modules/adnuntiusBidAdapter.js b/modules/adnuntiusBidAdapter.js index 189e2287571..c9275e6bd0b 100644 --- a/modules/adnuntiusBidAdapter.js +++ b/modules/adnuntiusBidAdapter.js @@ -1,6 +1,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { isStr, deepAccess } from '../src/utils.js'; +import {isStr, isEmpty, deepAccess, getUnixTimestampFromNow, convertObjectToArray} from '../src/utils.js'; import { config } from '../src/config.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -19,10 +19,6 @@ const METADATA_KEY = 'adn.metaData'; const METADATA_KEY_SEPARATOR = '@@@'; export const misc = { - getUnixTimestamp: function (addDays, asMinutes) { - const multiplication = addDays / (asMinutes ? 1440 : 1); - return Date.now() + (addDays && addDays > 0 ? (1000 * 60 * 60 * 24 * multiplication) : 0); - } }; const storageTool = (function () { @@ -50,11 +46,11 @@ const storageTool = (function () { if (datum.key === 'voidAuIds' && Array.isArray(datum.value)) { return true; } - return datum.key && datum.value && datum.exp && datum.exp > misc.getUnixTimestamp() && (!network || network === datum.network); + return datum.key && datum.value && datum.exp && datum.exp > getUnixTimestampFromNow() && (!network || network === datum.network); }) : []; const voidAuIdsEntry = filteredEntries.find(entry => entry.key === 'voidAuIds'); if (voidAuIdsEntry) { - const now = misc.getUnixTimestamp(); + const now = getUnixTimestampFromNow(); voidAuIdsEntry.value = voidAuIdsEntry.value.filter(voidAuId => voidAuId.auId && voidAuId.exp > now); if (!voidAuIdsEntry.value.length) { filteredEntries = filteredEntries.filter(entry => entry.key !== 'voidAuIds'); @@ -73,7 +69,7 @@ const storageTool = (function () { const notNewExistingAuIds = currentVoidAuIds.filter(auIdObj => { return newAuIds.indexOf(auIdObj.value) < -1; }) || []; - const oneDayFromNow = misc.getUnixTimestamp(1); + const oneDayFromNow = getUnixTimestampFromNow(1); const apiIdsArray = newAuIds.map(auId => { return { exp: oneDayFromNow, auId: auId }; }) || []; @@ -86,7 +82,7 @@ const storageTool = (function () { if (key !== 'voidAuIds') { metaAsObj[key + METADATA_KEY_SEPARATOR + network] = { value: apiRespMetadata[key], - exp: misc.getUnixTimestamp(100), + exp: getUnixTimestampFromNow(100), network: network } } @@ -201,10 +197,14 @@ const targetingTool = (function() { }, mergeKvsFromOrtb: function(bidTargeting, bidderRequest) { const kv = getKvsFromOrtb(bidderRequest || {}); - if (!kv) { + if (isEmpty(kv)) { return; } - bidTargeting.kv = {...kv, ...bidTargeting.kv}; + if (bidTargeting.kv && !Array.isArray(bidTargeting.kv)) { + bidTargeting.kv = convertObjectToArray(bidTargeting.kv); + } + bidTargeting.kv = bidTargeting.kv || []; + bidTargeting.kv = bidTargeting.kv.concat(convertObjectToArray(kv)); } } })(); @@ -252,6 +252,7 @@ export const spec = { const bidderConfig = config.getConfig(); if (bidderConfig.useCookie === false) queryParamsAndValues.push('noCookies=true'); + if (bidderConfig.advertiserTransparency === true) queryParamsAndValues.push('advertiserTransparency=true'); if (bidderConfig.maxDeals > 0) queryParamsAndValues.push('ds=' + Math.min(bidderConfig.maxDeals, MAXIMUM_DEALS_LIMIT)); const bidRequests = {}; diff --git a/modules/adomikAnalyticsAdapter.js b/modules/adomikAnalyticsAdapter.js deleted file mode 100644 index d6e1547cce8..00000000000 --- a/modules/adomikAnalyticsAdapter.js +++ /dev/null @@ -1,262 +0,0 @@ -import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {EVENTS} from '../src/constants.js'; -import adapterManager from '../src/adapterManager.js'; -import {logInfo} from '../src/utils.js'; -import {find, findIndex} from '../src/polyfill.js'; - -// Events used in adomik analytics adapter. -const auctionInit = EVENTS.AUCTION_INIT; -const auctionEnd = EVENTS.AUCTION_END; -const bidRequested = EVENTS.BID_REQUESTED; -const bidResponse = EVENTS.BID_RESPONSE; -const bidWon = EVENTS.BID_WON; -const bidTimeout = EVENTS.BID_TIMEOUT; -const ua = navigator.userAgent; - -var _sampled = true; - -let adomikAdapter = Object.assign(adapter({}), - { - // Track every event needed - track({ eventType, args }) { - switch (eventType) { - case auctionInit: - adomikAdapter.initializeBucketEvents() - adomikAdapter.currentContext.id = args.auctionId - break; - - case bidTimeout: - adomikAdapter.currentContext.timeouted = true; - break; - - case bidResponse: - adomikAdapter.saveBidResponse(args); - break; - - case bidWon: - args.id = args.adId; - args.placementCode = args.adUnitCode; - adomikAdapter.sendWonEvent(args); - break; - - case bidRequested: - args.bids.forEach(function(bid) { - adomikAdapter.bucketEvents.push({ - type: 'request', - event: { - bidder: bid.bidder.toUpperCase(), - placementCode: bid.adUnitCode - } - }); - }); - break; - - case auctionEnd: - if (adomikAdapter.bucketEvents.length > 0) { - adomikAdapter.sendTypedEvent(); - } - break; - } - } - } -); - -adomikAdapter.initializeBucketEvents = function() { - adomikAdapter.bucketEvents = []; -} - -adomikAdapter.saveBidResponse = function(args) { - let responseSaved = adomikAdapter.bucketEvents.find((bucketEvent) => - bucketEvent.type == 'response' && bucketEvent.event.id == args.id - ); - if (responseSaved) { return true; } - adomikAdapter.bucketEvents.push({ - type: 'response', - event: adomikAdapter.buildBidResponse(args) - }); -} - -adomikAdapter.maxPartLength = function () { - return (ua.includes(' MSIE ')) ? 1600 : 60000; -}; - -adomikAdapter.sendTypedEvent = function() { - let [testId, testValue] = adomikAdapter.getKeyValues(); - const groupedTypedEvents = adomikAdapter.buildTypedEvents(); - - const bulkEvents = { - testId: testId, - testValue: testValue, - uid: adomikAdapter.currentContext.uid, - ahbaid: adomikAdapter.currentContext.id, - hostname: window.location.hostname, - sampling: adomikAdapter.currentContext.sampling, - eventsByPlacementCode: groupedTypedEvents.map(function(typedEventsByType) { - let sizes = []; - const eventKeys = ['request', 'response', 'winner']; - let events = {}; - - eventKeys.forEach((eventKey) => { - events[`${eventKey}s`] = []; - if (typedEventsByType[eventKey] !== undefined) { - typedEventsByType[eventKey].forEach((typedEvent) => { - if (typedEvent.event.size !== undefined) { - const size = adomikAdapter.sizeUtils.handleSize(sizes, typedEvent.event.size); - if (size !== null) { - sizes = [...sizes, size]; - } - } - events[`${eventKey}s`] = [...events[`${eventKey}s`], typedEvent.event]; - }); - } - }); - - return { - placementCode: typedEventsByType.placementCode, - sizes, - events - }; - }) - }; - - const stringBulkEvents = JSON.stringify(bulkEvents) - logInfo('Events sent to adomik prebid analytic ' + stringBulkEvents); - - const encodedBuf = window.btoa(stringBulkEvents); - - const encodedUri = encodeURIComponent(encodedBuf); - const maxLength = adomikAdapter.maxPartLength(); - const splittedUrl = encodedUri.match(new RegExp(`.{1,${maxLength}}`, 'g')); - - splittedUrl.forEach((split, i) => { - const partUrl = `${split}&id=${adomikAdapter.currentContext.id}&part=${i}&on=${splittedUrl.length - 1}`; - const img = new Image(1, 1); - img.src = 'https://' + adomikAdapter.currentContext.url + '/?q=' + partUrl; - }) -}; - -adomikAdapter.sendWonEvent = function (wonEvent) { - let [testId, testValue] = adomikAdapter.getKeyValues(); - let keyValues = { testId: testId, testValue: testValue }; - let samplingInfo = { sampling: adomikAdapter.currentContext.sampling }; - wonEvent = { ...adomikAdapter.buildBidResponse(wonEvent), ...keyValues, ...samplingInfo }; - - const stringWonEvent = JSON.stringify(wonEvent); - logInfo('Won event sent to adomik prebid analytic ' + stringWonEvent); - - const encodedBuf = window.btoa(stringWonEvent); - const encodedUri = encodeURIComponent(encodedBuf); - const img = new Image(1, 1); - img.src = `https://${adomikAdapter.currentContext.url}/?q=${encodedUri}&id=${adomikAdapter.currentContext.id}&won=true`; -} - -adomikAdapter.buildBidResponse = function (bid) { - return { - bidder: bid.bidderCode.toUpperCase(), - placementCode: bid.adUnitCode, - id: bid.adId, - status: (bid.statusMessage === 'Bid available') ? 'VALID' : 'EMPTY_OR_ERROR', - cpm: parseFloat(bid.cpm), - size: { - width: Number(bid.width), - height: Number(bid.height) - }, - timeToRespond: bid.timeToRespond, - afterTimeout: adomikAdapter.currentContext.timeouted - }; -} - -adomikAdapter.sizeUtils = { - sizeAlreadyExists: (sizes, typedEventSize) => { - return find(sizes, (size) => size.height === typedEventSize.height && size.width === typedEventSize.width); - }, - formatSize: (typedEventSize) => { - return { - width: Number(typedEventSize.width), - height: Number(typedEventSize.height) - }; - }, - handleSize: (sizes, typedEventSize) => { - let formattedSize = null; - if (adomikAdapter.sizeUtils.sizeAlreadyExists(sizes, typedEventSize) === undefined) { - formattedSize = adomikAdapter.sizeUtils.formatSize(typedEventSize); - } - return formattedSize; - } -}; - -adomikAdapter.buildTypedEvents = function () { - const groupedTypedEvents = []; - adomikAdapter.bucketEvents.forEach(function(typedEvent, i) { - const [placementCode, type] = [typedEvent.event.placementCode, typedEvent.type]; - let existTypedEvent = findIndex(groupedTypedEvents, (groupedTypedEvent) => groupedTypedEvent.placementCode === placementCode); - - if (existTypedEvent === -1) { - groupedTypedEvents.push({ - placementCode: placementCode, - [type]: [typedEvent] - }); - existTypedEvent = groupedTypedEvents.length - 1; - } - - if (groupedTypedEvents[existTypedEvent][type]) { - groupedTypedEvents[existTypedEvent][type] = [...groupedTypedEvents[existTypedEvent][type], typedEvent]; - } else { - groupedTypedEvents[existTypedEvent][type] = [typedEvent]; - } - }); - - return groupedTypedEvents; -} - -adomikAdapter.getKeyValues = function () { - let preventTest = sessionStorage.getItem(window.location.hostname + '_NoAdomikTest') - let inScope = sessionStorage.getItem(window.location.hostname + '_AdomikTestInScope') - let keyValues = JSON.parse(sessionStorage.getItem(window.location.hostname + '_AdomikTest')) - let testId; - let testValue; - if (typeof (keyValues) === 'object' && keyValues != undefined && !preventTest && inScope) { - testId = keyValues.testId - testValue = keyValues.testOptionLabel - } - return [testId, testValue] -} - -adomikAdapter.enable = function(options) { - adomikAdapter.currentContext = { - uid: options.id, - url: options.url, - id: '', - timeouted: false, - sampling: options.sampling - } - logInfo('Adomik Analytics enabled with config', options); - adomikAdapter.adapterEnableAnalytics(options); -}; - -adomikAdapter.checkOptions = function(options) { - if (typeof options !== 'undefined') { - if (options.id && options.url) { adomikAdapter.enable(options); } else { logInfo('Adomik Analytics disabled because id and/or url is missing from config', options); } - } else { logInfo('Adomik Analytics disabled because config is missing'); } -}; - -adomikAdapter.checkSampling = function(options) { - _sampled = typeof options === 'undefined' || - typeof options.sampling === 'undefined' || - (options.sampling > 0 && Math.random() < parseFloat(options.sampling)); - if (_sampled) { adomikAdapter.checkOptions(options) } else { logInfo('Adomik Analytics ignored for sampling', options.sampling); } -}; - -adomikAdapter.adapterEnableAnalytics = adomikAdapter.enableAnalytics; - -adomikAdapter.enableAnalytics = function ({ provider, options }) { - logInfo('Adomik Analytics enableAnalytics', provider); - adomikAdapter.checkSampling(options); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: adomikAdapter, - code: 'adomik' -}); - -export default adomikAdapter; diff --git a/modules/adotBidAdapter.js b/modules/adotBidAdapter.js index 9f2810e13df..fd24ccdeecb 100644 --- a/modules/adotBidAdapter.js +++ b/modules/adotBidAdapter.js @@ -197,7 +197,7 @@ function buildVideo(video) { mimes: video.mimes, minduration: video.minduration, maxduration: video.maxduration, - placement: video.placement, + placement: video.plcmt, playbackmethod: video.playbackmethod, pos: video.position || 0, protocols: video.protocols, diff --git a/modules/adprimeBidAdapter.js b/modules/adprimeBidAdapter.js index 55ee1f0900c..e40d20356af 100644 --- a/modules/adprimeBidAdapter.js +++ b/modules/adprimeBidAdapter.js @@ -1,183 +1,46 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { isFn, deepAccess, logMessage } from '../src/utils.js'; -import { config } from '../src/config.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import {getAllOrtbKeywords} from '../libraries/keywords/keywords.js'; +import { getAllOrtbKeywords } from '../libraries/keywords/keywords.js'; +import { + isBidRequestValid, + buildRequestsBase, + interpretResponse, + getUserSyncs, + buildPlacementProcessingFunction +} from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'adprime'; const AD_URL = 'https://delta.adprime.com/pbjs'; const SYNC_URL = 'https://sync.adprime.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency || !bid.meta) { - return false; +const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => { + if (placement.adFormat === VIDEO) { + placement.wPlayer = placement.playerSize?.[0]?.[0]; + placement.hPlayer = placement.playerSize?.[0]?.[1]; } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; + if (bid.userId && bid.userId.idl_env) { + placement.identeties = {}; + placement.identeties.identityLink = bid.userId.idl_env; } -} -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } + placement.keywords = getAllOrtbKeywords(bidderRequest.ortb2, bid.params.keywords); + placement.audiences = bid.params.audiences || []; +}; - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} +const placementProcessingFunction = buildPlacementProcessingFunction({ addCustomFieldsToPlacement }); + +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + return buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction }); +}; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && bid.params.placementId); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let winTop = window; - let location; - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page) - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; - let placements = []; - let request = { - deviceWidth: winTop.screen.width, - deviceHeight: winTop.screen.height, - language: (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - secure: 1, - host: location.host, - page: location.pathname, - placements: placements - }; - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - let bid = validBidRequests[i]; - const { mediaTypes } = bid; - const placement = {}; - let sizes - let identeties = {} - if (mediaTypes) { - if (mediaTypes[BANNER] && mediaTypes[BANNER].sizes) { - placement.adFormat = BANNER; - sizes = mediaTypes[BANNER].sizes - } else if (mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize) { - placement.adFormat = VIDEO; - sizes = mediaTypes[VIDEO].playerSize - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else { - placement.adFormat = NATIVE; - placement.native = mediaTypes[NATIVE]; - } - } - if (bid.userId && bid.userId.idl_env) { - identeties.identityLink = bid.userId.idl_env - } - - placements.push({ - ...placement, - placementId: bid.params.placementId, - bidId: bid.bidId, - sizes: sizes || [], - wPlayer: sizes ? sizes[0] : 0, - hPlayer: sizes ? sizes[1] : 0, - schain: bid.schain || {}, - keywords: getAllOrtbKeywords(bidderRequest.ortb2, bid.params.keywords), - audiences: bid.params.audiences || [], - identeties, - bidFloor: getBidFloor(bid) - }); - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests, + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/adtelligentBidAdapter.js b/modules/adtelligentBidAdapter.js index a95b9ed5652..afdc49a71f4 100644 --- a/modules/adtelligentBidAdapter.js +++ b/modules/adtelligentBidAdapter.js @@ -4,7 +4,6 @@ import {ADPOD, BANNER, VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; import {Renderer} from '../src/Renderer.js'; import {find} from '../src/polyfill.js'; -import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; import {chunk} from '../libraries/chunk/chunk.js'; /** @@ -138,11 +137,6 @@ export const spec = { return bids; }, - transformBidParams(params) { - return convertTypes({ - 'aid': 'number', - }, params); - } }; function parseRTBResponse(serverResponse, adapterRequest) { diff --git a/modules/adtrgtmeBidAdapter.js b/modules/adtrgtmeBidAdapter.js index 4dc95ce6bc1..955e908f000 100644 --- a/modules/adtrgtmeBidAdapter.js +++ b/modules/adtrgtmeBidAdapter.js @@ -2,7 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; import { deepAccess, isFn, isStr, isNumber, isArray, isEmpty, isPlainObject, generateUUID, logWarn } from '../src/utils.js'; import { config } from '../src/config.js'; -import { hasPurpose1Consent } from '../src/utils/gpdr.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; const INTEGRATION_METHOD = 'prebid.js'; const BIDDER_CODE = 'adtrgtme'; diff --git a/modules/adtrueBidAdapter.js b/modules/adtrueBidAdapter.js index 389986eb586..a6186d6129f 100644 --- a/modules/adtrueBidAdapter.js +++ b/modules/adtrueBidAdapter.js @@ -43,6 +43,7 @@ const VIDEO_CUSTOM_PARAMS = { 'battr': DATA_TYPES.ARRAY, 'linearity': DATA_TYPES.NUMBER, 'placement': DATA_TYPES.NUMBER, + 'plcmt': DATA_TYPES.NUMBER, 'minbitrate': DATA_TYPES.NUMBER, 'maxbitrate': DATA_TYPES.NUMBER }; diff --git a/modules/advRedAnalyticsAdapter.js b/modules/advRedAnalyticsAdapter.js new file mode 100644 index 00000000000..8ad30ed351d --- /dev/null +++ b/modules/advRedAnalyticsAdapter.js @@ -0,0 +1,198 @@ +import {generateUUID, logInfo} from '../src/utils.js' +import {ajaxBuilder} from '../src/ajax.js' +import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js' +import adapterManager from '../src/adapterManager.js' +import {EVENTS} from '../src/constants.js' +import {getRefererInfo} from '../src/refererDetection.js'; + +/** + * advRedAnalyticsAdapter.js - analytics adapter for AdvRed + */ +const DEFAULT_EVENT_URL = 'https://api.adv.red/api/event' + +let ajax = ajaxBuilder(10000) +let pwId +let initOptions +let flushInterval +let queue = [] + +let advRedAnalytics = Object.assign(adapter({url: DEFAULT_EVENT_URL, analyticsType: 'endpoint'}), { + track({eventType, args}) { + handleEvent(eventType, args) + } +}) + +function sendEvents() { + if (queue.length > 0) { + const message = { + pwId: pwId, + publisherId: initOptions.publisherId, + events: queue, + pageUrl: getRefererInfo().page + } + queue = [] + + const url = initOptions.url ? initOptions.url : DEFAULT_EVENT_URL + ajax( + url, + () => logInfo('AdvRed Analytics sent ' + queue.length + ' events'), + JSON.stringify(message), + { + method: 'POST', + contentType: 'application/json', + withCredentials: true + } + ) + } +} + +function convertAdUnit(adUnit) { + if (!adUnit) return adUnit + + const shortAdUnit = {} + shortAdUnit.code = adUnit.code + shortAdUnit.sizes = adUnit.sizes + return shortAdUnit +} + +function convertBid(bid) { + if (!bid) return bid + + const shortBid = {} + shortBid.adUnitCode = bid.adUnitCode + shortBid.bidder = bid.bidder + shortBid.cpm = bid.cpm + shortBid.currency = bid.currency + shortBid.mediaTypes = bid.mediaTypes + shortBid.sizes = bid.sizes + shortBid.serverResponseTimeMs = bid.serverResponseTimeMs + return shortBid +} + +function convertAuctionInit(origEvent) { + let shortEvent = {} + shortEvent.auctionId = origEvent.auctionId + shortEvent.timeout = origEvent.timeout + shortEvent.adUnits = origEvent.adUnits && origEvent.adUnits.map(convertAdUnit) + return shortEvent +} + +function convertBidRequested(origEvent) { + let shortEvent = {} + shortEvent.bidderCode = origEvent.bidderCode + shortEvent.bids = origEvent.bids && origEvent.bids.map(convertBid) + shortEvent.timeout = origEvent.timeout + return shortEvent +} + +function convertBidTimeout(origEvent) { + let shortEvent = {} + shortEvent.bids = origEvent && origEvent.map ? origEvent.map(convertBid) : origEvent + return shortEvent +} + +function convertBidderError(origEvent) { + let shortEvent = {} + shortEvent.bids = origEvent.bidderRequest && origEvent.bidderRequest.bids && origEvent.bidderRequest.bids.map(convertBid) + return shortEvent +} + +function convertAuctionEnd(origEvent) { + let shortEvent = {} + shortEvent.adUnitCodes = origEvent.adUnitCodes + shortEvent.bidsReceived = origEvent.bidsReceived && origEvent.bidsReceived.map(convertBid) + shortEvent.noBids = origEvent.noBids && origEvent.noBids.map(convertBid) + return shortEvent +} + +function convertBidWon(origEvent) { + let shortEvent = {} + shortEvent.adUnitCode = origEvent.adUnitCode + shortEvent.bidderCode = origEvent.bidderCode + shortEvent.mediaType = origEvent.mediaType + shortEvent.netRevenue = origEvent.netRevenue + shortEvent.cpm = origEvent.cpm + shortEvent.size = origEvent.size + shortEvent.currency = origEvent.currency + return shortEvent +} + +function handleEvent(eventType, origEvent) { + try { + origEvent = origEvent ? JSON.parse(JSON.stringify(origEvent)) : {} + } catch (e) { + } + + let shortEvent + switch (eventType) { + case EVENTS.AUCTION_INIT: { + shortEvent = convertAuctionInit(origEvent) + break + } + case EVENTS.BID_REQUESTED: { + shortEvent = convertBidRequested(origEvent) + break + } + case EVENTS.BID_TIMEOUT: { + shortEvent = convertBidTimeout(origEvent) + break + } + case EVENTS.BIDDER_ERROR: { + shortEvent = convertBidderError(origEvent) + break + } + case EVENTS.AUCTION_END: { + shortEvent = convertAuctionEnd(origEvent) + break + } + case EVENTS.BID_WON: { + shortEvent = convertBidWon(origEvent) + break + } + default: + return + } + + shortEvent.eventType = eventType + shortEvent.auctionId = origEvent.auctionId + shortEvent.timestamp = origEvent.timestamp || Date.now() + + sendEvent(shortEvent) +} + +function sendEvent(event) { + queue.push(event) + + if (event.eventType === EVENTS.AUCTION_END) { + sendEvents() + } +} + +advRedAnalytics.originEnableAnalytics = advRedAnalytics.enableAnalytics +advRedAnalytics.enableAnalytics = function (config) { + initOptions = config.options || {} + pwId = generateUUID() + flushInterval = setInterval(sendEvents, 1000) + + advRedAnalytics.originEnableAnalytics(config) +} + +advRedAnalytics.originDisableAnalytics = advRedAnalytics.disableAnalytics +advRedAnalytics.disableAnalytics = function () { + clearInterval(flushInterval) + sendEvents() + advRedAnalytics.originDisableAnalytics() +} + +adapterManager.registerAnalyticsAdapter({ + adapter: advRedAnalytics, + code: 'advRed' +}) + +advRedAnalytics.getOptions = function () { + return initOptions +} + +advRedAnalytics.sendEvents = sendEvents + +export default advRedAnalytics diff --git a/modules/advRedAnalyticsAdapter.md b/modules/advRedAnalyticsAdapter.md new file mode 100644 index 00000000000..59345dfd01e --- /dev/null +++ b/modules/advRedAnalyticsAdapter.md @@ -0,0 +1,30 @@ +# Overview +``` +Module Name: AdvRed Analytics Adapter +Module Type: Analytics Adapter +Maintainer: support@adv.red +``` + +### Usage + +The AdvRed analytics adapter can be used by all clients after approval. For more information, +please visit + +### Analytics Options +| Param enableAnalytics | Scope | Type | Description | Example | +|-----------------------|----------|--------|------------------------------------------------------|----------------------------------------| +| provider | Required | String | The name of this Adapter. | `'advRed'` | +| params | Required | Object | Details of module params. | | +| params.publisherId | Required | String | This is the Publisher ID value obtained from AdvRed. | `'123456'` | +| params.url | Optional | String | Custom URL of the endpoint to collect the events | `'https://pub1.api.adv.red/api/event'` | + +### Example Configuration + +```javascript +pbjs.enableAnalytics({ + provider: 'advRed', + options: { + publisherId: '123456' // change to the Publisher ID you received from AdvRed + } +}); +``` diff --git a/modules/adxcgAnalyticsAdapter.js b/modules/adxcgAnalyticsAdapter.js index 7ad95121209..7538e2962cc 100644 --- a/modules/adxcgAnalyticsAdapter.js +++ b/modules/adxcgAnalyticsAdapter.js @@ -3,7 +3,6 @@ import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; -import {getGlobal} from '../src/prebidGlobal.js'; /** * Analytics adapter from adxcg.com @@ -123,7 +122,7 @@ function send (data) { ats: adxcgAnalyticsAdapter.context.auctionTimestamp, aav: adxcgAnalyticsVersion, iob: intersectionObserverAvailable(window) ? '1' : '0', - pbv: getGlobal().version, + pbv: '$prebid.version$', sz: window.screen.width + 'x' + window.screen.height } }); diff --git a/modules/aidemBidAdapter.js b/modules/aidemBidAdapter.js index 0730149e909..3b55682b217 100644 --- a/modules/aidemBidAdapter.js +++ b/modules/aidemBidAdapter.js @@ -1,4 +1,4 @@ -import {deepAccess, deepSetValue, isBoolean, isNumber, isStr, logError, logInfo} from '../src/utils.js'; +import {deepAccess, deepClone, deepSetValue, isBoolean, isNumber, isStr, logError, logInfo} from '../src/utils.js'; import {config} from '../src/config.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; @@ -132,7 +132,7 @@ function getRegs(bidderRequest) { } function setPrebidRequestEnvironment(payload) { - const __navigator = JSON.parse(JSON.stringify(recur(navigator))); + const __navigator = deepClone(recur(navigator)); delete __navigator.plugins; deepSetValue(payload, 'environment.ri', getRefererInfo()); deepSetValue(payload, 'environment.hl', window.history.length); diff --git a/modules/akamaiDapRtdProvider.js b/modules/akamaiDapRtdProvider.js index 0bd53b2a91f..e5a647a90ef 100644 --- a/modules/akamaiDapRtdProvider.js +++ b/modules/akamaiDapRtdProvider.js @@ -5,802 +5,23 @@ * @module modules/akamaiDapRtdProvider * @requires module:modules/realTimeData */ -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {submodule} from '../src/hook.js'; -import {isPlainObject, mergeDeep, logMessage, logInfo, logError} from '../src/utils.js'; -import { loadExternalScript } from '../src/adloader.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; -/** - * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule - */ - -const MODULE_NAME = 'realTimeData'; -const SUBMODULE_NAME = 'dap'; -const MODULE_CODE = 'akamaidap'; - -export const DAP_TOKEN = 'async_dap_token'; -export const DAP_MEMBERSHIP = 'async_dap_membership'; -export const DAP_ENCRYPTED_MEMBERSHIP = 'encrypted_dap_membership'; -export const DAP_SS_ID = 'dap_ss_id'; -export const DAP_DEFAULT_TOKEN_TTL = 3600; // in seconds -export const DAP_MAX_RETRY_TOKENIZE = 1; -export const DAP_CLIENT_ENTROPY = 'dap_client_entropy' - -export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME}); -let dapRetryTokenize = 0; - -/** - * Lazy merge objects. - * @param {String} target - * @param {String} source - */ -function mergeLazy(target, source) { - if (!isPlainObject(target)) { - target = {}; - } - if (!isPlainObject(source)) { - source = {}; - } - return mergeDeep(target, source); -} - -/** - * Add real-time data & merge segments. - * @param {Object} ortb2 destination object to merge RTD into - * @param {Object} rtd - */ -export function addRealTimeData(ortb2, rtd) { - logInfo('DEBUG(addRealTimeData) - ENTER'); - if (isPlainObject(rtd.ortb2)) { - logMessage('DEBUG(addRealTimeData): merging original: ', ortb2); - logMessage('DEBUG(addRealTimeData): merging in: ', rtd.ortb2); - mergeLazy(ortb2, rtd.ortb2); - } - logInfo('DEBUG(addRealTimeData) - EXIT'); -} - -/** - * Real-time data retrieval from Audigent - * @param {Object} bidConfig - * @param {function} onDone - * @param {Object} rtdConfig - * @param {Object} userConsent - */ -export function getRealTimeData(bidConfig, onDone, rtdConfig, userConsent) { - let entropyDict = JSON.parse(storage.getDataFromLocalStorage(DAP_CLIENT_ENTROPY)); - let loadScriptPromise = new Promise((resolve, reject) => { - if (rtdConfig && rtdConfig.params && rtdConfig.params.dapEntropyTimeout && Number.isInteger(rtdConfig.params.dapEntropyTimeout)) { - setTimeout(reject, rtdConfig.params.dapEntropyTimeout, Error('DapEntropy script could not be loaded')); - } - if (entropyDict && entropyDict.expires_at > Math.round(Date.now() / 1000.0)) { - logMessage('Using cached entropy'); - resolve(); - } else { - if (typeof window.dapCalculateEntropy === 'function') { - window.dapCalculateEntropy(resolve, reject); - } else { - if (rtdConfig && rtdConfig.params && dapUtils.isValidHttpsUrl(rtdConfig.params.dapEntropyUrl)) { - loadExternalScript(rtdConfig.params.dapEntropyUrl, MODULE_CODE, () => { dapUtils.dapGetEntropy(resolve, reject) }); - } else { - reject(Error('Please check if dapEntropyUrl is specified and is valid under config.params')); - } - } - } - }); - loadScriptPromise - .catch((error) => { - logError('Entropy could not be calculated due to: ', error.message); - }) - .finally(() => { - generateRealTimeData(bidConfig, onDone, rtdConfig, userConsent); - }); -} - -export function generateRealTimeData(bidConfig, onDone, rtdConfig, userConsent) { - logInfo('DEBUG(generateRealTimeData) - ENTER'); - logMessage(' - apiHostname: ' + rtdConfig.params.apiHostname); - logMessage(' - apiVersion: ' + rtdConfig.params.apiVersion); - dapRetryTokenize = 0; - var jsonData = null; - if (rtdConfig && isPlainObject(rtdConfig.params)) { - if (rtdConfig.params.segtax == 504) { - let encMembership = dapUtils.dapGetEncryptedMembershipFromLocalStorage(); - if (encMembership) { - jsonData = dapUtils.dapGetEncryptedRtdObj(encMembership, rtdConfig.params.segtax) - } - } else { - let membership = dapUtils.dapGetMembershipFromLocalStorage(); - if (membership) { - jsonData = dapUtils.dapGetRtdObj(membership, rtdConfig.params.segtax) - } - } - } - if (jsonData) { - if (jsonData.rtd) { - addRealTimeData(bidConfig.ortb2Fragments?.global, jsonData.rtd); - onDone(); - logInfo('DEBUG(generateRealTimeData) - 1'); - // Don't return - ensure the data is always fresh. - } - } - // Calling setTimeout to release the main thread so that the bid request could be sent. - setTimeout(dapUtils.callDapAPIs, 0, bidConfig, onDone, rtdConfig, userConsent); -} - -/** - * Module init - * @param {Object} provider - * @param {Object} userConsent - * @return {boolean} - */ -function init(provider, userConsent) { - if (dapUtils.checkConsent(userConsent) === false) { - return false; - } - return true; -} - -/** @type {RtdSubmodule} */ -export const akamaiDapRtdSubmodule = { - name: SUBMODULE_NAME, - getBidRequestData: getRealTimeData, - init: init -}; - -submodule(MODULE_NAME, akamaiDapRtdSubmodule); -export const dapUtils = { - - callDapAPIs: function(bidConfig, onDone, rtdConfig, userConsent) { - if (rtdConfig && isPlainObject(rtdConfig.params)) { - let config = { - api_hostname: rtdConfig.params.apiHostname, - api_version: rtdConfig.params.apiVersion, - domain: rtdConfig.params.domain, - segtax: rtdConfig.params.segtax, - identity: {type: rtdConfig.params.identityType} - }; - let refreshMembership = true; - let token = dapUtils.dapGetTokenFromLocalStorage(); - const ortb2 = bidConfig.ortb2Fragments.global; - logMessage('token is: ', token); - if (token !== null) { // If token is not null then check the membership in storage and add the RTD object - if (config.segtax == 504) { // Follow the encrypted membership path - dapUtils.dapRefreshEncryptedMembership(ortb2, config, token, onDone) // Get the encrypted membership from server - refreshMembership = false; - } else { - dapUtils.dapRefreshMembership(ortb2, config, token, onDone) // Get the membership from server - refreshMembership = false; - } - } - dapUtils.dapRefreshToken(ortb2, config, refreshMembership, onDone) // Refresh Token and membership in all the cases - } - }, - dapGetEntropy: function(resolve, reject) { - if (typeof window.dapCalculateEntropy === 'function') { - window.dapCalculateEntropy(resolve, reject); - } else { - reject(Error('window.dapCalculateEntropy function is not defined')) - } - }, - - dapGetTokenFromLocalStorage: function(ttl) { - let now = Math.round(Date.now() / 1000.0); // in seconds - let token = null; - let item = JSON.parse(storage.getDataFromLocalStorage(DAP_TOKEN)); - if (item) { - if (now < item.expires_at) { - token = item.token; - } - } - return token; - }, - - dapRefreshToken: function(ortb2, config, refreshMembership, onDone) { - dapUtils.dapLog('Token missing or expired, fetching a new one...'); - // Trigger a refresh - let now = Math.round(Date.now() / 1000.0); // in seconds - let item = {} - let configAsync = {...config}; - dapUtils.dapTokenize(configAsync, config.identity, onDone, - function(token, status, xhr, onDone) { - item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; - let exp = dapUtils.dapExtractExpiryFromToken(token); - if (typeof exp == 'number') { - item.expires_at = exp - 10; - } - item.token = token; - storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(item)); - dapUtils.dapLog('Successfully updated and stored token; expires at ' + item.expires_at); - let dapSSID = xhr.getResponseHeader('Akamai-DAP-SS-ID'); - if (dapSSID) { - storage.setDataInLocalStorage(DAP_SS_ID, JSON.stringify(dapSSID)); - } - let deviceId100 = xhr.getResponseHeader('Akamai-DAP-100'); - if (deviceId100 != null) { - storage.setDataInLocalStorage('dap_deviceId100', deviceId100); - dapUtils.dapLog('Successfully stored DAP 100 Device ID: ' + deviceId100); - } - if (refreshMembership) { - if (config.segtax == 504) { - dapUtils.dapRefreshEncryptedMembership(ortb2, config, token, onDone); - } else { - dapUtils.dapRefreshMembership(ortb2, config, token, onDone); - } - } - }, - function(xhr, status, error, onDone) { - logError('ERROR(' + error + '): failed to retrieve token! ' + status); - onDone() - } - ); - }, - - dapGetMembershipFromLocalStorage: function() { - let now = Math.round(Date.now() / 1000.0); // in seconds - let membership = null; - let item = JSON.parse(storage.getDataFromLocalStorage(DAP_MEMBERSHIP)); - if (item) { - if (now < item.expires_at) { - membership = { - said: item.said, - cohorts: item.cohorts, - attributes: null - }; - } - } - return membership; - }, - - dapRefreshMembership: function(ortb2, config, token, onDone) { - let now = Math.round(Date.now() / 1000.0); // in seconds - let item = {} - let configAsync = {...config}; - dapUtils.dapMembership(configAsync, token, onDone, - function(membership, status, xhr, onDone) { - item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; - let exp = dapUtils.dapExtractExpiryFromToken(membership.said) - if (typeof exp == 'number') { - item.expires_at = exp - 10; - } - item.said = membership.said; - item.cohorts = membership.cohorts; - storage.setDataInLocalStorage(DAP_MEMBERSHIP, JSON.stringify(item)); - dapUtils.dapLog('Successfully updated and stored membership:'); - dapUtils.dapLog(item); - - let data = dapUtils.dapGetRtdObj(item, config.segtax) - dapUtils.checkAndAddRealtimeData(ortb2, data, config.segtax); - onDone(); - }, - function(xhr, status, error, onDone) { - logError('ERROR(' + error + '): failed to retrieve membership! ' + status); - if (status == 403 && dapRetryTokenize < DAP_MAX_RETRY_TOKENIZE) { - dapRetryTokenize++; - dapUtils.dapRefreshToken(ortb2, config, true, onDone); - } else { - onDone(); - } - } - ); - }, - - dapGetEncryptedMembershipFromLocalStorage: function() { - let now = Math.round(Date.now() / 1000.0); // in seconds - let encMembership = null; - let item = JSON.parse(storage.getDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP)); - if (item) { - if (now < item.expires_at) { - encMembership = { - encryptedSegments: item.encryptedSegments - }; - } - } - return encMembership; - }, - - dapRefreshEncryptedMembership: function(ortb2, config, token, onDone) { - let now = Math.round(Date.now() / 1000.0); // in seconds - let item = {}; - let configAsync = {...config}; - dapUtils.dapEncryptedMembership(configAsync, token, onDone, - function(encToken, status, xhr, onDone) { - item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; - let exp = dapUtils.dapExtractExpiryFromToken(encToken); - if (typeof exp == 'number') { - item.expires_at = exp - 10; - } - item.encryptedSegments = encToken; - storage.setDataInLocalStorage(DAP_ENCRYPTED_MEMBERSHIP, JSON.stringify(item)); - dapUtils.dapLog('Successfully updated and stored encrypted membership:'); - dapUtils.dapLog(item); - - let encData = dapUtils.dapGetEncryptedRtdObj(item, config.segtax); - dapUtils.checkAndAddRealtimeData(ortb2, encData, config.segtax); - onDone(); - }, - function(xhr, status, error, onDone) { - logError('ERROR(' + error + '): failed to retrieve encrypted membership! ' + status); - if (status == 403 && dapRetryTokenize < DAP_MAX_RETRY_TOKENIZE) { - dapRetryTokenize++; - dapUtils.dapRefreshToken(ortb2, config, true, onDone); - } else { - onDone(); - } - } - ); - }, - - /** - * DESCRIPTION - * Extract expiry value from a token - */ - dapExtractExpiryFromToken: function(token) { - let exp = null; - if (token) { - const tokenArray = token.split('..'); - if (tokenArray && tokenArray.length > 0) { - let decode = atob(tokenArray[0]) - let header = JSON.parse(decode.replace(/"/g, '"')); - exp = header.exp; - } - } - return exp - }, - - /** - * DESCRIPTION - * - * Convert a DAP membership response to an OpenRTB2 segment object suitable - * for insertion into user.data.segment or site.data.segment and add it to the rtd obj. - */ - dapGetRtdObj: function(membership, segtax) { - let segment = { - name: 'dap.akamai.com', - ext: { - 'segtax': segtax - }, - segment: [] - }; - if (membership != null) { - for (const i of membership.cohorts) { - segment.segment.push({ id: i }); - } - } - let data = { - rtd: { - ortb2: { - user: { - data: [ - segment - ] - }, - site: { - ext: { - data: { - dapSAID: membership.said - } - } - } - } - } - }; - return data; - }, - - /** - * DESCRIPTION - * - * Convert a DAP membership response to an OpenRTB2 segment object suitable - * for insertion into user.data.segment or site.data.segment and add it to the rtd obj. - */ - dapGetEncryptedRtdObj: function(encToken, segtax) { - let segment = { - name: 'dap.akamai.com', - ext: { - 'segtax': segtax - }, - segment: [] - }; - if (encToken != null) { - segment.segment.push({ id: encToken.encryptedSegments }); - } - let encData = { - rtd: { - ortb2: { - user: { - data: [ - segment - ] - } - } - } - }; - return encData; - }, - - checkAndAddRealtimeData: function(ortb2, data, segtax) { - if (data.rtd) { - if (segtax == 504 && dapUtils.checkIfSegmentsAlreadyExist(ortb2, data.rtd, 504)) { - logMessage('DEBUG(handleInit): rtb Object already added'); - } else { - addRealTimeData(ortb2, data.rtd); - } - logInfo('DEBUG(checkAndAddRealtimeData) - 1'); - } - }, - - checkIfSegmentsAlreadyExist: function(ortb2, rtd, segtax) { - let segmentsExist = false - if (ortb2.user && ortb2.user.data && ortb2.user.data.length > 0) { - for (let i = 0; i < ortb2.user.data.length; i++) { - let element = ortb2.user.data[i] - if (element.ext && element.ext.segtax == segtax) { - segmentsExist = true - logMessage('DEBUG(checkIfSegmentsAlreadyExist): rtb Object already added: ', ortb2.user.data); - break; - } - } - } - return segmentsExist - }, - - dapLog: function(args) { - let css = ''; - css += 'display: inline-block;'; - css += 'color: #fff;'; - css += 'background: #F28B20;'; - css += 'padding: 1px 4px;'; - css += 'border-radius: 3px'; - - logInfo('%cDAP Client', css, args); - }, - - isValidHttpsUrl: function(urlString) { - let url; - try { - url = new URL(urlString); - } catch (_) { - return false; - } - return url.protocol === 'https:'; - }, - - checkConsent: function(userConsent) { - let consent = true; - - if (userConsent && userConsent.gdpr && userConsent.gdpr.gdprApplies) { - const gdpr = userConsent.gdpr; - const hasGdpr = (gdpr && typeof gdpr.gdprApplies === 'boolean' && gdpr.gdprApplies) ? 1 : 0; - const gdprConsentString = hasGdpr ? gdpr.consentString : ''; - if (hasGdpr && (!gdprConsentString || gdprConsentString === '')) { - logError('akamaiDapRtd submodule requires consent string to call API'); - consent = false; - } - } else if (userConsent && userConsent.usp) { - const usp = userConsent.usp; - consent = usp[1] !== 'N' && usp[2] !== 'Y'; - } - - return consent; - }, - - /******************************************************************************* - * - * V2 (And Beyond) API - * - ******************************************************************************/ - - /** - * SYNOPSIS - * - * dapTokenize( config, identity ); - * - * DESCRIPTION - * - * Tokenize an identity into a secure, privacy safe pseudonymiziation. - * - * PARAMETERS - * - * config: an array of system configuration parameters - * - * identity: an array of identity parameters passed to the tokenizing system - * - * EXAMPLE - * - * config = { - * api_hostname: "prebid.dap.akadns.net", // required - * domain: "prebid.org", // required - * api_version: "x1", // optional, default "x1" - * }; - * - * token = null; - * identity_email = { - * type: "email", - * identity: "obiwan@jedi.com" - * attributes: { cohorts: [ "100:1641013200", "101:1641013200", "102":3:1641013200" ] }, - * }; - * dap_x1_tokenize( config, identity_email, - * function( response, status, xhr ) { token = response; }, - * function( xhr, status, error ) { ; } // handle error - * - * token = null; - * identity_signature = { type: "signature:1.0.0" }; - * dap_x1_tokenize( config, identity_signature, - * function( response, status, xhr } { token = response; }, - * function( xhr, status, error ) { ; } // handle error - */ - dapTokenize: function(config, identity, onDone, onSuccess = null, onError = null) { - if (onError == null) { - onError = function(xhr, status, error, onDone) {}; - } - - if (config == null || typeof (config) == typeof (undefined)) { - onError(null, 'Invalid config object', 'ClientError', onDone); - return; - } - - if (typeof (config.domain) != 'string') { - onError(null, 'Invalid config.domain: must be a string', 'ClientError', onDone); - return; - } - - if (config.domain.length <= 0) { - onError(null, 'Invalid config.domain: must have non-zero length', 'ClientError', onDone); - return; - } - - if (!('api_version' in config) || (typeof (config.api_version) == 'string' && config.api_version.length == 0)) { - config.api_version = 'x1'; - } - - if (typeof (config.api_version) != 'string') { - onError(null, "Invalid api_version: must be a string like 'x1', etc.", 'ClientError', onDone); - return; - } - - if (!(('api_hostname') in config) || typeof (config.api_hostname) != 'string' || config.api_hostname.length == 0) { - onError(null, 'Invalid api_hostname: must be a non-empty string', 'ClientError', onDone); - return; - } - - if (identity == null || typeof (identity) == typeof (undefined)) { - onError(null, 'Invalid identity object', 'ClientError', onDone); - return; - } - - if (!('type' in identity) || typeof (identity.type) != 'string' || identity.type.length <= 0) { - onError(null, "Identity must contain a valid 'type' field", 'ClientError', onDone); - return; - } - - let apiParams = { - 'type': identity.type, - }; - - if (typeof (identity.identity) != typeof (undefined)) { - apiParams.identity = identity.identity; - } - if (typeof (identity.attributes) != typeof (undefined)) { - apiParams.attributes = identity.attributes; - } - - let entropyDict = JSON.parse(storage.getDataFromLocalStorage(DAP_CLIENT_ENTROPY)); - if (entropyDict && entropyDict.entropy) { - apiParams.entropy = entropyDict.entropy; - } - - let method; - let body; - let path; - switch (config.api_version) { - case 'x1': - case 'x1-dev': - method = 'POST'; - path = '/data-activation/' + config.api_version + '/domain/' + config.domain + '/identity/tokenize'; - body = JSON.stringify(apiParams); - break; - default: - onError(null, 'Invalid api_version: ' + config.api_version, 'ClientError', onDone); - return; - } - - let customHeaders = {'Content-Type': 'application/json'}; - let dapSSID = JSON.parse(storage.getDataFromLocalStorage(DAP_SS_ID)); - if (dapSSID) { - customHeaders['Akamai-DAP-SS-ID'] = dapSSID; - } - - let url = 'https://' + config.api_hostname + path; - let cb = { - success: (response, request) => { - let token = null; - switch (config.api_version) { - case 'x1': - case 'x1-dev': - token = request.getResponseHeader('Akamai-DAP-Token'); - break; - } - onSuccess(token, request.status, request, onDone); - }, - error: (request, error) => { - onError(request, request.statusText, error, onDone); - } - }; - - ajax(url, cb, body, { - method: method, - customHeaders: customHeaders - }); - }, - - /** - * SYNOPSIS - * - * dapMembership( config, token, onSuccess, onError ); - * - * DESCRIPTION - * - * Return the audience segment membership along with a new Secure Advertising - * ID for this token. - * - * PARAMETERS - * - * config: an array of system configuration parameters - * - * token: the token previously returned from the tokenize API - * - * EXAMPLE - * - * config = { - * api_hostname: 'api.dap.akadns.net', - * }; - * - * // token from dap_tokenize - * - * dapMembership( config, token, - * function( membership, status, xhr ) { - * // Run auction with membership.segments and membership.said - * }, - * function( xhr, status, error ) { - * // error - * } ); - * - */ - dapMembership: function(config, token, onDone, onSuccess = null, onError = null) { - if (onError == null) { - onError = function(xhr, status, error, onDone) {}; - } - - if (config == null || typeof (config) == typeof (undefined)) { - onError(null, 'Invalid config object', 'ClientError', onDone); - return; - } - - if (!('api_version' in config) || (typeof (config.api_version) == 'string' && config.api_version.length == 0)) { - config.api_version = 'x1'; - } - - if (typeof (config.api_version) != 'string') { - onError(null, "Invalid api_version: must be a string like 'x1', etc.", 'ClientError', onDone); - return; - } - - if (!(('api_hostname') in config) || typeof (config.api_hostname) != 'string' || config.api_hostname.length == 0) { - onError(null, 'Invalid api_hostname: must be a non-empty string', 'ClientError', onDone); - return; - } - - if (token == null || typeof (token) != 'string') { - onError(null, 'Invalid token: must be a non-null string', 'ClientError', onDone); - return; - } - let path = '/data-activation/' + - config.api_version + - '/token/' + token + - '/membership'; - - let url = 'https://' + config.api_hostname + path; - - let cb = { - success: (response, request) => { - onSuccess(JSON.parse(response), request.status, request, onDone); - }, - error: (error, request) => { - onError(request, request.status, error, onDone); - } - }; - - ajax(url, cb, undefined, { - method: 'GET', - customHeaders: {} - }); - }, - - /** - * SYNOPSIS - * - * dapEncryptedMembership( config, token, onSuccess, onError ); - * - * DESCRIPTION - * - * Return the audience segment membership along with a new Secure Advertising - * ID for this token in encrypted format. - * - * PARAMETERS - * - * config: an array of system configuration parameters - * - * token: the token previously returned from the tokenize API - * - * EXAMPLE - * - * config = { - * api_hostname: 'api.dap.akadns.net', - * }; - * - * // token from dap_tokenize - * - * dapEncryptedMembership( config, token, - * function( membership, status, xhr ) { - * // Run auction with membership.segments and membership.said after decryption - * }, - * function( xhr, status, error ) { - * // error - * } ); - * - */ - dapEncryptedMembership: function(config, token, onDone, onSuccess = null, onError = null) { - if (onError == null) { - onError = function(xhr, status, error, onDone) {}; - } - - if (config == null || typeof (config) == typeof (undefined)) { - onError(null, 'Invalid config object', 'ClientError', onDone); - return; - } - - if (!('api_version' in config) || (typeof (config.api_version) == 'string' && config.api_version.length == 0)) { - config.api_version = 'x1'; - } - - if (typeof (config.api_version) != 'string') { - onError(null, "Invalid api_version: must be a string like 'x1', etc.", 'ClientError', onDone); - return; - } - - if (!(('api_hostname') in config) || typeof (config.api_hostname) != 'string' || config.api_hostname.length == 0) { - onError(null, 'Invalid api_hostname: must be a non-empty string', 'ClientError', onDone); - return; - } - - if (token == null || typeof (token) != 'string') { - onError(null, 'Invalid token: must be a non-null string', 'ClientError', onDone); - return; - } - let path = '/data-activation/' + - config.api_version + - '/token/' + token + - '/membership/encrypt'; - - let url = 'https://' + config.api_hostname + path; - - let cb = { - success: (response, request) => { - let encToken = request.getResponseHeader('Akamai-DAP-Token'); - onSuccess(encToken, request.status, request, onDone); - }, - error: (error, request) => { - onError(request, request.status, error, onDone); - } - }; - ajax(url, cb, undefined, { - method: 'GET', - customHeaders: { - 'Content-Type': 'application/json', - 'Pragma': 'akamai-x-get-extracted-values' - } - }); - } -} +import { + createRtdProvider +} from './symitriDapRtdProvider.js'/* eslint prebid/validate-imports: "off" */ + +export const { + addRealTimeData, + getRealTimeData, + generateRealTimeData, + rtdSubmodule: akamaiDapRtdSubmodule, + storage, + dapUtils, + DAP_TOKEN, + DAP_MEMBERSHIP, + DAP_ENCRYPTED_MEMBERSHIP, + DAP_SS_ID, + DAP_DEFAULT_TOKEN_TTL, + DAP_MAX_RETRY_TOKENIZE, + DAP_CLIENT_ENTROPY +} = createRtdProvider('dap', 'akamaidap', 'Akamai'); diff --git a/modules/amxBidAdapter.js b/modules/amxBidAdapter.js index 6e14f65b0c8..df260958104 100644 --- a/modules/amxBidAdapter.js +++ b/modules/amxBidAdapter.js @@ -454,6 +454,10 @@ export const spec = { setUIDSafe(response.am); } + const bidderSettings = config.getConfig('bidderSettings'); + const settings = bidderSettings?.amx ?? bidderSettings?.standard ?? {}; + const allowAlternateBidderCodes = !!settings.allowAlternateBidderCodes; + return flatMap(Object.keys(response.r), (bidID) => { return flatMap(response.r[bidID], (siteBid) => siteBid.b.map((bid) => { @@ -466,8 +470,10 @@ export const spec = { const size = resolveSize(bid, request.data, bidID); const defaultExpiration = mediaType === BANNER ? 240 : 300; + const { bc: bidderCode, ds: demandSource } = bid.ext ?? {}; return { + ...(bidderCode != null && allowAlternateBidderCodes ? { bidderCode } : {}), requestId: bidID, cpm: bid.price, width: size[0], @@ -479,6 +485,7 @@ export const spec = { meta: { advertiserDomains: bid.adomain, mediaType, + ...(demandSource != null ? { demandSource } : {}), }, mediaType, ttl: typeof bid.exp === 'number' ? bid.exp : defaultExpiration, diff --git a/modules/anPspParamsConverter.js b/modules/anPspParamsConverter.js new file mode 100644 index 00000000000..27b90168476 --- /dev/null +++ b/modules/anPspParamsConverter.js @@ -0,0 +1,128 @@ +/* +- register a hook function on the makeBidRequests hook (after the main function ran) + +- this hook function will: +1. verify s2sconfig is defined and we (or our aliases) are included to the config +2. filter bidRequests that match to our bidderName or any registered aliases +3. for each request, read the bidderRequests.bids[].params to modify the keys/values + a. in particular change the keywords structure, apply underscore casing for keys, adjust use_payment_rule name, and convert certain values' types + b. will import some functions from the anKeywords library, but ideally should be kept separate to avoid including this code when it's not needed (strict client-side setups) and avoid the rest of the appnexus adapter's need for inclusion for those strictly server-side setups. +*/ + +// import { CONSTANTS } from '../src/cons tants.js'; +import {isArray, isPlainObject, isStr} from '../src/utils.js'; +import {getHook} from '../src/hook.js'; +import {config} from '../src/config.js'; +import {convertCamelToUnderscore, appnexusAliases} from '../libraries/appnexusUtils/anUtils.js'; +import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; +import adapterManager from '../src/adapterManager.js'; + +// keywords: { 'genre': ['rock', 'pop'], 'pets': ['dog'] } goes to 'genre=rock,genre=pop,pets=dog' +function convertKeywordsToString(keywords) { + let result = ''; + Object.keys(keywords).forEach(key => { + // if 'text' or '' + if (isStr(keywords[key])) { + if (keywords[key] !== '') { + result += `${key}=${keywords[key]},` + } else { + result += `${key},`; + } + } else if (isArray(keywords[key])) { + if (keywords[key][0] === '') { + result += `${key},` + } else { + keywords[key].forEach(val => { + result += `${key}=${val},` + }); + } + } + }); + + // remove last trailing comma + result = result.substring(0, result.length - 1); + return result; +} + +function digForAppNexusBidder(s2sConfig) { + let result = false; + // check for plain setup + if (s2sConfig?.bidders?.includes('appnexus')) result = true; + + // registered aliases + const aliasList = appnexusAliases.map(aliasObj => (aliasObj.code)); + if (!result && s2sConfig?.bidders?.filter(s2sBidder => aliasList.includes(s2sBidder)).length > 0) result = true; + + // pbjs.aliasBidder + if (!result) { + result = !!(s2sConfig?.bidders?.find(bidder => (adapterManager.resolveAlias(bidder) === 'appnexus'))); + } + + return result; +} + +// need a separate check b/c we're checking a specific bidRequest to see if we modify it, not just that we have a server-side bidder somewhere in prebid.js +// function isThisOurBidderInDisguise(tarBidder, s2sConfig) { +// if (tarBidder === 'appnexus') return true; + +// if (isPlainObject(s2sConfig?.extPrebid?.aliases) && !!(Object.entries(s2sConfig?.extPrebid?.aliases).find((pair) => (pair[0] === tarBidder && pair[1] === 'appnexus')))) return true; + +// if (appnexusAliases.map(aliasObj => (aliasObj.code)).includes(tarBidder)) return true; + +// if (adapterManager.resolveAlias(tarBidder) === 'appnexus') return true; + +// return false; +// } + +export function convertAnParams(next, bidderRequests) { + // check s2sconfig + const s2sConfig = config.getConfig('s2sConfig'); + let proceed = false; + + if (isPlainObject(s2sConfig)) { + proceed = digForAppNexusBidder(s2sConfig); + } else if (isArray(s2sConfig)) { + s2sConfig.forEach(s2sCfg => { + proceed = digForAppNexusBidder(s2sCfg); + }); + } + + if (proceed) { + bidderRequests + .flatMap(br => br.bids) + .filter(bid => bid.src === 's2s' && adapterManager.resolveAlias(bid.bidder) === 'appnexus') + .forEach((bid) => { + transformBidParams(bid); + }); + } + + next(bidderRequests); +} + +function transformBidParams(bid) { + let params = bid.params; + if (params) { + params = convertTypes({ + 'member': 'string', + 'invCode': 'string', + 'placementId': 'number', + 'keywords': convertKeywordsToString, + 'publisherId': 'number' + }, params); + + Object.keys(params).forEach(paramKey => { + let convertedKey = convertCamelToUnderscore(paramKey); + if (convertedKey !== paramKey) { + params[convertedKey] = params[paramKey]; + delete params[paramKey]; + } + }); + + params.use_pmt_rule = (typeof params.use_payment_rule === 'boolean') ? params.use_payment_rule : false; + if (params.use_payment_rule) { + delete params.use_payment_rule; + } + } +} + +getHook('makeBidRequests').after(convertAnParams, 9); diff --git a/modules/anPspParamsConverter.md b/modules/anPspParamsConverter.md new file mode 100644 index 00000000000..f341b0a5976 --- /dev/null +++ b/modules/anPspParamsConverter.md @@ -0,0 +1,10 @@ +## Quick Summary + +This module is a temporary measure for publishers running Prebid.js 9.0+ and using the AppNexus PSP endpoint through their Prebid.js setup. Please ensure to include this module in your builds of Prebid.js 9.0+, otherwise requests to PSP may not complete successfully. + +## Module's purpose + +This module replicates certain functionality that was previously stored in the appnexusBidAdapter.js file within a function named transformBidParams. + +This transformBidParams was a standard function in all adapters, which helped to change/modify the params and their values to a format that matched the bidder's request structure on the server-side endpoint. In Prebid.js 9.0, this standard function was removed in all adapter files, so that the whole client-side file (eg appnexusBidAdapter.js) wouldn't have to be included in a prebid.js build file that was meant for server-side bidders. + diff --git a/modules/anonymisedRtdProvider.js b/modules/anonymisedRtdProvider.js index 48ac649f002..c3bb21ce8a5 100644 --- a/modules/anonymisedRtdProvider.js +++ b/modules/anonymisedRtdProvider.js @@ -9,10 +9,13 @@ import {getStorageManager} from '../src/storageManager.js'; import {submodule} from '../src/hook.js'; import {isPlainObject, mergeDeep, logMessage, logError} from '../src/utils.js'; import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; - +/** + * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule + */ export function createRtdProvider(moduleName) { const MODULE_NAME = 'realTimeData'; const SUBMODULE_NAME = moduleName; + const GVLID = 1116; const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME }); /** @@ -106,6 +109,7 @@ export function createRtdProvider(moduleName) { /** @type {RtdSubmodule} */ const rtdSubmodule = { name: SUBMODULE_NAME, + gvlid: GVLID, getBidRequestData: getRealTimeData, init: init }; diff --git a/modules/anonymisedRtdProvider.md b/modules/anonymisedRtdProvider.md index 2ff2597690b..936e5fc7437 100644 --- a/modules/anonymisedRtdProvider.md +++ b/modules/anonymisedRtdProvider.md @@ -8,7 +8,7 @@ Anonymised’s Real-time Data Provider automatically obtains segment IDs from th - Build the anonymisedRtd module into the Prebid.js package with: ```bash - gulp build --modules=anonymisedRtdProvider,... + gulp build --modules=rtdModule,anonymisedRtdProvider,... ``` - Use `setConfig` to instruct Prebid.js to initilaize the anonymisedRtdProvider module, as specified below. diff --git a/modules/apacdexBidAdapter.js b/modules/apacdexBidAdapter.js index dadbdb72e95..83119052f3a 100644 --- a/modules/apacdexBidAdapter.js +++ b/modules/apacdexBidAdapter.js @@ -1,7 +1,7 @@ -import { deepAccess, isPlainObject, isArray, replaceAuctionPrice, isFn, logError } from '../src/utils.js'; +import { deepAccess, isPlainObject, isArray, replaceAuctionPrice, isFn, logError, deepClone } from '../src/utils.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {parseDomain} from '../src/refererDetection.js'; const BIDDER_CODE = 'apacdex'; const ENDPOINT = 'https://useast.quantumdex.io/auction/pbjs' @@ -85,7 +85,7 @@ export const spec = { bidReq.bidFloor = bidFloor; } - bids.push(JSON.parse(JSON.stringify(bidReq))); + bids.push(deepClone(bidReq)); }); const payload = {}; diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index b0c91a14a46..62b62d20216 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -15,7 +15,8 @@ import { logError, logInfo, logMessage, - logWarn + logWarn, + mergeDeep } from '../src/utils.js'; import {Renderer} from '../src/Renderer.js'; import {config} from '../src/config.js'; @@ -25,16 +26,15 @@ import {find, includes} from '../src/polyfill.js'; import {INSTREAM, OUTSTREAM} from '../src/video.js'; import {getStorageManager} from '../src/storageManager.js'; import {bidderSettings} from '../src/bidderSettings.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; import {APPNEXUS_CATEGORY_MAPPING} from '../libraries/categoryTranslationMapping/index.js'; import { convertKeywordStringToANMap, getANKewyordParamFromMaps, - getANKeywordParam, - transformBidderParamKeywords + getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; -import {convertCamelToUnderscore, fill} from '../libraries/appnexusUtils/anUtils.js'; +import {convertCamelToUnderscore, fill, appnexusAliases} from '../libraries/appnexusUtils/anUtils.js'; import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; import {chunk} from '../libraries/chunk/chunk.js'; @@ -104,25 +104,33 @@ const VIEWABILITY_URL_START = /\/\/cdn\.adnxs\.com\/v|\/\/cdn\.adnxs\-simple\.co const VIEWABILITY_FILE_NAME = 'trk.js'; const GVLID = 32; const storage = getStorageManager({bidderCode: BIDDER_CODE}); +// ORTB2 device types according to the OpenRTB specification +const ORTB2_DEVICE_TYPE = { + MOBILE_TABLET: 1, + PERSONAL_COMPUTER: 2, + CONNECTED_TV: 3, + PHONE: 4, + TABLET: 5, + CONNECTED_DEVICE: 6, + SET_TOP_BOX: 7, + OOH_DEVICE: 8 +}; +// Map of ORTB2 device types to AppNexus device types +const ORTB2_DEVICE_TYPE_MAP = new Map([ + [ORTB2_DEVICE_TYPE.MOBILE_TABLET, 'Mobile/Tablet - General'], + [ORTB2_DEVICE_TYPE.PERSONAL_COMPUTER, 'Personal Computer'], + [ORTB2_DEVICE_TYPE.CONNECTED_TV, 'Connected TV'], + [ORTB2_DEVICE_TYPE.PHONE, 'Phone'], + [ORTB2_DEVICE_TYPE.TABLET, 'Tablet'], + [ORTB2_DEVICE_TYPE.CONNECTED_DEVICE, 'Connected Device'], + [ORTB2_DEVICE_TYPE.SET_TOP_BOX, 'Set Top Box'], + [ORTB2_DEVICE_TYPE.OOH_DEVICE, 'OOH Device'], +]); export const spec = { code: BIDDER_CODE, gvlid: GVLID, - aliases: [ - { code: 'appnexusAst', gvlid: 32 }, - { code: 'emxdigital', gvlid: 183 }, - { code: 'emetriq', gvlid: 213 }, - { code: 'pagescience', gvlid: 32 }, - { code: 'gourmetads', gvlid: 32 }, - { code: 'matomy', gvlid: 32 }, - { code: 'featureforward', gvlid: 32 }, - { code: 'oftmedia', gvlid: 32 }, - { code: 'adasta', gvlid: 32 }, - { code: 'beintoo', gvlid: 618 }, - { code: 'projectagora', gvlid: 1032 }, - { code: 'uol', gvlid: 32 }, - { code: 'adzymic', gvlid: 723 }, - ], + aliases: appnexusAliases, supportedMediaTypes: [BANNER, VIDEO, NATIVE], /** @@ -262,6 +270,12 @@ export const spec = { payload.app = appIdObj; } + // if present, convert and merge device object from ortb2 into `payload.device` + if (bidderRequest?.ortb2?.device) { + payload.device = payload.device || {}; + mergeDeep(payload.device, convertORTB2DeviceDataToAppNexusDeviceObject(bidderRequest.ortb2.device)); + } + // grab the ortb2 keyword data (if it exists) and convert from the comma list string format to object format let ortb2 = deepClone(bidderRequest && bidderRequest.ortb2); @@ -449,51 +463,6 @@ export const spec = { url: 'https://acdn.adnxs.com/dmp/async_usersync.html' }]; } - }, - - transformBidParams: function (params, isOpenRtb, adUnit, bidRequests) { - let conversionFn = transformBidderParamKeywords; - if (isOpenRtb === true) { - let s2sEndpointUrl = null; - let s2sConfig = config.getConfig('s2sConfig'); - - if (isPlainObject(s2sConfig)) { - s2sEndpointUrl = deepAccess(s2sConfig, 'endpoint.p1Consent'); - } else if (isArray(s2sConfig)) { - s2sConfig.forEach(s2sCfg => { - if (includes(s2sCfg.bidders, adUnit.bids[0].bidder)) { - s2sEndpointUrl = deepAccess(s2sCfg, 'endpoint.p1Consent'); - } - }); - } - - if (s2sEndpointUrl && s2sEndpointUrl.match('/openrtb2/prebid')) { - conversionFn = convertKeywordsToString; - } - } - - params = convertTypes({ - 'member': 'string', - 'invCode': 'string', - 'placementId': 'number', - 'keywords': conversionFn, - 'publisherId': 'number' - }, params); - - if (isOpenRtb) { - Object.keys(params).forEach(paramKey => { - let convertedKey = convertCamelToUnderscore(paramKey); - if (convertedKey !== paramKey) { - params[convertedKey] = params[paramKey]; - delete params[paramKey]; - } - }); - - params.use_pmt_rule = (typeof params.use_payment_rule === 'boolean') ? params.use_payment_rule : false; - if (params.use_payment_rule) { delete params.use_payment_rule; } - } - - return params; } }; @@ -1256,31 +1225,29 @@ function getBidFloor(bid) { return null; } -// keywords: { 'genre': ['rock', 'pop'], 'pets': ['dog'] } goes to 'genre=rock,genre=pop,pets=dog' -function convertKeywordsToString(keywords) { - let result = ''; - Object.keys(keywords).forEach(key => { - // if 'text' or '' - if (isStr(keywords[key])) { - if (keywords[key] !== '') { - result += `${key}=${keywords[key]},` - } else { - result += `${key},`; - } - } else if (isArray(keywords[key])) { - if (keywords[key][0] === '') { - result += `${key},` - } else { - keywords[key].forEach(val => { - result += `${key}=${val},` - }); - } - } - }); +// Convert device data to a format that AppNexus expects +function convertORTB2DeviceDataToAppNexusDeviceObject(ortb2DeviceData) { + const _device = { + useragent: ortb2DeviceData.ua, + devicetype: ORTB2_DEVICE_TYPE_MAP.get(ortb2DeviceData.devicetype), + make: ortb2DeviceData.make, + model: ortb2DeviceData.model, + os: ortb2DeviceData.os, + os_version: ortb2DeviceData.osv, + w: ortb2DeviceData.w, + h: ortb2DeviceData.h, + ppi: ortb2DeviceData.ppi, + pxratio: ortb2DeviceData.pxratio, + }; - // remove last trailing comma - result = result.substring(0, result.length - 1); - return result; + // filter out any empty values and return the object + return Object.keys(_device) + .reduce((r, key) => { + if (_device[key]) { + r[key] = _device[key]; + } + return r; + }, {}); } registerBidder(spec); diff --git a/modules/appushBidAdapter.js b/modules/appushBidAdapter.js index 97772b65e45..67557aed10c 100644 --- a/modules/appushBidAdapter.js +++ b/modules/appushBidAdapter.js @@ -57,6 +57,7 @@ function getPlacementReqData(bid) { placement.protocols = mediaTypes[VIDEO].protocols; placement.startdelay = mediaTypes[VIDEO].startdelay; placement.placement = mediaTypes[VIDEO].placement; + placement.plcmt = mediaTypes[VIDEO].plcmt; placement.skip = mediaTypes[VIDEO].skip; placement.skipafter = mediaTypes[VIDEO].skipafter; placement.minbitrate = mediaTypes[VIDEO].minbitrate; diff --git a/modules/apstreamBidAdapter.js b/modules/apstreamBidAdapter.js index 2856fb02087..37e2bde44c1 100644 --- a/modules/apstreamBidAdapter.js +++ b/modules/apstreamBidAdapter.js @@ -292,7 +292,6 @@ function getConsentStringFromPrebid(gdprConsentConfig) { return null; } - let isIab = config.getConfig('consentManagement.cmpApi') != 'static'; let vendorConsents = ( gdprConsentConfig.vendorData.vendorConsents || (gdprConsentConfig.vendorData.vendor || {}).consents || @@ -300,7 +299,7 @@ function getConsentStringFromPrebid(gdprConsentConfig) { ); let isConsentGiven = !!vendorConsents[CONSTANTS.GVLID.toString(10)]; - return isIab && isConsentGiven ? consentString : null; + return isConsentGiven ? consentString : null; } function getIabConsentString(bidderRequest) { diff --git a/modules/asteriobidAnalyticsAdapter.js b/modules/asteriobidAnalyticsAdapter.js index d5b6c0b4cf7..615293e2641 100644 --- a/modules/asteriobidAnalyticsAdapter.js +++ b/modules/asteriobidAnalyticsAdapter.js @@ -1,4 +1,4 @@ -import { generateUUID, getParameterByName, logError, logInfo, parseUrl } from '../src/utils.js' +import { generateUUID, getParameterByName, logError, logInfo, parseUrl, deepClone, hasNonSerializableProperty } from '../src/utils.js' import { ajaxBuilder } from '../src/ajax.js' import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js' import adapterManager from '../src/adapterManager.js' @@ -192,10 +192,10 @@ function handleEvent(eventType, eventArgs) { return } - try { - eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {} - } catch (e) { - // keep eventArgs as is + if (eventArgs) { + eventArgs = hasNonSerializableProperty(eventArgs) ? eventArgs : deepClone(eventArgs) + } else { + eventArgs = {} } const pmEvent = {} diff --git a/modules/automatadAnalyticsAdapter.js b/modules/automatadAnalyticsAdapter.js index 523e8d558ca..7ed109ab705 100644 --- a/modules/automatadAnalyticsAdapter.js +++ b/modules/automatadAnalyticsAdapter.js @@ -18,6 +18,8 @@ var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null const prettyLog = (level, text, isGroup = false, cb = () => {}) => { if (self.isLoggingEnabled === undefined) { + // TODO FIX THIS RULES VIOLATION + // eslint-disable-next-line prebid/no-global if (window.localStorage.getItem('__aggLoggingEnabled')) { self.isLoggingEnabled = true } else { diff --git a/modules/axisBidAdapter.js b/modules/axisBidAdapter.js index 8d7f2dd04fd..c2ad40b2b94 100644 --- a/modules/axisBidAdapter.js +++ b/modules/axisBidAdapter.js @@ -1,189 +1,53 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - +import { deepAccess } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; +import { + isBidRequestValid, + buildRequestsBase, + interpretResponse, + buildPlacementProcessingFunction, +} from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'axis'; const AD_URL = 'https://prebid.axis-marketplace.com/pbjs'; const SYNC_URL = 'https://cs.axis-marketplace.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { integration, token } = params; - const bidfloor = getBidFloor(bid); +const addPlacementType = (bid, bidderRequest, placement) => { + placement.integration = bid.params.integration; + placement.token = bid.params.token; +}; - const placement = { - integration, - token, - bidId, - schain, - bidfloor - }; +const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => { + const { mediaTypes } = bid; - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; + if (placement.adFormat === BANNER) { placement.pos = mediaTypes[BANNER].pos; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; + } else if (placement.adFormat === VIDEO) { placement.pos = mediaTypes[VIDEO].pos; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; placement.context = mediaTypes[VIDEO].context; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; } +}; - return placement; -} +const placementProcessingFunction = buildPlacementProcessingFunction({ addPlacementType, addCustomFieldsToPlacement }); -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + const request = buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction }); - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (e) { - logError(e); - return 0; - } -} + request.data.iabCat = deepAccess(bidderRequest, 'ortb2.site.cat'); + + return request; +}; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && params.integration && params.token); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); + isBidRequestValid: isBidRequestValid(['integration', 'token'], 'every'), + buildRequests, + interpretResponse, - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - iabCat: deepAccess(bidderRequest, 'ortb2.site.cat'), - coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout || 3000, - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { + getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => { let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; if (gdprConsent && gdprConsent.consentString) { @@ -197,6 +61,11 @@ export const spec = { syncUrl += `&ccpa=${uspConsent.consentString}`; } + if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { + syncUrl += '&gpp=' + gppConsent.gppString; + syncUrl += '&gpp_sid=' + gppConsent.applicableSections.join(','); + } + const coppa = config.getConfig('coppa') ? 1 : 0; syncUrl += `&coppa=${coppa}`; @@ -205,6 +74,6 @@ export const spec = { url: syncUrl }]; } -}; +} registerBidder(spec); diff --git a/modules/azerionedgeRtdProvider.js b/modules/azerionedgeRtdProvider.js index a162ce074aa..852639972c2 100644 --- a/modules/azerionedgeRtdProvider.js +++ b/modules/azerionedgeRtdProvider.js @@ -19,6 +19,8 @@ const REAL_TIME_MODULE = 'realTimeData'; const SUBREAL_TIME_MODULE = 'azerionedge'; export const STORAGE_KEY = 'ht-pa-v1-a'; +const IMPROVEDIGITAL_GVLID = '253'; + export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBREAL_TIME_MODULE, @@ -42,14 +44,21 @@ function getScriptURL(config) { * Attach script tag to DOM * * @param {Object} config + * @param {Object} userConsent * * @return {void} */ -export function attachScript(config) { +export function attachScript(config, userConsent) { const script = getScriptURL(config); loadExternalScript(script, SUBREAL_TIME_MODULE, () => { if (typeof window.azerionPublisherAudiences === 'function') { - window.azerionPublisherAudiences(config.params?.process || {}); + const publisherConfig = config.params?.process || {}; + window.azerionPublisherAudiences({ + ...publisherConfig, + gdprApplies: userConsent?.gdpr?.gdprApplies, + gdprConsent: userConsent?.gdpr?.consentString, + uspConsent: userConsent?.usp, + }); } }); } @@ -106,7 +115,7 @@ export function setAudiencesToBidders(reqBidsConfigObj, config, audiences) { * @return {boolean} */ function init(config, userConsent) { - attachScript(config); + attachScript(config, userConsent); return true; } @@ -138,6 +147,7 @@ export const azerionedgeSubmodule = { name: SUBREAL_TIME_MODULE, init: init, getBidRequestData: getBidRequestData, + gvlid: IMPROVEDIGITAL_GVLID, }; submodule(REAL_TIME_MODULE, azerionedgeSubmodule); diff --git a/modules/azerionedgeRtdProvider.md b/modules/azerionedgeRtdProvider.md index 6658907c480..e1bdf792647 100644 --- a/modules/azerionedgeRtdProvider.md +++ b/modules/azerionedgeRtdProvider.md @@ -79,23 +79,6 @@ provided to the module when the user gives the relevant permissions on the publi As Prebid.js utilizes TCF vendor consent for the RTD module to load, the module needs to be labeled within the Vendor Exceptions. -### Instructions - -If the Prebid GDPR enforcement is enabled, the module should be labeled -as exception, as shown below: - -```js -[ - { - purpose: 'storage', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: ["azerionedge"] - }, - ... -] -``` - ## Testing To view an example: diff --git a/modules/beyondmediaBidAdapter.js b/modules/beyondmediaBidAdapter.js index bbcd972470c..077717c36f4 100644 --- a/modules/beyondmediaBidAdapter.js +++ b/modules/beyondmediaBidAdapter.js @@ -1,202 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'beyondmedia'; const AD_URL = 'https://backend.andbeyond.media/pbjs'; const SYNC_URL = 'https://cookies.andbeyond.media'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - placement.placementId = placementId; - placement.type = 'publisher'; - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && params.placementId); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } - - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/bidwatchAnalyticsAdapter.js b/modules/bidwatchAnalyticsAdapter.js index ffbd125eeab..e385b02fe5f 100644 --- a/modules/bidwatchAnalyticsAdapter.js +++ b/modules/bidwatchAnalyticsAdapter.js @@ -3,6 +3,7 @@ import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; import { ajax } from '../src/ajax.js'; import { getRefererInfo } from '../src/refererDetection.js'; +import { deepClone } from '../src/utils.js'; const analyticsType = 'endpoint'; const url = 'URL_TO_SERVER_ENDPOINT'; @@ -113,7 +114,7 @@ function addTimeout(args) { let stringArgs = JSON.parse(dereferenceWithoutRenderer(args)); argsDereferenced = stringArgs; argsDereferenced.forEach((attr) => { - argsCleaned.push(filterAttributes(JSON.parse(JSON.stringify(attr)), false)); + argsCleaned.push(filterAttributes(deepClone(attr), false)); }); if (auctionEnd[eventType] == undefined) { auctionEnd[eventType] = [] } auctionEnd[eventType].push(argsCleaned); diff --git a/modules/bizzclickBidAdapter.js b/modules/blastoBidAdapter.js similarity index 90% rename from modules/bizzclickBidAdapter.js rename to modules/blastoBidAdapter.js index d2eba3f0f81..0e97c294049 100644 --- a/modules/bizzclickBidAdapter.js +++ b/modules/blastoBidAdapter.js @@ -3,11 +3,11 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -const BIDDER_CODE = 'bizzclick'; +const BIDDER_CODE = 'blasto'; const SOURCE_ID_MACRO = '[sourceid]'; const ACCOUNT_ID_MACRO = '[accountid]'; const HOST_MACRO = '[host]'; -const URL = `https://${HOST_MACRO}.bizzclick.com/bid?rtb_seat_id=${SOURCE_ID_MACRO}&secret_key=${ACCOUNT_ID_MACRO}&integration_type=prebidjs`; +const URL = `https://${HOST_MACRO}.blasto.ai/bid?rtb_seat_id=${SOURCE_ID_MACRO}&secret_key=${ACCOUNT_ID_MACRO}&integration_type=prebidjs`; const DEFAULT_CURRENCY = 'USD'; const DEFAULT_HOST = 'us-e-node1'; @@ -53,7 +53,7 @@ export const spec = { buildRequests: (validBidRequests, bidderRequest) => { if (validBidRequests && validBidRequests.length === 0) return []; const { sourceId, accountId } = validBidRequests[0].params; - const host = validBidRequests[0].params.host || 'USE'; + const host = validBidRequests[0].params.host; const endpointURL = URL.replace(HOST_MACRO, host || DEFAULT_HOST) .replace(ACCOUNT_ID_MACRO, accountId) .replace(SOURCE_ID_MACRO, sourceId); diff --git a/modules/bizzclickBidAdapter.md b/modules/blastoBidAdapter.md similarity index 88% rename from modules/bizzclickBidAdapter.md rename to modules/blastoBidAdapter.md index ad342f34e07..60ebad14764 100644 --- a/modules/bizzclickBidAdapter.md +++ b/modules/blastoBidAdapter.md @@ -1,14 +1,14 @@ # Overview ``` -Module Name: BizzClick SSP Bidder Adapter +Module Name: Blasto SSP Bidder Adapter Module Type: Bidder Adapter -Maintainer: support@bizzclick.com +Maintainer: support@blasto.ai ``` # Description -Module that connects to BizzClick SSP demand sources +Module that connects to Blasto SSP demand sources # Test Parameters @@ -26,7 +26,7 @@ const adUnits = [ }, bids: [ { - bidder: "bizzclick", + bidder: "blasto", params: { placementId: "hash", accountId: "accountId", @@ -68,7 +68,7 @@ const adUnits = [ }, bids: [ { - bidder: "bizzclick", + bidder: "blasto", params: { placementId: "hash", accountId: "accountId", @@ -96,7 +96,7 @@ const adUnits = [ }, bids: [ { - bidder: "bizzclick", + bidder: "blasto", params: { placementId: "hash", accountId: "accountId", diff --git a/modules/bliinkBidAdapter.js b/modules/bliinkBidAdapter.js index 37c99878d68..b66923fd476 100644 --- a/modules/bliinkBidAdapter.js +++ b/modules/bliinkBidAdapter.js @@ -1,8 +1,6 @@ -// eslint-disable-next-line prebid/validate-imports -// eslint-disable-next-line prebid/validate-imports import { registerBidder } from '../src/adapters/bidderFactory.js' import { config } from '../src/config.js' -import { _each, deepAccess, deepSetValue, getWindowSelf, getWindowTop } from '../src/utils.js' +import { _each, canAccessWindowTop, deepAccess, deepSetValue, getDomLoadingDuration, getWindowSelf, getWindowTop } from '../src/utils.js' export const BIDDER_CODE = 'bliink' export const GVL_ID = 658 export const BLIINK_ENDPOINT_ENGINE = 'https://engine.bliink.io/prebid' @@ -123,35 +121,6 @@ export function getKeywords() { return []; } -function canAccessTopWindow() { - try { - if (getWindowTop().location.href) { - return true; - } - } catch (error) { - return false; - } -} - -/** - * domLoading feature is computed on window.top if reachable. - */ -export function getDomLoadingDuration() { - let domLoadingDuration = -1; - let performance; - - performance = (canAccessTopWindow()) ? getWindowTop().performance : getWindowSelf().performance; - - if (performance && performance.timing && performance.timing.navigationStart > 0) { - const val = performance.timing.domLoading - performance.timing.navigationStart; - if (val > 0) { - domLoadingDuration = val; - } - } - - return domLoadingDuration; -} - /** * @param bidResponse * @return {({cpm, netRevenue: boolean, requestId, width: number, currency, ttl: number, creativeId, height: number}&{mediaType: string, vastXml})|null} @@ -210,7 +179,8 @@ export const isBidRequestValid = (bid) => { */ export const buildRequests = (validBidRequests, bidderRequest) => { if (!validBidRequests || !bidderRequest || !bidderRequest.bids) return null - const domLoadingDuration = getDomLoadingDuration().toString(); + const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf(); + const domLoadingDuration = getDomLoadingDuration(w).toString(); const tags = bidderRequest.bids.map((bid) => { let bidFloor; const sizes = bid.sizes.map((size) => ({ w: size[0], h: size[1] })); diff --git a/modules/bluebillywigBidAdapter.js b/modules/bluebillywigBidAdapter.js deleted file mode 100644 index 0718f512cdd..00000000000 --- a/modules/bluebillywigBidAdapter.js +++ /dev/null @@ -1,374 +0,0 @@ -import {deepAccess, deepClone, deepSetValue, logError, logWarn} from '../src/utils.js'; -import {find} from '../src/polyfill.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {Renderer} from '../src/Renderer.js'; - -const DEV_MODE = window.location.search.match(/bbpbs_debug=true/); - -// Blue Billywig Constants -const BB_CONSTANTS = { - BIDDER_CODE: 'bluebillywig', - AUCTION_URL: '$$URL_STARTpbs.bluebillywig.com/openrtb2/auction?pub=$$PUBLICATION', - SYNC_URL: '$$URL_STARTpbs.bluebillywig.com/static/cookie-sync.html?pub=$$PUBLICATION', - RENDERER_URL: 'https://$$PUBLICATION.bbvms.com/r/$$RENDERER.js', - DEFAULT_TIMEOUT: 5000, - DEFAULT_TTL: 300, - DEFAULT_WIDTH: 768, - DEFAULT_HEIGHT: 432, - DEFAULT_NET_REVENUE: true, - VIDEO_PARAMS: ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', - 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', - 'api', 'companiontype', 'ext'] -}; - -// Aliasing -const getConfig = config.getConfig; - -// Helper Functions -const BB_HELPERS = { - addSiteAppDevice: function(request, pageUrl) { - if (typeof getConfig('app') === 'object') request.app = getConfig('app'); - else { - request.site = {}; - if (typeof getConfig('site') === 'object') request.site = getConfig('site'); - if (pageUrl) request.site.page = pageUrl; - } - - if (typeof getConfig('device') === 'object') request.device = getConfig('device'); - if (!request.device) request.device = {}; - if (!request.device.w) request.device.w = window.innerWidth; - if (!request.device.h) request.device.h = window.innerHeight; - }, - addSchain: function(request, validBidRequests) { - const schain = deepAccess(validBidRequests, '0.schain'); - if (schain) request.source.ext = { schain: schain }; - }, - addCurrency: function(request) { - const adServerCur = getConfig('currency.adServerCurrency'); - if (adServerCur && typeof adServerCur === 'string') request.cur = [adServerCur]; - else if (Array.isArray(adServerCur) && adServerCur.length) request.cur = [adServerCur[0]]; - }, - addUserIds: function(request, validBidRequests) { - const eids = deepAccess(validBidRequests, '0.userIdAsEids'); - - if (eids != null && eids.length) { - deepSetValue(request, 'user.ext.eids', eids); - } - }, - substituteUrl: function (url, publication, renderer) { - return url.replace('$$URL_START', (DEV_MODE) ? 'https://dev.' : 'https://').replace('$$PUBLICATION', publication).replace('$$RENDERER', renderer); - }, - getAuctionUrl: function(publication) { - return BB_HELPERS.substituteUrl(BB_CONSTANTS.AUCTION_URL, publication); - }, - getSyncUrl: function(publication) { - return BB_HELPERS.substituteUrl(BB_CONSTANTS.SYNC_URL, publication); - }, - getRendererUrl: function(publication, renderer) { - return BB_HELPERS.substituteUrl(BB_CONSTANTS.RENDERER_URL, publication, renderer); - }, - transformVideoParams: function(videoParams, videoParamsExt) { - videoParams = deepClone(videoParams); - - let playerSize = videoParams.playerSize || [BB_CONSTANTS.DEFAULT_WIDTH, BB_CONSTANTS.DEFAULT_HEIGHT]; - if (Array.isArray(playerSize[0])) playerSize = playerSize[0]; - - videoParams.w = playerSize[0]; - videoParams.h = playerSize[1]; - videoParams.placement = 3; - - if (videoParamsExt) videoParams = Object.assign(videoParams, videoParamsExt); - - const videoParamsProperties = Object.keys(videoParams); - - videoParamsProperties.forEach(property => { - if (BB_CONSTANTS.VIDEO_PARAMS.indexOf(property) === -1) delete videoParams[property]; - }); - - return videoParams; - }, - transformRTBToPrebidProps: function(bid, serverResponse) { - const bidObject = { - cpm: bid.price, - currency: serverResponse.cur, - netRevenue: BB_CONSTANTS.DEFAULT_NET_REVENUE, - bidId: bid.impid, - requestId: bid.impid, - creativeId: bid.crid, - mediaType: VIDEO, - width: bid.w || BB_CONSTANTS.DEFAULT_WIDTH, - height: bid.h || BB_CONSTANTS.DEFAULT_HEIGHT, - ttl: BB_CONSTANTS.DEFAULT_TTL - }; - - const extPrebidTargeting = deepAccess(bid, 'ext.prebid.targeting'); - const extPrebidCache = deepAccess(bid, 'ext.prebid.cache'); - - if (extPrebidCache && typeof extPrebidCache.vastXml === 'object' && extPrebidCache.vastXml.cacheId && extPrebidCache.vastXml.url) { - bidObject.videoCacheKey = extPrebidCache.vastXml.cacheId; - bidObject.vastUrl = extPrebidCache.vastXml.url; - } else if (extPrebidTargeting && extPrebidTargeting.hb_uuid && extPrebidTargeting.hb_cache_host && extPrebidTargeting.hb_cache_path) { - bidObject.videoCacheKey = extPrebidTargeting.hb_uuid; - bidObject.vastUrl = `https://${extPrebidTargeting.hb_cache_host}${extPrebidTargeting.hb_cache_path}?uuid=${extPrebidTargeting.hb_uuid}`; - } - if (bid.adm) { - bidObject.ad = bid.adm; - bidObject.vastXml = bid.adm; - } - if (!bidObject.vastUrl && bid.nurl && !bid.adm) { // ad markup is on win notice url, and adm is ommited according to OpenRTB 2.5 - bidObject.vastUrl = bid.nurl; - } - bidObject.meta = bid.meta || {}; - if (bid.adomain) { bidObject.meta.advertiserDomains = bid.adomain; } - return bidObject; - }, -}; - -// Renderer Functions -const BB_RENDERER = { - bootstrapPlayer: function(bid) { - const config = { - code: bid.adUnitCode, - }; - - if (bid.vastXml) config.vastXml = bid.vastXml; - else if (bid.vastUrl) config.vastUrl = bid.vastUrl; - - if (!bid.vastXml && !bid.vastUrl) { - logWarn(`${BB_CONSTANTS.BIDDER_CODE}: No vastXml or vastUrl on bid, bailing...`); - return; - } - - if (!(window.bluebillywig && window.bluebillywig.renderers)) { - logWarn(`${BB_CONSTANTS.BIDDER_CODE}: renderer code failed to initialize...`); - return; - } - - const rendererId = BB_RENDERER.getRendererId(bid.publicationName, bid.rendererCode); - const ele = document.getElementById(bid.adUnitCode); // NB convention - const renderer = find(window.bluebillywig.renderers, r => r._id === rendererId); - - if (renderer) renderer.bootstrap(config, ele, bid.rendererSettings || {}); - else logWarn(`${BB_CONSTANTS.BIDDER_CODE}: Couldn't find a renderer with ${rendererId}`); - }, - newRenderer: function(rendererUrl, adUnitCode) { - const renderer = Renderer.install({ - url: rendererUrl, - loaded: false, - adUnitCode - }); - - try { - renderer.setRender(BB_RENDERER.outstreamRender); - } catch (err) { - logWarn(`${BB_CONSTANTS.BIDDER_CODE}: Error tying to setRender on renderer`, err); - } - - return renderer; - }, - outstreamRender: function(bid) { - bid.renderer.push(function() { BB_RENDERER.bootstrapPlayer(bid) }); - }, - getRendererId: function(pub, renderer) { - return `${pub}-${renderer}`; // NB convention! - } -}; - -// Spec Functions -// These functions are used to construct the core spec for the adapter -export const spec = { - code: BB_CONSTANTS.BIDDER_CODE, - supportedMediaTypes: [VIDEO], - syncStore: { bidders: [], }, - isBidRequestValid(bid) { - const publicationNameRegex = /^\w+\.?\w+$/; - const rendererRegex = /^[\w+_]+$/; - - if (!bid.params) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: no params set on bid. Rejecting bid: `, bid); - return false; - } - - if (!bid.params.hasOwnProperty('publicationName') || typeof bid.params.publicationName !== 'string') { - logError(`${BB_CONSTANTS.BIDDER_CODE}: no publicationName specified in bid params, or it's not a string. Rejecting bid: `, bid); - return false; - } else if (!publicationNameRegex.test(bid.params.publicationName)) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: publicationName must be in format 'publication' or 'publication.environment'. Rejecting bid: `, bid); - return false; - } - - if ((!bid.params.hasOwnProperty('rendererCode') || typeof bid.params.rendererCode !== 'string')) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: no rendererCode was specified in bid params. Rejecting bid: `, bid); - return false; - } else if (!rendererRegex.test(bid.params.rendererCode)) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: rendererCode must be alphanumeric, including underscores. Rejecting bid: `, bid); - return false; - } - - if (!bid.params.accountId) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: no accountId specified in bid params. Rejecting bid: `, bid); - return false; - } - - if (bid.params.hasOwnProperty('connections')) { - if (!Array.isArray(bid.params.connections)) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: connections is not of type array. Rejecting bid: `, bid); - return false; - } else { - for (let i = 0; i < bid.params.connections.length; i++) { - if (!bid.params.hasOwnProperty(bid.params.connections[i])) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: connection specified in params.connections, but not configured in params. Rejecting bid: `, bid); - return false; - } - } - } - } else { - logError(`${BB_CONSTANTS.BIDDER_CODE}: no connections specified in bid. Rejecting bid: `, bid); - return false; - } - - if (bid.params.hasOwnProperty('video') && (bid.params.video === null || typeof bid.params.video !== 'object')) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: params.video must be of type object. Rejecting bid: `, bid); - return false; - } - - if (bid.params.hasOwnProperty('rendererSettings') && (bid.params.rendererSettings === null || typeof bid.params.rendererSettings !== 'object')) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: params.rendererSettings must be of type object. Rejecting bid: `, bid); - return false; - } - - if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { - if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) { - logError(`${BB_CONSTANTS.BIDDER_CODE}: no context specified in bid. Rejecting bid: `, bid); - return false; - } - - if (bid.mediaTypes[VIDEO].context !== 'outstream') { - logError(`${BB_CONSTANTS.BIDDER_CODE}: video.context is invalid, must be "outstream". Rejecting bid: `, bid); - return false; - } - } else { - logError(`${BB_CONSTANTS.BIDDER_CODE}: mediaTypes or mediaTypes.video is not specified. Rejecting bid: `, bid); - return false; - } - - return true; - }, - buildRequests(validBidRequests, bidderRequest) { - const imps = []; - - validBidRequests.forEach(validBidRequest => { - if (!this.syncStore.publicationName) this.syncStore.publicationName = validBidRequest.params.publicationName; - if (!this.syncStore.accountId) this.syncStore.accountId = validBidRequest.params.accountId; - - const ext = validBidRequest.params.connections.reduce((extBuilder, connection) => { - extBuilder[connection] = validBidRequest.params[connection]; - - if (this.syncStore.bidders.indexOf(connection) === -1) this.syncStore.bidders.push(connection); - - return extBuilder; - }, {}); - - const videoParams = BB_HELPERS.transformVideoParams(deepAccess(validBidRequest, 'mediaTypes.video'), deepAccess(validBidRequest, 'params.video')); - imps.push({ id: validBidRequest.bidId, ext, secure: window.location.protocol === 'https' ? 1 : 0, video: videoParams }); - }); - - const request = { - id: bidderRequest.bidderRequestId, - source: {tid: bidderRequest.ortb2?.source?.tid}, - tmax: Math.min(BB_CONSTANTS.DEFAULT_TIMEOUT, bidderRequest.timeout), - imp: imps, - test: DEV_MODE ? 1 : 0, - ext: { - prebid: { - targeting: { includewinners: true, includebidderkeys: false } - } - } - }; - - // handle privacy settings for GDPR/CCPA/COPPA - if (bidderRequest.gdprConsent) { - let gdprApplies = 0; - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - deepSetValue(request, 'regs.ext.gdpr', gdprApplies); - deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - if (bidderRequest.uspConsent) { - deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent); - this.syncStore.uspConsent = bidderRequest.uspConsent; - } - - if (getConfig('coppa') == true) deepSetValue(request, 'regs.coppa', 1); - - // Enrich the request with any external data we may have - BB_HELPERS.addSiteAppDevice(request, bidderRequest.refererInfo && bidderRequest.refererInfo.page); - BB_HELPERS.addSchain(request, validBidRequests); - BB_HELPERS.addCurrency(request); - BB_HELPERS.addUserIds(request, validBidRequests); - - return { - method: 'POST', - url: BB_HELPERS.getAuctionUrl(validBidRequests[0].params.publicationName), - data: JSON.stringify(request), - bidderRequest: bidderRequest - }; - }, - interpretResponse(serverResponse, request) { - serverResponse = serverResponse.body || {}; - - if (!serverResponse.hasOwnProperty('seatbid') || !Array.isArray(serverResponse.seatbid)) { - return []; - } - - const bids = []; - - serverResponse.seatbid.forEach(seatbid => { - if (!seatbid.bid || !Array.isArray(seatbid.bid)) return; - seatbid.bid.forEach(bid => { - bid = BB_HELPERS.transformRTBToPrebidProps(bid, serverResponse); - - const bidParams = find(request.bidderRequest.bids, bidderRequestBid => bidderRequestBid.bidId === bid.bidId).params; - bid.publicationName = bidParams.publicationName; - bid.rendererCode = bidParams.rendererCode; - bid.accountId = bidParams.accountId; - bid.rendererSettings = bidParams.rendererSettings; - - const rendererUrl = BB_HELPERS.getRendererUrl(bid.publicationName, bid.rendererCode); - bid.renderer = BB_RENDERER.newRenderer(rendererUrl, bid.adUnitCode); - - bids.push(bid); - }); - }); - - return bids; - }, - getUserSyncs(syncOptions, serverResponses, gdpr) { - if (!syncOptions.iframeEnabled) return []; - - const queryString = []; - - if (gdpr.gdprApplies) queryString.push(`gdpr=${gdpr.gdprApplies ? 1 : 0}`); - if (gdpr.gdprApplies && gdpr.consentString) queryString.push(`gdpr_consent=${gdpr.consentString}`); - - if (this.syncStore.uspConsent) queryString.push(`usp_consent=${this.syncStore.uspConsent}`); - - queryString.push(`accountId=${this.syncStore.accountId}`); - queryString.push(`bidders=${btoa(JSON.stringify(this.syncStore.bidders))}`); - queryString.push(`cb=${Date.now()}-${Math.random().toString().replace('.', '')}`); - - if (DEV_MODE) queryString.push('bbpbs_debug=true'); - - // NB syncUrl by default starts with ?pub=$$PUBLICATION - const syncUrl = `${BB_HELPERS.getSyncUrl(this.syncStore.publicationName)}&${queryString.join('&')}`; - - return [{ - type: 'iframe', - url: syncUrl - }]; - } -}; - -registerBidder(spec); diff --git a/modules/bluebillywigBidAdapter.md b/modules/bluebillywigBidAdapter.md deleted file mode 100644 index 7879697baf5..00000000000 --- a/modules/bluebillywigBidAdapter.md +++ /dev/null @@ -1,38 +0,0 @@ -# Overview - -``` -Module Name: Blue Billywig Adapter -Module Type: Bidder Adapter -Maintainer: dev+prebid@bluebillywig.com -``` - -# Description - -Prebid Blue Billywig Bidder Adapter - -# Test Parameters - -``` - const adUnits = [{ - code: 'ad-unit', - sizes: [[[768,432],[640,480],[640,360]]], - mediaTypes: { - video: { - playerSize: [768, 432], - context: 'outstream', - mimes: ['video/mp4'], - protocols: [ 2,3,5,6] - } - }, - bids: [{ - bidder: 'bluebillywig', - params: { - publicationName: "bbprebid", - rendererCode: "renderer", - accountId: 642, - connections: [ 'bluebillywig' ], - bluebillywig: {} - } - }] - }]; -``` diff --git a/modules/boldwinBidAdapter.js b/modules/boldwinBidAdapter.js index c7def383b5e..1cf3bf889b7 100644 --- a/modules/boldwinBidAdapter.js +++ b/modules/boldwinBidAdapter.js @@ -1,175 +1,38 @@ -import { isFn, deepAccess, logMessage } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { + isBidRequestValid, + buildRequestsBase, + interpretResponse, + getUserSyncs, + buildPlacementProcessingFunction, +} from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'boldwin'; const AD_URL = 'https://ssp.videowalldirect.com/pbjs'; const SYNC_URL = 'https://sync.videowalldirect.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; +const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => { + if (placement.adFormat === VIDEO) { + placement.wPlayer = placement.playerSize?.[0]?.[0]; + placement.hPlayer = placement.playerSize?.[0]?.[1]; } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} +}; -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } +const placementProcessingFunction = buildPlacementProcessingFunction({ addCustomFieldsToPlacement }); - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + return buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction }); +}; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && (bid.params.placementId || bid.params.endpointId)); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let winTop = window; - let location; - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page); - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent; - } - - // Add GPP consent - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - let bid = validBidRequests[i]; - const { mediaTypes, params } = bid; - const placement = {}; - let sizes; - if (mediaTypes) { - if (mediaTypes[BANNER] && mediaTypes[BANNER].sizes) { - placement.adFormat = BANNER; - sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize) { - placement.adFormat = VIDEO; - sizes = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else { - placement.adFormat = NATIVE; - placement.native = mediaTypes[NATIVE]; - } - } - - const { placementId, endpointId } = params; - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - placements.push({ - ...placement, - bidId: bid.bidId, - sizes: sizes || [], - wPlayer: sizes ? sizes[0] : 0, - hPlayer: sizes ? sizes[1] : 0, - schain: bid.schain || {}, - bidFloor: getBidFloor(bid), - }); - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: () => { - return [{ - type: 'image', - url: SYNC_URL - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests, + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/bridBidAdapter.js b/modules/bridBidAdapter.js index f3fe1541886..527cb9d5d5d 100644 --- a/modules/bridBidAdapter.js +++ b/modules/bridBidAdapter.js @@ -1,7 +1,7 @@ -import {createTrackPixelHtml, _each, deepAccess, getDefinedParams, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js'; +import {_each, deepAccess, getDefinedParams, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js'; import {VIDEO} from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import {getAd, getSiteObj} from '../libraries/targetVideoUtils/bidderUtils.js' /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -180,50 +180,50 @@ export const spec = { } -/** - * Helper function to get ad - * - * @param {object} bid The bid. - * @return {object} ad object. - */ -function getAd(bid) { - let ad, adUrl, vastXml, vastUrl; - - switch (deepAccess(bid, 'ext.prebid.type')) { - case VIDEO: - if (bid.adm.substr(0, 4) === 'http') { - vastUrl = bid.adm; - } else { - vastXml = bid.adm; - }; - break; - default: - if (bid.adm && bid.nurl) { - ad = bid.adm; - ad += createTrackPixelHtml(decodeURIComponent(bid.nurl)); - } else if (bid.adm) { - ad = bid.adm; - } else if (bid.nurl) { - adUrl = bid.nurl; - }; - } - - return {ad, adUrl, vastXml, vastUrl}; -} - -/** - * Helper function to get site object - * - * @return {object} siteObj. - */ -function getSiteObj() { - const refInfo = (getRefererInfo && getRefererInfo()) || {}; - - return { - page: refInfo.page, - ref: refInfo.ref, - domain: refInfo.domain - }; -} +// /** +// * Helper function to get ad +// * +// * @param {object} bid The bid. +// * @return {object} ad object. +// */ +// function getAd(bid) { +// let ad, adUrl, vastXml, vastUrl; + +// switch (deepAccess(bid, 'ext.prebid.type')) { +// case VIDEO: +// if (bid.adm.substr(0, 4) === 'http') { +// vastUrl = bid.adm; +// } else { +// vastXml = bid.adm; +// }; +// break; +// default: +// if (bid.adm && bid.nurl) { +// ad = bid.adm; +// ad += createTrackPixelHtml(decodeURIComponent(bid.nurl)); +// } else if (bid.adm) { +// ad = bid.adm; +// } else if (bid.nurl) { +// adUrl = bid.nurl; +// }; +// } + +// return {ad, adUrl, vastXml, vastUrl}; +// } + +// /** +// * Helper function to get site object +// * +// * @return {object} siteObj. +// */ +// function getSiteObj() { +// const refInfo = (getRefererInfo && getRefererInfo()) || {}; + +// return { +// page: refInfo.page, +// ref: refInfo.ref, +// domain: refInfo.domain +// }; +// } registerBidder(spec); diff --git a/modules/brightcomBidAdapter.js b/modules/brightcomBidAdapter.js deleted file mode 100644 index 1fa1dac4e95..00000000000 --- a/modules/brightcomBidAdapter.js +++ /dev/null @@ -1,303 +0,0 @@ -import { - _each, - isArray, - getWindowTop, - getUniqueIdentifierStr, - deepSetValue, - logError, - logWarn, - createTrackPixelHtml, - getWindowSelf, - isFn, - isPlainObject, - getBidIdParameter -} from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'brightcom'; -const URL = 'https://brightcombid.marphezis.com/hb'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - gvlid: 883, - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs -}; - -function buildRequests(bidReqs, bidderRequest) { - try { - let referrer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.page; - } - const brightcomImps = []; - const publisherId = getBidIdParameter('publisherId', bidReqs[0].params); - _each(bidReqs, function (bid) { - let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; - bidSizes = ((isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes]); - bidSizes = bidSizes.filter(size => isArray(size)); - const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})); - - const element = document.getElementById(bid.adUnitCode); - const minSize = _getMinSize(processedSizes); - const viewabilityAmount = _isViewabilityMeasurable(element) - ? _getViewability(element, getWindowTop(), minSize) - : 'na'; - const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); - - const imp = { - id: bid.bidId, - banner: { - format: processedSizes, - ext: { - viewability: viewabilityAmountRounded - } - }, - tagid: String(bid.adUnitCode) - }; - const bidFloor = _getBidFloor(bid); - if (bidFloor) { - imp.bidfloor = bidFloor; - } - brightcomImps.push(imp); - }); - const brightcomBidReq = { - id: getUniqueIdentifierStr(), - imp: brightcomImps, - site: { - domain: bidderRequest?.refererInfo?.domain || '', - page: referrer, - publisher: { - id: publisherId - } - }, - device: { - devicetype: _getDeviceType(), - w: screen.width, - h: screen.height - }, - tmax: bidderRequest?.timeout - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - deepSetValue(brightcomBidReq, 'regs.ext.gdpr', +bidderRequest.gdprConsent.gdprApplies); - deepSetValue(brightcomBidReq, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - if (bidderRequest && bidderRequest.uspConsent) { - deepSetValue(brightcomBidReq, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (config.getConfig('coppa') === true) { - deepSetValue(brightcomBidReq, 'regs.coppa', 1); - } - - if (bidReqs[0] && bidReqs[0].schain) { - deepSetValue(brightcomBidReq, 'source.ext.schain', bidReqs[0].schain) - } - - if (bidReqs[0] && bidReqs[0].userIdAsEids) { - deepSetValue(brightcomBidReq, 'user.ext.eids', bidReqs[0].userIdAsEids || []) - } - - if (bidReqs[0] && bidReqs[0].userId) { - deepSetValue(brightcomBidReq, 'user.ext.ids', bidReqs[0].userId || []) - } - - return { - method: 'POST', - url: URL, - data: JSON.stringify(brightcomBidReq), - }; - } catch (e) { - logError(e, {bidReqs, bidderRequest}); - } -} - -function isBidRequestValid(bid) { - if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { - return false; - } - - if (typeof bid.params.publisherId === 'undefined') { - return false; - } - - return true; -} - -function interpretResponse(serverResponse) { - if (!serverResponse.body || typeof serverResponse.body != 'object') { - logWarn('Brightcom server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); - return []; - } - const {body: {id, seatbid}} = serverResponse; - try { - const brightcomBidResponses = []; - if (id && - seatbid && - seatbid.length > 0 && - seatbid[0].bid && - seatbid[0].bid.length > 0) { - seatbid[0].bid.map(brightcomBid => { - brightcomBidResponses.push({ - requestId: brightcomBid.impid, - cpm: parseFloat(brightcomBid.price), - width: parseInt(brightcomBid.w), - height: parseInt(brightcomBid.h), - creativeId: brightcomBid.crid || brightcomBid.id, - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: _getAdMarkup(brightcomBid), - ttl: 60, - meta: { - advertiserDomains: brightcomBid && brightcomBid.adomain ? brightcomBid.adomain : [] - } - }); - }); - } - return brightcomBidResponses; - } catch (e) { - logError(e, {id, seatbid}); - } -} - -// Don't do user sync for now -function getUserSyncs(syncOptions, responses, gdprConsent) { - return []; -} - -function _isMobile() { - return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); -} - -function _isConnectedTV() { - return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); -} - -function _getDeviceType() { - return _isMobile() ? 1 : _isConnectedTV() ? 3 : 2; -} - -function _getAdMarkup(bid) { - let adm = bid.adm; - if ('nurl' in bid) { - adm += createTrackPixelHtml(bid.nurl); - } - return adm; -} - -function _isViewabilityMeasurable(element) { - return !_isIframe() && element !== null; -} - -function _getViewability(element, topWin, {w, h} = {}) { - return getWindowTop().document.visibilityState === 'visible' - ? _getPercentInView(element, topWin, {w, h}) - : 0; -} - -function _isIframe() { - try { - return getWindowSelf() !== getWindowTop(); - } catch (e) { - return true; - } -} - -function _getMinSize(sizes) { - return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); -} - -function _getBoundingBox(element, {w, h} = {}) { - let {width, height, left, top, right, bottom} = element.getBoundingClientRect(); - - if ((width === 0 || height === 0) && w && h) { - width = w; - height = h; - right = left + w; - bottom = top + h; - } - - return {width, height, left, top, right, bottom}; -} - -function _getIntersectionOfRects(rects) { - const bbox = { - left: rects[0].left, - right: rects[0].right, - top: rects[0].top, - bottom: rects[0].bottom - }; - - for (let i = 1; i < rects.length; ++i) { - bbox.left = Math.max(bbox.left, rects[i].left); - bbox.right = Math.min(bbox.right, rects[i].right); - - if (bbox.left >= bbox.right) { - return null; - } - - bbox.top = Math.max(bbox.top, rects[i].top); - bbox.bottom = Math.min(bbox.bottom, rects[i].bottom); - - if (bbox.top >= bbox.bottom) { - return null; - } - } - - bbox.width = bbox.right - bbox.left; - bbox.height = bbox.bottom - bbox.top; - - return bbox; -} - -function _getPercentInView(element, topWin, {w, h} = {}) { - const elementBoundingBox = _getBoundingBox(element, {w, h}); - - // Obtain the intersection of the element and the viewport - const elementInViewBoundingBox = _getIntersectionOfRects([{ - left: 0, - top: 0, - right: topWin.innerWidth, - bottom: topWin.innerHeight - }, elementBoundingBox]); - - let elementInViewArea, elementTotalArea; - - if (elementInViewBoundingBox !== null) { - // Some or all of the element is in view - elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height; - elementTotalArea = elementBoundingBox.width * elementBoundingBox.height; - - return ((elementInViewArea / elementTotalArea) * 100); - } - - // No overlap between element and the viewport; therefore, the element - // lies completely out of view - return 0; -} - -function _getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return bid.params.bidFloor ? bid.params.bidFloor : null; - } - - let floor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') { - return floor.floor; - } - return null; -} - -registerBidder(spec); diff --git a/modules/brightcomBidAdapter.md b/modules/brightcomBidAdapter.md deleted file mode 100644 index 9f9aa0e5dd7..00000000000 --- a/modules/brightcomBidAdapter.md +++ /dev/null @@ -1,46 +0,0 @@ -# Overview - -``` -Module Name: Brightcom Bid Adapter -Module Type: Bidder Adapter -Maintainer: vladislavy@brightcom.com -``` - -# Description - -Brightcom's adapter integration to the Prebid library. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-leaderboard', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bids: [{ - bidder: 'brightcom', - params: { - publisherId: 2141020, - bidFloor: 0.01 - } - }] - }, { - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'brightcom', - params: { - publisherId: 2141020 - } - }] - } -] -``` diff --git a/modules/brightcomSSPBidAdapter.js b/modules/brightcomSSPBidAdapter.js deleted file mode 100644 index 4750881da40..00000000000 --- a/modules/brightcomSSPBidAdapter.js +++ /dev/null @@ -1,321 +0,0 @@ -import { - isArray, - getWindowTop, - getUniqueIdentifierStr, - deepSetValue, - logError, - logWarn, - createTrackPixelHtml, - getWindowSelf, - isFn, - isPlainObject, getBidIdParameter, -} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {ajax} from '../src/ajax.js'; - -const BIDDER_CODE = 'bcmssp'; -const URL = 'https://rt.marphezis.com/hb'; -const TRACK_EVENT_URL = 'https://rt.marphezis.com/prebid' - -export const spec = { - code: BIDDER_CODE, - gvlid: 883, - supportedMediaTypes: [BANNER], - isBidRequestValid, - buildRequests, - interpretResponse, - onBidderError, - onTimeout, - onBidWon, - getUserSyncs, -}; - -function buildRequests(bidReqs, bidderRequest) { - try { - const impressions = bidReqs.map(bid => { - let bidSizes = bid?.mediaTypes?.banner?.sizes || bid.sizes; - bidSizes = ((isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes]); - bidSizes = bidSizes.filter(size => isArray(size)); - const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})); - - const element = document.getElementById(bid.adUnitCode); - const minSize = _getMinSize(processedSizes); - const viewabilityAmount = _isViewabilityMeasurable(element) ? _getViewability(element, getWindowTop(), minSize) : 'na'; - const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); - - const imp = { - id: bid.bidId, - banner: { - format: processedSizes, - ext: { - viewability: viewabilityAmountRounded - } - }, - tagid: String(bid.adUnitCode) - }; - - const bidFloor = _getBidFloor(bid); - - if (bidFloor) { - imp.bidfloor = bidFloor; - } - - return imp; - }) - - const referrer = bidderRequest?.refererInfo?.page || ''; - const publisherId = getBidIdParameter('publisherId', bidReqs[0].params); - - const payload = { - id: getUniqueIdentifierStr(), - imp: impressions, - site: { - domain: bidderRequest?.refererInfo?.domain || '', - page: referrer, - publisher: { - id: publisherId - } - }, - device: { - devicetype: _getDeviceType(), - w: screen.width, - h: screen.height - }, - tmax: bidderRequest?.timeout - }; - - if (bidderRequest?.gdprConsent) { - deepSetValue(payload, 'regs.ext.gdpr', +bidderRequest.gdprConsent.gdprApplies); - deepSetValue(payload, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - if (bidderRequest?.uspConsent) { - deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (config.getConfig('coppa') === true) { - deepSetValue(payload, 'regs.coppa', 1); - } - - if (bidReqs?.[0]?.schain) { - deepSetValue(payload, 'source.ext.schain', bidReqs[0].schain) - } - - if (bidReqs?.[0]?.userIdAsEids) { - deepSetValue(payload, 'user.ext.eids', bidReqs[0].userIdAsEids || []) - } - - if (bidReqs?.[0].userId) { - deepSetValue(payload, 'user.ext.ids', bidReqs[0].userId || []) - } - - return { - method: 'POST', - url: URL, - data: JSON.stringify(payload), - }; - } catch (e) { - logError(e, {bidReqs, bidderRequest}); - } -} - -function isBidRequestValid(bid) { - if (bid.bidder !== BIDDER_CODE || !bid.params || !bid.params.publisherId) { - return false; - } - - return true; -} - -function interpretResponse(serverResponse) { - let response = []; - if (!serverResponse.body || typeof serverResponse.body != 'object') { - logWarn('Brightcom server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); - return response; - } - - const {body: {id, seatbid}} = serverResponse; - - try { - if (id && seatbid && seatbid.length > 0 && seatbid[0].bid && seatbid[0].bid.length > 0) { - response = seatbid[0].bid.map(bid => { - return { - requestId: bid.impid, - cpm: parseFloat(bid.price), - width: parseInt(bid.w), - height: parseInt(bid.h), - creativeId: bid.crid || bid.id, - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: _getAdMarkup(bid), - ttl: 60, - meta: { - advertiserDomains: bid?.adomain || [] - } - }; - }); - } - } catch (e) { - logError(e, {id, seatbid}); - } - - return response; -} - -// Don't do user sync for now -function getUserSyncs(syncOptions, responses, gdprConsent) { - return []; -} - -function onTimeout(timeoutData) { - if (timeoutData === null) { - return; - } - - _trackEvent('timeout', timeoutData); -} - -function onBidderError(errorData) { - if (errorData === null || !errorData.bidderRequest) { - return; - } - - _trackEvent('error', errorData.bidderRequest) -} - -function onBidWon(bid) { - if (bid === null) { - return; - } - - _trackEvent('bidwon', bid) -} - -function _trackEvent(endpoint, data) { - ajax(`${TRACK_EVENT_URL}/${endpoint}`, null, JSON.stringify(data), { - method: 'POST', - withCredentials: false - }); -} - -function _isMobile() { - return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); -} - -function _isConnectedTV() { - return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); -} - -function _getDeviceType() { - return _isMobile() ? 1 : _isConnectedTV() ? 3 : 2; -} - -function _getAdMarkup(bid) { - let adm = bid.adm; - if ('nurl' in bid) { - adm += createTrackPixelHtml(bid.nurl); - } - return adm; -} - -function _isViewabilityMeasurable(element) { - return !_isIframe() && element !== null; -} - -function _getViewability(element, topWin, {w, h} = {}) { - return getWindowTop().document.visibilityState === 'visible' ? _getPercentInView(element, topWin, {w, h}) : 0; -} - -function _isIframe() { - try { - return getWindowSelf() !== getWindowTop(); - } catch (e) { - return true; - } -} - -function _getMinSize(sizes) { - return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); -} - -function _getBoundingBox(element, {w, h} = {}) { - let {width, height, left, top, right, bottom} = element.getBoundingClientRect(); - - if ((width === 0 || height === 0) && w && h) { - width = w; - height = h; - right = left + w; - bottom = top + h; - } - - return {width, height, left, top, right, bottom}; -} - -function _getIntersectionOfRects(rects) { - const bbox = { - left: rects[0].left, right: rects[0].right, top: rects[0].top, bottom: rects[0].bottom - }; - - for (let i = 1; i < rects.length; ++i) { - bbox.left = Math.max(bbox.left, rects[i].left); - bbox.right = Math.min(bbox.right, rects[i].right); - - if (bbox.left >= bbox.right) { - return null; - } - - bbox.top = Math.max(bbox.top, rects[i].top); - bbox.bottom = Math.min(bbox.bottom, rects[i].bottom); - - if (bbox.top >= bbox.bottom) { - return null; - } - } - - bbox.width = bbox.right - bbox.left; - bbox.height = bbox.bottom - bbox.top; - - return bbox; -} - -function _getPercentInView(element, topWin, {w, h} = {}) { - const elementBoundingBox = _getBoundingBox(element, {w, h}); - - // Obtain the intersection of the element and the viewport - const elementInViewBoundingBox = _getIntersectionOfRects([{ - left: 0, top: 0, right: topWin.innerWidth, bottom: topWin.innerHeight - }, elementBoundingBox]); - - let elementInViewArea, elementTotalArea; - - if (elementInViewBoundingBox !== null) { - // Some or all of the element is in view - elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height; - elementTotalArea = elementBoundingBox.width * elementBoundingBox.height; - - return ((elementInViewArea / elementTotalArea) * 100); - } - - // No overlap between element and the viewport; therefore, the element - // lies completely out of view - return 0; -} - -function _getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return bid.params.bidFloor ? bid.params.bidFloor : null; - } - - let floor = bid.getFloor({ - currency: 'USD', mediaType: '*', size: '*' - }); - if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') { - return floor.floor; - } - return null; -} - -registerBidder(spec); diff --git a/modules/brightcomSSPBidAdapter.md b/modules/brightcomSSPBidAdapter.md deleted file mode 100644 index 8d0e4ec70dc..00000000000 --- a/modules/brightcomSSPBidAdapter.md +++ /dev/null @@ -1,46 +0,0 @@ -# Overview - -``` -Module Name: Brightcom SSP Bid Adapter -Module Type: Bidder Adapter -Maintainer: alexandruc@brightcom.com -``` - -# Description - -Brightcom's adapter integration to the Prebid library. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-leaderboard', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bids: [{ - bidder: 'bcmssp', - params: { - publisherId: 2141020, - bidFloor: 0.01 - } - }] - }, { - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'bcmssp', - params: { - publisherId: 2141020 - } - }] - } -] -``` diff --git a/modules/britepoolIdSystem.js b/modules/britepoolIdSystem.js deleted file mode 100644 index dcc365faaac..00000000000 --- a/modules/britepoolIdSystem.js +++ /dev/null @@ -1,155 +0,0 @@ -/** - * This module adds BritePoolId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/britepoolIdSystem - * @requires module:modules/userId - */ - -import { isEmpty, triggerPixel, logError } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -const PIXEL = 'https://px.britepool.com/new?partner_id=t'; - -/** - * @typedef {import('../modules/userId/index.js').Submodule} Submodule - * @typedef {import('../modules/userId/index.js').SubmoduleConfig} SubmoduleConfig - * @typedef {import('../modules/userId/index.js').ConsentData} ConsentData - * @typedef {import('../modules/userId/index.js').SubmoduleParams} SubmoduleParams - */ - -/** @type {Submodule} */ -export const britepoolIdSubmodule = { - /** - * Used to link submodule with config - * @type {string} - */ - name: 'britepoolId', - /** - * Decode the stored id value for passing to bid requests - * @function - * @param {string} value - * @returns {{britepoolid:string}} - */ - decode(value) { - return (value && typeof value['primaryBPID'] === 'string') ? { 'britepoolid': value['primaryBPID'] } : null; - }, - /** - * Performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [submoduleConfig] - * @param {ConsentData|undefined} consentData - * @returns {function} - */ - getId(submoduleConfig, consentData) { - const submoduleConfigParams = (submoduleConfig && submoduleConfig.params) || {}; - const { params, headers, url, getter, errors } = britepoolIdSubmodule.createParams(submoduleConfigParams, consentData); - let getterResponse = null; - if (typeof getter === 'function') { - getterResponse = getter(params); - // First let's rule out that the response is not a function - if (typeof getterResponse !== 'function') { - // Optimization to return value from getter - return { - id: britepoolIdSubmodule.normalizeValue(getterResponse) - }; - } - } - if (isEmpty(params)) { - triggerPixel(PIXEL); - } - // Return for async operation - return { - callback: function(callback) { - if (errors.length > 0) { - errors.forEach(error => logError(error)); - callback(); - return; - } - if (getterResponse) { - // Resolve the getter function response - try { - getterResponse(function(response) { - callback(britepoolIdSubmodule.normalizeValue(response)); - }); - } catch (error) { - if (error !== '') logError(error); - callback(); - } - } else { - ajax(url, { - success: response => { - const responseObj = britepoolIdSubmodule.normalizeValue(response); - callback(responseObj ? { primaryBPID: responseObj.primaryBPID } : null); - }, - error: error => { - if (error !== '') logError(error); - callback(); - } - }, JSON.stringify(params), { customHeaders: headers, contentType: 'application/json', method: 'POST', withCredentials: true }); - } - } - } - }, - /** - * Helper method to create params for our API call - * @param {SubmoduleParams} [submoduleConfigParams] - * @param {ConsentData|undefined} consentData - * @returns {object} Object with parsed out params - */ - createParams(submoduleConfigParams, consentData) { - const hasGdprData = consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies; - const gdprConsentString = hasGdprData ? consentData.consentString : undefined; - let errors = []; - const headers = {}; - const dynamicVars = typeof britepool_pubparams !== 'undefined' ? britepool_pubparams : {}; // eslint-disable-line camelcase, no-undef - let params = Object.assign({}, submoduleConfigParams, dynamicVars); - if (params.getter) { - // Custom getter will not require other params - if (typeof params.getter !== 'function') { - errors.push(`userIdTargeting - britepoolId submodule requires getter to be a function`); - return { errors }; - } - } else { - if (params.api_key) { - // Add x-api-key into the header - headers['x-api-key'] = params.api_key; - } - } - const url = params.url || `https://api.britepool.com/v1/britepool/id${gdprConsentString ? '?gdprString=' + encodeURIComponent(gdprConsentString) : ''}`; - const getter = params.getter; - delete params.api_key; - delete params.url; - delete params.getter; - return { - params, - headers, - url, - getter, - errors - }; - }, - /** - * Helper method to normalize a JSON value - */ - normalizeValue(value) { - let valueObj = null; - if (typeof value === 'object') { - valueObj = value; - } else if (typeof value === 'string') { - try { - valueObj = JSON.parse(value); - } catch (error) { - logError(error); - } - } - return valueObj; - }, - eids: { - 'britepoolid': { - source: 'britepool.com', - atype: 3 - }, - } -}; - -submodule('userId', britepoolIdSubmodule); diff --git a/modules/britepoolIdSystem.md b/modules/britepoolIdSystem.md deleted file mode 100644 index 72edbe2324b..00000000000 --- a/modules/britepoolIdSystem.md +++ /dev/null @@ -1,42 +0,0 @@ -## BritePool User ID Submodule - -BritePool User ID Module. For assistance setting up your module please contact us at [prebid@britepool.com](prebid@britepool.com). - -### Prebid Params - -Individual params may be set for the BritePool User ID Submodule. -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'britepoolId', - storage: { - name: 'britepoolid', - type: 'cookie', - expires: 30 - }, - params: { - url: 'https://sandbox-api.britepool.com/v1/britepool/id', // optional - api_key: '3fdbe297-3690-4f5c-9e11-ee9186a6d77c', // provided by britepool - hash: '31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66', // example hash identifier (sha256) - ssid: '221aa074-57fc-453b-81f0-6c74f628cd5c' // example identifier - } - }] - } -}); -``` -## Parameter Descriptions for the `usersync` Configuration Section -The below parameters apply only to the BritePool User ID Module integration. - -| Param under usersync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | ID value for the BritePool module - `"britepoolId"` | `"britepoolId"` | -| params | Required | Object | Details for BritePool initialization. | | -| params.api_key | Required | String |BritePool API Key provided by BritePool | "3fdbe297-3690-4f5c-9e11-ee9186a6d77c" | -| params.url | Optional | String |BritePool API url | "https://sandbox-api.britepool.com/v1/britepool/id" | -| params.identifier | Required | String | Where identifier in the params object is the key name. At least one identifier is required. Available Identifiers `aaid` `dtid` `idfa` `ilid` `luid` `mmid` `msid` `mwid` `rida` `ssid` `hash` | `params.ssid` `params.aaid` | -| storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | | -| storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` | -| storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"britepoolid"` | -| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` | -| value | Optional | Object | Used only if the page has a separate mechanism for storing the BritePool ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"primaryBPID": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}` | diff --git a/modules/carodaBidAdapter.js b/modules/carodaBidAdapter.js index cb7b5fbe7c5..8ec260213b6 100644 --- a/modules/carodaBidAdapter.js +++ b/modules/carodaBidAdapter.js @@ -8,7 +8,8 @@ import { deepSetValue, logError, mergeDeep, - parseSizesInput + sizeTupleToRtbSize, + sizesToSizeTuples } from '../src/utils.js'; import { config } from '../src/config.js'; @@ -195,13 +196,7 @@ function getImps (validBidRequests, common) { }; const bannerParams = deepAccess(bid, 'mediaTypes.banner'); if (bannerParams && bannerParams.sizes) { - const sizes = parseSizesInput(bannerParams.sizes); - const format = sizes.map(size => { - const [width, height] = size.split('x'); - const w = parseInt(width, 10); - const h = parseInt(height, 10); - return { w, h }; - }); + const format = sizesToSizeTuples(bannerParams.sizes).map(sizeTupleToRtbSize); imp.banner = { format }; diff --git a/modules/ceeIdSystem.js b/modules/ceeIdSystem.js index 5558e2c7d6f..30240e3f75f 100644 --- a/modules/ceeIdSystem.js +++ b/modules/ceeIdSystem.js @@ -16,14 +16,13 @@ import {domainOverrideToRootDomain} from '../libraries/domainOverrideToRootDomai */ const MODULE_NAME = 'ceeId'; -const ID_TOKEN = 'WPxid'; export const storage = getStorageManager({ moduleName: MODULE_NAME, moduleType: MODULE_TYPE_UID }); /** * Reads the ID token from local storage or cookies. * @returns {string|undefined} The ID token, or undefined if not found. */ -export const readId = () => storage.getDataFromLocalStorage(ID_TOKEN) || storage.getCookie(ID_TOKEN); +export const readId = tokenName => storage.getDataFromLocalStorage(tokenName) || storage.getCookie(tokenName); /** @type {Submodule} */ export const ceeIdSubmodule = { @@ -45,8 +44,10 @@ export const ceeIdSubmodule = { * @function * @returns {(IdResponse|undefined)} */ - getId() { - const ceeIdToken = readId(); + getId(config) { + const { params = {} } = config; + const { tokenName, value } = params + const ceeIdToken = value || readId(tokenName); return ceeIdToken ? { id: ceeIdToken } : undefined; }, diff --git a/modules/ceeIdSystem.md b/modules/ceeIdSystem.md index 811efe08069..fe7a543748d 100644 --- a/modules/ceeIdSystem.md +++ b/modules/ceeIdSystem.md @@ -20,6 +20,10 @@ pbjs.setConfig({ name: 'ceeIdToken', expires: 7, refreshInSeconds: 360 + }, + params: { + tokenName: 'name' // Your custom name of token to read + value: 'tokenValue' // Optional param if you want to pass token value directly through setConfig (this param shouldn't be set if token value will be taken from cookie or LS) } }] } diff --git a/modules/cleanioRtdProvider.js b/modules/cleanioRtdProvider.js index c3f3dd51a61..1a5e64de3cc 100644 --- a/modules/cleanioRtdProvider.js +++ b/modules/cleanioRtdProvider.js @@ -43,6 +43,7 @@ let preloadStatus = 0; * @param {string} scriptURL The script URL to preload */ function pageInitStepPreloadScript(scriptURL) { + // TODO: this bypasses adLoader const linkElement = document.createElement('link'); linkElement.rel = 'preload'; linkElement.as = 'script'; diff --git a/modules/cleanmedianetBidAdapter.js b/modules/cleanmedianetBidAdapter.js index 601a237baa8..a0e85032798 100644 --- a/modules/cleanmedianetBidAdapter.js +++ b/modules/cleanmedianetBidAdapter.js @@ -157,7 +157,7 @@ export const spec = { maxduration: bidRequest.mediaTypes.video.maxduration, api: bidRequest.mediaTypes.video.api, skip: bidRequest.mediaTypes.video.skip || bidRequest.params.video.skip, - placement: bidRequest.mediaTypes.video.placement || bidRequest.params.video.placement, + placement: bidRequest.mediaTypes.video.plcmt || bidRequest.params.video.plcmt, minduration: bidRequest.mediaTypes.video.minduration || bidRequest.params.video.minduration, playbackmethod: bidRequest.mediaTypes.video.playbackmethod || bidRequest.params.video.playbackmethod, startdelay: bidRequest.mediaTypes.video.startdelay || bidRequest.params.video.startdelay diff --git a/modules/codefuelBidAdapter.js b/modules/codefuelBidAdapter.js index a4accee3ce0..9f85b2b82cb 100644 --- a/modules/codefuelBidAdapter.js +++ b/modules/codefuelBidAdapter.js @@ -1,4 +1,4 @@ -import {deepAccess, isArray} from '../src/utils.js'; +import {isArray, setOnAny} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER} from '../src/mediaTypes.js'; @@ -148,15 +148,6 @@ function getDeviceType() { return 2; // 'desktop' } -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - function flatten(arr) { return [].concat(...arr); } diff --git a/modules/colossussspBidAdapter.js b/modules/colossussspBidAdapter.js index c69e484feb3..2abe9cb94a8 100644 --- a/modules/colossussspBidAdapter.js +++ b/modules/colossussspBidAdapter.js @@ -152,7 +152,6 @@ export const spec = { placement.gpid = gpid; } if (bid.userId) { - getUserId(placement.eids, bid.userId.britepoolid, 'britepool.com'); getUserId(placement.eids, bid.userId.idl_env, 'identityLink'); getUserId(placement.eids, bid.userId.id5id, 'id5-sync.com'); getUserId(placement.eids, bid.userId.uid2 && bid.userId.uid2.id, 'uidapi.com'); diff --git a/modules/compassBidAdapter.js b/modules/compassBidAdapter.js index addcdfebb27..f5d98312a63 100644 --- a/modules/compassBidAdapter.js +++ b/modules/compassBidAdapter.js @@ -1,212 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'compass'; const AD_URL = 'https://sa-lb.deliverimp.com/pbjs'; const SYNC_URL = 'https://sa-cs.deliverimp.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/concertBidAdapter.js b/modules/concertBidAdapter.js index 12dba194844..ec65ba11205 100644 --- a/modules/concertBidAdapter.js +++ b/modules/concertBidAdapter.js @@ -1,7 +1,7 @@ import { logWarn, logMessage, debugTurnedOn, generateUUID, deepAccess } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; -import { hasPurpose1Consent } from '../src/utils/gpdr.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/connatixBidAdapter.js b/modules/connatixBidAdapter.js index 0b840db6c26..802ad855e27 100644 --- a/modules/connatixBidAdapter.js +++ b/modules/connatixBidAdapter.js @@ -11,7 +11,9 @@ import { } from '../src/utils.js'; import { + ADPOD, BANNER, + VIDEO, } from '../src/mediaTypes.js'; const BIDDER_CODE = 'connatix'; @@ -41,10 +43,28 @@ export function getBidFloor(bid) { } } +export function validateBanner(mediaTypes) { + if (!mediaTypes[BANNER]) { + return true; + } + + const banner = deepAccess(mediaTypes, BANNER, {}); + return (Boolean(banner.sizes) && isArray(mediaTypes[BANNER].sizes) && mediaTypes[BANNER].sizes.length > 0); +} + +export function validateVideo(mediaTypes) { + const video = mediaTypes[VIDEO]; + if (!video) { + return true; + } + + return video.context !== ADPOD; +} + export const spec = { code: BIDDER_CODE, gvlid: 143, - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, VIDEO], /* * Validate the bid request. @@ -57,17 +77,24 @@ export const spec = { const params = deepAccess(bid, 'params', {}); const bidder = deepAccess(bid, 'bidder'); - const banner = deepAccess(mediaTypes, BANNER, {}); - const hasBidId = Boolean(bidId); const isValidBidder = (bidder === BIDDER_CODE); - const isValidSize = (Boolean(banner.sizes) && isArray(mediaTypes[BANNER].sizes) && mediaTypes[BANNER].sizes.length > 0); - const hasSizes = mediaTypes[BANNER] ? isValidSize : false; + const hasMediaTypes = Boolean(mediaTypes) && (Boolean(mediaTypes[BANNER]) || Boolean(mediaTypes[VIDEO])); + const isValidBanner = validateBanner(mediaTypes); + const isValidVideo = validateVideo(mediaTypes); const hasRequiredBidParams = Boolean(params.placementId); - const isValid = isValidBidder && hasBidId && hasSizes && hasRequiredBidParams; + const isValid = isValidBidder && hasBidId && hasMediaTypes && isValidBanner && isValidVideo && hasRequiredBidParams; if (!isValid) { - logError(`Invalid bid request: isValidBidder: ${isValidBidder} hasBidId: ${hasBidId}, hasSizes: ${hasSizes}, hasRequiredBidParams: ${hasRequiredBidParams}`); + logError( + `Invalid bid request: + isValidBidder: ${isValidBidder}, + hasBidId: ${hasBidId}, + hasMediaTypes: ${hasMediaTypes}, + isValidBanner: ${isValidBanner}, + isValidVideo: ${isValidVideo}, + hasRequiredBidParams: ${hasRequiredBidParams}` + ); } return isValid; }, @@ -129,12 +156,13 @@ export const spec = { cpm: bidResponse.Cpm, ttl: bidResponse.Ttl || DEFAULT_MAX_TTL, currency: 'USD', - mediaType: BANNER, + mediaType: bidResponse.VastXml ? VIDEO : BANNER, netRevenue: true, width: bidResponse.Width, height: bidResponse.Height, creativeId: bidResponse.CreativeId, ad: bidResponse.Ad, + vastXml: bidResponse.VastXml, referrer: referrer, })); }, diff --git a/modules/connectIdSystem.js b/modules/connectIdSystem.js index 2ebc68baa84..6926c69d453 100644 --- a/modules/connectIdSystem.js +++ b/modules/connectIdSystem.js @@ -313,12 +313,16 @@ export const connectIdSubmodule = { /** * Utility function that returns a boolean flag indicating if the user - * has opeted out via the Yahoo easy-opt-out mechanism. + * has opted out via the Yahoo easy-opt-out mechanism. * @returns {Boolean} */ userHasOptedOut() { try { - return localStorage.getItem(OVERRIDE_OPT_OUT_KEY) === '1'; + if (storage.localStorageIsEnabled()) { + return storage.getDataFromLocalStorage(OVERRIDE_OPT_OUT_KEY) === '1'; + } else { + return true; + } } catch { return false; } diff --git a/modules/connectadBidAdapter.js b/modules/connectadBidAdapter.js index b40ef30f6bc..5b892a6df22 100644 --- a/modules/connectadBidAdapter.js +++ b/modules/connectadBidAdapter.js @@ -3,7 +3,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js' import {config} from '../src/config.js'; import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; -import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; const BIDDER_CODE = 'connectad'; const BIDDER_CODE_ALIAS = 'connectadrealtime'; const ENDPOINT_URL = 'https://i.connectad.io/api/v2'; @@ -141,13 +140,6 @@ export const spec = { return bidResponses; }, - transformBidParams: function (params, isOpenRtb) { - return convertTypes({ - 'siteId': 'number', - 'networkId': 'number' - }, params); - }, - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { let syncEndpoint = 'https://cdn.connectad.io/connectmyusers.php?'; diff --git a/modules/consentManagementGpp.js b/modules/consentManagementGpp.js index f94048813c6..013650de20a 100644 --- a/modules/consentManagementGpp.js +++ b/modules/consentManagementGpp.js @@ -7,12 +7,12 @@ import {deepSetValue, isEmpty, isNumber, isPlainObject, isStr, logError, logInfo, logWarn} from '../src/utils.js'; import {config} from '../src/config.js'; import {gppDataHandler} from '../src/adapterManager.js'; -import {timedAuctionHook} from '../src/utils/perfMetrics.js'; import {enrichFPD} from '../src/fpd/enrichment.js'; import {getGlobal} from '../src/prebidGlobal.js'; -import {cmpClient, MODE_CALLBACK, MODE_MIXED, MODE_RETURN} from '../libraries/cmp/cmpClient.js'; +import {cmpClient, MODE_CALLBACK} from '../libraries/cmp/cmpClient.js'; import {GreedyPromise} from '../src/utils/promise.js'; import {buildActivityParams} from '../src/activities/params.js'; +import {consentManagementHook} from '../libraries/consentManagement/cmUtils.js'; const DEFAULT_CMP = 'iab'; const DEFAULT_CONSENT_TIMEOUT = 10000; @@ -38,9 +38,6 @@ function lookupStaticConsentData(callbacks) { return pipeCallbacks(() => processCmpData(staticConsentData), callbacks); } -const GPP_10 = '1.0'; -const GPP_11 = '1.1'; - class GPPError { constructor(message, arg) { this.message = message; @@ -49,104 +46,22 @@ class GPPError { } export class GPPClient { - static CLIENTS = {}; - - static register(apiVersion, defaultVersion = false) { - this.apiVersion = apiVersion; - this.CLIENTS[apiVersion] = this; - if (defaultVersion) { - this.CLIENTS.default = this; - } - } - + apiVersion = '1.1'; static INST; - /** - * Ping the CMP to set up an appropriate client for it, and initialize it. - * - * @param mkCmp - * @returns {Promise<[GPPClient,Promise<{}>]>} a promise to two objects: - * - a GPPClient that talks the best GPP dialect we know for the CMP's version; - * - a promise to GPP data. - */ - static init(mkCmp = cmpClient) { - let inst = this.INST; - if (!inst) { - let err; - const reset = () => err && (this.INST = null); - inst = this.INST = this.ping(mkCmp).catch(e => { - err = true; - reset(); - throw e; + static get(mkCmp = cmpClient) { + if (this.INST == null) { + const cmp = mkCmp({ + apiName: '__gpp', + apiArgs: ['command', 'callback', 'parameter'], // do not pass version - not clear what it's for (or what we should use), + mode: MODE_CALLBACK }); - reset(); - } - return inst.then(([client, pingData]) => [ - client, - client.initialized ? client.refresh() : client.init(pingData) - ]); - } - - /** - * Ping the CMP to determine its version and set up a client appropriate for it. - * - * @param mkCmp - * @returns {Promise<[GPPClient, {}]>} a promise to two objects: - * - a GPPClient that talks the best GPP dialect we know for the CMP's version; - * - the result from pinging the CMP. - */ - static ping(mkCmp = cmpClient) { - const cmpOptions = { - apiName: '__gpp', - apiArgs: ['command', 'callback', 'parameter'], // do not pass version - not clear what it's for (or what we should use) - }; - - // in 1.0, 'ping' should return pingData but ignore callback; - // in 1.1 it should not return anything but run the callback - // the following looks for either - but once the version is known, produce a client that knows whether the - // rest of the interactions should pick return values or pass callbacks - - const probe = mkCmp({...cmpOptions, mode: MODE_RETURN}); - return new GreedyPromise((resolve, reject) => { - if (probe == null) { - reject(new GPPError('GPP CMP not found')); - return; + if (cmp == null) { + throw new GPPError('GPP CMP not found'); } - let done = false; // some CMPs do both return value and callbacks - avoid repeating log messages - const pong = (result, success) => { - if (done) return; - if (success != null && !success) { - reject(result); - return; - } - if (result == null) return; - done = true; - const cmpVersion = result?.gppVersion; - const Client = this.getClient(cmpVersion); - if (cmpVersion !== Client.apiVersion) { - logWarn(`Unrecognized GPP CMP version: ${cmpVersion}. Continuing using GPP API version ${Client}...`); - } else { - logInfo(`Using GPP version ${cmpVersion}`); - } - const mode = Client.apiVersion === GPP_10 ? MODE_MIXED : MODE_CALLBACK; - const client = new Client( - cmpVersion, - mkCmp({...cmpOptions, mode}) - ); - resolve([client, result]); - }; - - probe({ - command: 'ping', - callback: pong - }).then((res) => pong(res, true), reject); - }).finally(() => { - probe && probe.close(); - }); - } - - static getClient(cmpVersion) { - return this.CLIENTS.hasOwnProperty(cmpVersion) ? this.CLIENTS[cmpVersion] : this.CLIENTS.default; + this.INST = new this(cmp); + } + return this.INST; } #resolve; @@ -155,9 +70,7 @@ export class GPPClient { initialized = false; - constructor(cmpVersion, cmp) { - this.apiVersion = this.constructor.apiVersion; - this.cmpVersion = cmp; + constructor(cmp) { this.cmp = cmp; [this.#resolve, this.#reject] = [0, 1].map(slot => (result) => { while (this.#pending.length) { @@ -176,6 +89,9 @@ export class GPPClient { init(pingData) { const ready = this.updateWhenReady(pingData); if (!this.initialized) { + if (pingData.gppVersion !== this.apiVersion) { + logWarn(`Unrecognized GPP CMP version: ${pingData.apiVersion}. Continuing using GPP API version ${this.apiVersion}...`); + } this.initialized = true; this.cmp({ command: 'addEventListener', @@ -184,7 +100,7 @@ export class GPPClient { this.#reject(new GPPError('Received error response from CMP', event)); } else if (event?.pingData?.cmpStatus === 'error') { this.#reject(new GPPError('CMP status is "error"; please check CMP setup', event)); - } else if (this.isCMPReady(event?.pingData || {}) && this.events.includes(event?.eventName)) { + } else if (this.isCMPReady(event?.pingData || {}) && ['sectionChange', 'signalStatus'].includes(event?.eventName)) { this.#resolve(this.updateConsent(event.pingData)); } } @@ -194,7 +110,7 @@ export class GPPClient { } refresh() { - return this.cmp({command: 'ping'}).then(this.updateWhenReady.bind(this)); + return this.cmp({command: 'ping'}).then(this.init.bind(this)); } /** @@ -204,15 +120,14 @@ export class GPPClient { * @returns {Promise<{}>} a promise to GPP consent data */ updateConsent(pingData) { - return this.getGPPData(pingData).then((data) => { - if (data == null || isEmpty(data)) { - throw new GPPError('Received empty response from CMP', data); + return new GreedyPromise(resolve => { + if (pingData == null || isEmpty(pingData)) { + throw new GPPError('Received empty response from CMP', pingData); } - return processCmpData(data); - }).then((data) => { - logInfo('Retrieved GPP consent from CMP:', data); - return data; - }); + const consentData = processCmpData(pingData); + logInfo('Retrieved GPP consent from CMP:', consentData); + resolve(consentData); + }) } /** @@ -236,68 +151,10 @@ export class GPPClient { updateWhenReady(pingData) { return this.isCMPReady(pingData) ? this.updateConsent(pingData) : this.nextUpdate(); } -} - -// eslint-disable-next-line no-unused-vars -class GPP10Client extends GPPClient { - static { - super.register(GPP_10); - } - - events = ['sectionChange', 'cmpStatus']; - - isCMPReady(pingData) { - return pingData.cmpStatus === 'loaded'; - } - - getGPPData(pingData) { - const parsedSections = GreedyPromise.all( - (pingData.supportedAPIs || pingData.apiSupport || []).map((api) => this.cmp({ - command: 'getSection', - parameter: api - }).catch(err => { - logWarn(`Could not retrieve GPP section '${api}'`, err); - }).then((section) => [api, section])) - ).then(sections => { - // parse single section object into [core, gpc] to uniformize with 1.1 parsedSections - return Object.fromEntries( - sections.filter(([_, val]) => val != null) - .map(([api, section]) => { - const subsections = [ - Object.fromEntries(Object.entries(section).filter(([k]) => k !== 'Gpc')) - ]; - if (section.Gpc != null) { - subsections.push({ - SubsectionType: 1, - Gpc: section.Gpc - }); - } - return [api, subsections]; - }) - ); - }); - return GreedyPromise.all([ - this.cmp({command: 'getGPPData'}), - parsedSections - ]).then(([gppData, parsedSections]) => Object.assign({}, gppData, {parsedSections})); - } -} - -// eslint-disable-next-line no-unused-vars -class GPP11Client extends GPPClient { - static { - super.register(GPP_11, true); - } - - events = ['sectionChange', 'signalStatus']; isCMPReady(pingData) { return pingData.signalStatus === 'ready'; } - - getGPPData(pingData) { - return GreedyPromise.resolve(pingData); - } } /** @@ -310,7 +167,7 @@ class GPP11Client extends GPPClient { * @param {function(): Object} [mkCmp=cmpClient] - A function to create the CMP client. Defaults to `cmpClient`. */ export function lookupIabConsent({onSuccess, onError}, mkCmp = cmpClient) { - pipeCallbacks(() => GPPClient.init(mkCmp).then(([client, gppDataPm]) => gppDataPm), {onSuccess, onError}); + pipeCallbacks(() => GPPClient.get(mkCmp).refresh(), {onSuccess, onError}); } // add new CMPs here, with their dedicated lookup function @@ -371,20 +228,6 @@ function loadConsentData(cb) { } } -/** - * Like `loadConsentData`, but cache and re-use previously loaded data. - * @param cb - */ -function loadIfMissing(cb) { - if (consentData) { - logInfo('User consent information already known. Pulling internally stored information...'); - // eslint-disable-next-line standard/no-callback-literal - cb(false); - } else { - loadConsentData(cb); - } -} - /** * If consentManagement module is enabled (ie included in setConfig), this hook function will attempt to fetch the * user's encoded consent string from the supported CMP. Once obtained, the module will store this @@ -393,29 +236,7 @@ function loadIfMissing(cb) { * @param {object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids. * @param {function} fn required; The next function in the chain, used by hook.js */ -export const requestBidsHook = timedAuctionHook('gpp', function requestBidsHook(fn, reqBidsConfigObj) { - loadIfMissing(function (shouldCancelAuction, errMsg, ...extraArgs) { - if (errMsg) { - let log = logWarn; - if (shouldCancelAuction) { - log = logError; - errMsg = `${errMsg} Canceling auction as per consentManagement config.`; - } - log(errMsg, ...extraArgs); - } - - if (shouldCancelAuction) { - fn.stopTiming(); - if (typeof reqBidsConfigObj.bidsBackHandler === 'function') { - reqBidsConfigObj.bidsBackHandler(); - } else { - logError('Error executing bidsBackHandler'); - } - } else { - fn.call(this, reqBidsConfigObj); - } - }); -}); +export const requestBidsHook = consentManagementHook('gpp', () => consentData, loadConsentData); function processCmpData(consentData) { if ( @@ -427,9 +248,9 @@ function processCmpData(consentData) { } ['usnatv1', 'uscav1'].forEach(section => { if (consentData?.parsedSections?.[section]) { - logWarn(`Received invalid section from cmp: '${section}'. Some functionality may not work as expected`, consentData) + logWarn(`Received invalid section from cmp: '${section}'. Some functionality may not work as expected`, consentData); } - }) + }); return storeConsentData(consentData); } diff --git a/modules/consentManagement.js b/modules/consentManagementTcf.js similarity index 91% rename from modules/consentManagement.js rename to modules/consentManagementTcf.js index c7c618635ba..7de273c1380 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagementTcf.js @@ -8,11 +8,11 @@ import {deepSetValue, isNumber, isPlainObject, isStr, logError, logInfo, logWarn import {config} from '../src/config.js'; import {gdprDataHandler} from '../src/adapterManager.js'; import {includes} from '../src/polyfill.js'; -import {timedAuctionHook} from '../src/utils/perfMetrics.js'; import {registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js'; import {enrichFPD} from '../src/fpd/enrichment.js'; import {getGlobal} from '../src/prebidGlobal.js'; import {cmpClient} from '../libraries/cmp/cmpClient.js'; +import {consentManagementHook} from '../libraries/consentManagement/cmUtils.js'; const DEFAULT_CMP = 'iab'; const DEFAULT_CONSENT_TIMEOUT = 10000; @@ -22,6 +22,7 @@ export let userCMP; export let consentTimeout; export let gdprScope; export let staticConsentData; +let dsaPlatform = false; let actionTimeout; let consentData; @@ -156,20 +157,6 @@ function loadConsentData(cb) { } } -/** - * Like `loadConsentData`, but cache and re-use previously loaded data. - * @param cb - */ -function loadIfMissing(cb) { - if (consentData) { - logInfo('User consent information already known. Pulling internally stored information...'); - // eslint-disable-next-line standard/no-callback-literal - cb(false); - } else { - loadConsentData(cb); - } -} - /** * If consentManagement module is enabled (ie included in setConfig), this hook function will attempt to fetch the * user's encoded consent string from the supported CMP. Once obtained, the module will store this @@ -178,29 +165,7 @@ function loadIfMissing(cb) { * @param {object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids. * @param {function} fn required; The next function in the chain, used by hook.js */ -export const requestBidsHook = timedAuctionHook('gdpr', function requestBidsHook(fn, reqBidsConfigObj) { - loadIfMissing(function (shouldCancelAuction, errMsg, ...extraArgs) { - if (errMsg) { - let log = logWarn; - if (shouldCancelAuction) { - log = logError; - errMsg = `${errMsg} Canceling auction as per consentManagement config.`; - } - log(errMsg, ...extraArgs); - } - - if (shouldCancelAuction) { - fn.stopTiming(); - if (typeof reqBidsConfigObj.bidsBackHandler === 'function') { - reqBidsConfigObj.bidsBackHandler(); - } else { - logError('Error executing bidsBackHandler'); - } - } else { - fn.call(this, reqBidsConfigObj); - } - }); -}); +export const requestBidsHook = consentManagementHook('gdpr', () => consentData, loadConsentData); /** * This function checks the consent data provided by CMP to ensure it's in an expected state. @@ -282,6 +247,7 @@ export function setConsentConfig(config) { // if true, then gdprApplies should be set to true gdprScope = config.defaultGdprScope === true; + dsaPlatform = !!config.dsaPlatform; logInfo('consentManagement module has been activated...'); @@ -315,6 +281,9 @@ export function enrichFPDHook(next, fpd) { } deepSetValue(ortb2, 'user.ext.consent', consent.consentString); } + if (dsaPlatform) { + deepSetValue(ortb2, 'regs.ext.dsa.dsarequired', 3); + } return ortb2; })); } diff --git a/modules/consumableBidAdapter.js b/modules/consumableBidAdapter.js index 30b081e53d3..cb802508de9 100644 --- a/modules/consumableBidAdapter.js +++ b/modules/consumableBidAdapter.js @@ -61,7 +61,8 @@ export const spec = { source: [{ 'name': 'prebidjs', 'version': '$prebid.version$' - }] + }], + lang: bidderRequest.ortb2.device.language, }, validBidRequests[0].params); if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/modules/contentexchangeBidAdapter.js b/modules/contentexchangeBidAdapter.js index a6aa9262061..96a55d657d2 100644 --- a/modules/contentexchangeBidAdapter.js +++ b/modules/contentexchangeBidAdapter.js @@ -1,216 +1,21 @@ -import { isFn, deepAccess, logMessage } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'contentexchange'; const AD_URL = 'https://eu2.adnetwork.agency/pbjs'; const SYNC_URL = 'https://sync2.adnetwork.agency'; const GVLID = 864; -function isBidResponseValid (bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency || !bid.meta) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData (bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, adFormat } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - placementId, - bidId, - adFormat, - schain, - bidfloor - }; - - switch (adFormat) { - case BANNER: - placement.sizes = mediaTypes[BANNER].sizes; - break; - case VIDEO: - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - break; - case NATIVE: - placement.native = mediaTypes[NATIVE]; - break; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} - export const spec = { code: BIDDER_CODE, gvlid: GVLID, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && - params && - params.placementId && - params.adFormat - ); - switch (params.adFormat) { - case BANNER: - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - break; - case VIDEO: - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - break; - case NATIVE: - valid = valid && Boolean(mediaTypes[NATIVE]); - break; - default: - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - - // TODO: does the fallback to 'window.location' make sense? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/contxtfulRtdProvider.js b/modules/contxtfulRtdProvider.js index e2bb1f3b909..03050a6a64f 100644 --- a/modules/contxtfulRtdProvider.js +++ b/modules/contxtfulRtdProvider.js @@ -17,12 +17,19 @@ import { isArray, } from '../src/utils.js'; import { loadExternalScript } from '../src/adloader.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; const MODULE_NAME = 'contxtful'; const MODULE = `${MODULE_NAME}RtdProvider`; const CONTXTFUL_RECEPTIVITY_DOMAIN = 'api.receptivity.io'; +const storageManager = getStorageManager({ + moduleType: MODULE_TYPE_RTD, + moduleName: MODULE_NAME +}); + let rxApi = null; let isFirstBidRequestCall = true; @@ -35,8 +42,19 @@ function getRxEngineReceptivity(requester) { return rxApi?.receptivity(requester); } +function getItemFromSessionStorage(key) { + let value = null; + try { + // Use the Storage Manager + value = storageManager.getDataFromSessionStorage(key, null); + } catch (error) { + } + + return value; +} + function loadSessionReceptivity(requester) { - let sessionStorageValue = sessionStorage.getItem(requester); + let sessionStorageValue = getItemFromSessionStorage(requester); if (!sessionStorageValue) { return null; } @@ -54,7 +72,7 @@ function loadSessionReceptivity(requester) { } catch { return null; } -}; +} /** * Prepare a receptivity batch diff --git a/modules/contxtfulRtdProvider.md b/modules/contxtfulRtdProvider.md index 71a641db4ad..622b353c27a 100644 --- a/modules/contxtfulRtdProvider.md +++ b/modules/contxtfulRtdProvider.md @@ -63,6 +63,7 @@ pbjs.setConfig({ } }); ``` + ## Parameters | Name | Type | Scope | Description | diff --git a/modules/conversantAnalyticsAdapter.js b/modules/conversantAnalyticsAdapter.js index 44e712d54f7..520735d4e73 100644 --- a/modules/conversantAnalyticsAdapter.js +++ b/modules/conversantAnalyticsAdapter.js @@ -1,7 +1,6 @@ import {ajax} from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; -import {getGlobal} from '../src/prebidGlobal.js'; import adapterManager from '../src/adapterManager.js'; import {logInfo, logWarn, logError, logMessage, deepAccess, isInteger} from '../src/utils.js'; import {getRefererInfo} from '../src/refererDetection.js'; @@ -515,7 +514,7 @@ cnvrHelper.createPayload = function(payloadType, auctionId, timestamp) { cnvrSampleRate: initOptions.cnvr_sample_rate, auction: { auctionId: auctionId, - preBidVersion: getGlobal().version, + preBidVersion: '$prebid.version$', sid: initOptions.site_id, auctionTimestamp: timestamp }, diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js index 76ff2a9e2ad..ea8488cf361 100644 --- a/modules/conversantBidAdapter.js +++ b/modules/conversantBidAdapter.js @@ -60,6 +60,7 @@ const converter = ortbConverter({ request: function (buildRequest, imps, bidderRequest, context) { const request = buildRequest(imps, bidderRequest, context); request.at = 1; + request.cur = ['USD']; if (context.bidRequests) { const bidRequest = context.bidRequests[0]; setSiteId(bidRequest, request); @@ -95,7 +96,7 @@ const converter = ortbConverter({ }, response(buildResponse, bidResponses, ortbResponse, context) { const response = buildResponse(bidResponses, ortbResponse, context); - return response.bids; + return response; }, overrides: { imp: { @@ -176,7 +177,8 @@ export const spec = { * @return {Bid[]} An array of bids which were nested inside the server. */ interpretResponse: function(serverResponse, bidRequest) { - return converter.fromORTB({request: bidRequest.data, response: serverResponse.body}); + const ortbBids = converter.fromORTB({request: bidRequest.data, response: serverResponse.body}); + return ortbBids; }, /** diff --git a/modules/copper6sspBidAdapter.js b/modules/copper6sspBidAdapter.js new file mode 100644 index 00000000000..335b3b3d144 --- /dev/null +++ b/modules/copper6sspBidAdapter.js @@ -0,0 +1,19 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; + +const BIDDER_CODE = 'copper6ssp'; +const AD_URL = 'https://endpoint.copper6.com/pbjs'; +const SYNC_URL = 'https://сsync.copper6.com'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) +}; + +registerBidder(spec); diff --git a/modules/copper6sspBidAdapter.md b/modules/copper6sspBidAdapter.md new file mode 100755 index 00000000000..a414187022d --- /dev/null +++ b/modules/copper6sspBidAdapter.md @@ -0,0 +1,79 @@ +# Overview + +``` +Module Name: Copper6SSP Bidder Adapter +Module Type: Copper6SSP Bidder Adapter +Maintainer: info@copper6.com +``` + +# Description + +Connects to Copper6SSP exchange for bids. +Copper6SSP bid adapter supports Banner, Video (instream and outstream) and Native. + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'adunit1', + mediaTypes: { + banner: { + sizes: [ [300, 250], [320, 50] ], + } + }, + bids: [ + { + bidder: 'copper6ssp', + params: { + placementId: 'testBanner', + } + } + ] + }, + { + code: 'addunit2', + mediaTypes: { + video: { + playerSize: [ [640, 480] ], + context: 'instream', + minduration: 5, + maxduration: 60, + } + }, + bids: [ + { + bidder: 'copper6ssp', + params: { + placementId: 'testVideo', + } + } + ] + }, + { + code: 'addunit3', + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + }, + bids: [ + { + bidder: 'copper6ssp', + params: { + placementId: 'testNative', + } + } + ] + } + ]; +``` \ No newline at end of file diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index e076fb4b0bb..772cb8c537c 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -1,8 +1,8 @@ import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {getBidIdParameter} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const BIDDER_CODE = 'cpmstar'; @@ -12,15 +12,18 @@ const ENDPOINT_PRODUCTION = 'https://server.cpmstar.com/view.aspx'; const DEFAULT_TTL = 300; const DEFAULT_CURRENCY = 'USD'; +const DEFAULT_NET_REVENUE = true; -function fixedEncodeURIComponent(str) { - return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { - return '%' + c.charCodeAt(0).toString(16); - }); -} +export const converter = ortbConverter({ + context: { + ttl: DEFAULT_TTL, + netRevenue: DEFAULT_NET_REVENUE + } +}); export const spec = { code: BIDDER_CODE, + gvlid: 1317, supportedMediaTypes: [BANNER, VIDEO], pageID: Math.floor(Math.random() * 10e6), @@ -43,22 +46,30 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { var requests = []; - // This reference to window.top can cause issues when loaded in an iframe if not protected with a try/catch. for (var i = 0; i < validBidRequests.length; i++) { var bidRequest = validBidRequests[i]; - var referer = bidderRequest.refererInfo.page ? bidderRequest.refererInfo.page : bidderRequest.refererInfo.domain; - referer = encodeURIComponent(referer); - var e = getBidIdParameter('endpoint', bidRequest.params); - var ENDPOINT = e == 'dev' ? ENDPOINT_DEV : e == 'staging' ? ENDPOINT_STAGING : ENDPOINT_PRODUCTION; - var mediaType = spec.getMediaType(bidRequest); - var playerSize = spec.getPlayerSize(bidRequest); - var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : ''); - var url = ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + - '&json=c_b&mv=1&poolid=' + getBidIdParameter('placementId', bidRequest.params) + - '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + - '&requestid=' + bidRequest.bidId + - '&referer=' + encodeURIComponent(referer); + const referer = bidderRequest.refererInfo.page ? bidderRequest.refererInfo.page : bidderRequest.refererInfo.domain; + const e = utils.getBidIdParameter('endpoint', bidRequest.params); + const ENDPOINT = e == 'dev' ? ENDPOINT_DEV : e == 'staging' ? ENDPOINT_STAGING : ENDPOINT_PRODUCTION; + const url = new URL(ENDPOINT); + const body = {}; + const mediaType = spec.getMediaType(bidRequest); + const playerSize = spec.getPlayerSize(bidRequest); + url.searchParams.set('media', mediaType); + if (mediaType == VIDEO) { + url.searchParams.set('fv', 0); + if (playerSize) { + url.searchParams.set('w', playerSize?.[0]); + url.searchParams.set('h', playerSize?.[1]); + } + } + url.searchParams.set('json', 'c_b'); + url.searchParams.set('mv', 1); + url.searchParams.set('poolid', utils.getBidIdParameter('placementId', bidRequest.params)); + url.searchParams.set('reachedTop', bidderRequest.refererInfo.reachedTop); + url.searchParams.set('requestid', bidRequest.bidId); + url.searchParams.set('referer', referer); if (bidRequest.schain && bidRequest.schain.nodes) { var schain = bidRequest.schain; @@ -67,45 +78,49 @@ export const spec = { for (var i2 = 0; i2 < schain.nodes.length; i2++) { var node = schain.nodes[i2]; schainString += '!' + - fixedEncodeURIComponent(node.asi || '') + ',' + - fixedEncodeURIComponent(node.sid || '') + ',' + - fixedEncodeURIComponent(node.hp || '') + ',' + - fixedEncodeURIComponent(node.rid || '') + ',' + - fixedEncodeURIComponent(node.name || '') + ',' + - fixedEncodeURIComponent(node.domain || ''); + (node.asi || '') + ',' + + (node.sid || '') + ',' + + (node.hp || '') + ',' + + (node.rid || '') + ',' + + (node.name || '') + ',' + + (node.domain || ''); } - url += '&schain=' + schainString; + url.searchParams.set('schain', schainString); } if (bidderRequest.gdprConsent) { if (bidderRequest.gdprConsent.consentString != null) { - url += '&gdpr_consent=' + bidderRequest.gdprConsent.consentString; + url.searchParams.set('gdpr_consent', bidderRequest.gdprConsent.consentString); } if (bidderRequest.gdprConsent.gdprApplies != null) { - url += '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? 1 : 0); + url.searchParams.set('gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); } } if (bidderRequest.uspConsent != null) { - url += '&us_privacy=' + bidderRequest.uspConsent; + url.searchParams.set('us_privacy', bidderRequest.uspConsent); } if (config.getConfig('coppa')) { - url += '&tfcd=' + (config.getConfig('coppa') ? 1 : 0); + url.searchParams.set('tfcd', (config.getConfig('coppa') ? 1 : 0)); } - let body = {}; let adUnitCode = bidRequest.adUnitCode; if (adUnitCode) { body.adUnitCode = adUnitCode; } if (mediaType == VIDEO) { body.video = utils.deepAccess(bidRequest, 'mediaTypes.video'); + } else if (mediaType == BANNER) { + body.banner = utils.deepAccess(bidRequest, 'mediaTypes.banner'); } + const ortb = converter.toORTB({ bidderRequest, bidRequests: [bidRequest] }); + Object.assign(body, ortb); + requests.push({ method: 'POST', - url: url, + url: url.toString(), bidRequest: bidRequest, data: body }); @@ -144,7 +159,7 @@ export const spec = { width: rawBid.width || 0, height: rawBid.height || 0, currency: rawBid.currency ? rawBid.currency : DEFAULT_CURRENCY, - netRevenue: rawBid.netRevenue ? rawBid.netRevenue : true, + netRevenue: rawBid.netRevenue ? rawBid.netRevenue : DEFAULT_NET_REVENUE, ttl: rawBid.ttl ? rawBid.ttl : DEFAULT_TTL, creativeId: rawBid.creativeid || 0, meta: { @@ -191,4 +206,5 @@ export const spec = { } }; + registerBidder(spec); diff --git a/modules/cpmstarBidAdapter.md b/modules/cpmstarBidAdapter.md index c227f19bfaf..66f13479c05 100755 --- a/modules/cpmstarBidAdapter.md +++ b/modules/cpmstarBidAdapter.md @@ -3,10 +3,7 @@ ``` Module Name: Cpmstar Bidder Adapter Module Type: Bidder Adapter -Maintainer: josh@cpmstar.com -gdpr_supported: true -usp_supported: true -coppa_supported: true +Maintainer: prebid@cpmstar.com ``` # Description diff --git a/modules/craftBidAdapter.js b/modules/craftBidAdapter.js index c751a18cc84..f8d216f0838 100644 --- a/modules/craftBidAdapter.js +++ b/modules/craftBidAdapter.js @@ -4,7 +4,7 @@ import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {find, includes} from '../src/polyfill.js'; import {getStorageManager} from '../src/storageManager.js'; import {ajax} from '../src/ajax.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index c95cbf7af73..053980d04ab 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -1,15 +1,14 @@ -import { deepAccess, generateUUID, isArray, logError, logInfo, logWarn, parseUrl } from '../src/utils.js'; -import { loadExternalScript } from '../src/adloader.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; // ref#2 -import { getStorageManager } from '../src/storageManager.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import { hasPurpose1Consent } from '../src/utils/gpdr.js'; -import { Renderer } from '../src/Renderer.js'; -import { OUTSTREAM } from '../src/video.js'; -import { ajax } from '../src/ajax.js'; +import {deepAccess, deepSetValue, isArray, logError, logWarn, parseUrl} from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import {getStorageManager} from '../src/storageManager.js'; +import {getRefererInfo} from '../src/refererDetection.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; +import {Renderer} from '../src/Renderer.js'; +import {OUTSTREAM} from '../src/video.js'; +import {ajax} from '../src/ajax.js'; +import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +import {ortb25Translator} from '../libraries/ortb2.5Translator/translator.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -20,35 +19,199 @@ import { ajax } from '../src/ajax.js'; */ const GVLID = 91; -export const ADAPTER_VERSION = 36; +export const ADAPTER_VERSION = 37; const BIDDER_CODE = 'criteo'; -const CDB_ENDPOINT = 'https://bidder.criteo.com/cdb'; +const CDB_ENDPOINT = 'https://grid-bidder.criteo.com/openrtb_2_5/pbjs/auction/request'; const PROFILE_ID_INLINE = 207; -export const PROFILE_ID_PUBLISHERTAG = 185; export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const LOG_PREFIX = 'Criteo: '; +const TRANSLATOR = ortb25Translator(); -/* - If you don't want to use the FastBid adapter feature, you can lighten criteoBidAdapter size by : - 1. commenting the tryGetCriteoFastBid function inner content (see ref#1) - 2. removing the line 'verify' function import line (see ref#2) - - Unminified source code can be found in the privately shared repo: https://github.com/Prebid-org/prebid-js-external-js-criteo/blob/master/dist/prod.js -*/ -const FAST_BID_VERSION_PLACEHOLDER = '%FAST_BID_VERSION%'; -export const FAST_BID_VERSION_CURRENT = 144; -const FAST_BID_VERSION_LATEST = 'latest'; -const FAST_BID_VERSION_NONE = 'none'; -const PUBLISHER_TAG_URL_TEMPLATE = 'https://static.criteo.net/js/ld/publishertag.prebid' + FAST_BID_VERSION_PLACEHOLDER + '.js'; const PUBLISHER_TAG_OUTSTREAM_SRC = 'https://static.criteo.net/js/ld/publishertag.renderer.js' -const FAST_BID_PUBKEY_E = 65537; -const FAST_BID_PUBKEY_N = 'ztQYwCE5BU7T9CDM5he6rKoabstXRmkzx54zFPZkWbK530dwtLBDeaWBMxHBUT55CYyboR/EZ4efghPi3CoNGfGWezpjko9P6p2EwGArtHEeS4slhu/SpSIFMjG6fdrpRoNuIAMhq1Z+Pr/+HOd1pThFKeGFr2/NhtAg+TXAzaU='; - const OPTOUT_COOKIE_NAME = 'cto_optout'; const BUNDLE_COOKIE_NAME = 'cto_bundle'; const GUID_RETENTION_TIME_HOUR = 24 * 30 * 13; // 13 months const OPTOUT_RETENTION_TIME_HOUR = 5 * 12 * 30 * 24; // 5 years +/** + * Defines the generic oRTB converter and all customization functions. + */ +const CONVERTER = ortbConverter({ + context: { + netRevenue: true, + ttl: 60 + }, + imp, + request, + bidResponse, + response +}); + +/** + * Builds an impression object for the ORTB 2.5 request. + * + * @param {function} buildImp - The function for building an imp object. + * @param {Object} bidRequest - The bid request object. + * @param {Object} context - The context object. + * @returns {Object} The ORTB 2.5 imp object. + */ +function imp(buildImp, bidRequest, context) { + let imp = buildImp(bidRequest, context); + const params = bidRequest.params; + + imp.tagid = bidRequest.adUnitCode; + deepSetValue(imp, 'ext', { + ...bidRequest.params.ext, + ...imp.ext, + rwdd: imp.rwdd, + floors: getFloors(bidRequest), + bidder: { + publishersubid: params?.publisherSubId, + zoneid: params?.zoneId, + uid: params?.uid, + }, + }); + + delete imp.rwdd // oRTB 2.6 field moved to ext + + if (!context.fledgeEnabled && imp.ext.igs?.ae) { + delete imp.ext.igs.ae; + } + + if (hasVideoMediaType(bidRequest)) { + const paramsVideo = bidRequest.params.video; + if (paramsVideo !== undefined) { + deepSetValue(imp, 'video', { + ...imp.video, + skip: imp.video.skip || paramsVideo.skip || 0, + placement: imp.video.placement || paramsVideo.placement, + minduration: imp.video.minduration || paramsVideo.minduration, + playbackmethod: imp.video.playbackmethod || paramsVideo.playbackmethod, + startdelay: imp.video.startdelay || paramsVideo.startdelay || 0, + }) + } + deepSetValue(imp, 'video.ext', { + context: bidRequest.mediaTypes.video.context, + playersizes: parseSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize'), parseSize), + plcmt: bidRequest.mediaTypes.video.plcmt, + poddur: bidRequest.mediaTypes.video.adPodDurationSec, + rqddurs: bidRequest.mediaTypes.video.durationRangeSec, + }) + } + + if (imp.native && typeof imp.native.request !== 'undefined') { + let requestNative = JSON.parse(imp.native.request); + + // We remove the native asset requirements if we used the bypass to generate the imp + const hasAssetRequirements = requestNative.assets && + (requestNative.assets.length !== 1 || Object.keys(requestNative.assets[0]).length); + if (!hasAssetRequirements) { + delete requestNative.assets; + } + + deepSetValue(imp, 'native.request_native', requestNative); + delete imp.native.request; + } + + return imp; +} + +/** + * Builds a request object for the ORTB 2.5 request. + * + * @param {function} buildRequest - The function for building a request object. + * @param {Array} imps - An array of ORTB 2.5 impression objects. + * @param {Object} bidderRequest - The bidder request object. + * @param {Object} context - The context object. + * @returns {Object} The ORTB 2.5 request object. + */ +function request(buildRequest, imps, bidderRequest, context) { + let request = buildRequest(imps, bidderRequest, context); + + // params.pubid should override publisher id + if (typeof context.publisherId !== 'undefined') { + if (typeof request.app !== 'undefined') { + deepSetValue(request, 'app.publisher.id', context.publisherId); + } else { + deepSetValue(request, 'site.publisher.id', context.publisherId); + } + } + + if (bidderRequest && bidderRequest.gdprConsent) { + deepSetValue(request, 'regs.ext.gdprversion', bidderRequest.gdprConsent.apiVersion); + } + + // Translate 2.6 OpenRTB request into 2.5 OpenRTB request + request = TRANSLATOR(request); + + return request; +} + +/** + * Build bid from oRTB 2.5 bid. + * + * @param buildBidResponse + * @param bid + * @param context + * @returns {*} + */ +function bidResponse(buildBidResponse, bid, context) { + context.mediaType = deepAccess(bid, 'ext.mediatype'); + if (context.mediaType === NATIVE && typeof bid.adm_native !== 'undefined') { + bid.adm = bid.adm_native; + delete bid.adm_native; + } + + let bidResponse = buildBidResponse(bid, context); + const {bidRequest} = context; + + bidResponse.currency = deepAccess(bid, 'ext.cur') + + if (typeof deepAccess(bid, 'ext.meta') !== 'undefined') { + deepSetValue(bidResponse, 'meta', { + ...bidResponse.meta, + ...bid.ext.meta + }); + } + if (typeof deepAccess(bid, 'ext.paf.content_id') !== 'undefined') { + deepSetValue(bidResponse, 'meta.paf.content_id', bid.ext.paf.content_id) + } + + if (bidResponse.mediaType === VIDEO) { + bidResponse.vastUrl = bid.ext?.displayurl; + // if outstream video, add a default render for it. + if (deepAccess(bidRequest, 'mediaTypes.video.context') === OUTSTREAM) { + bidResponse.renderer = createOutstreamVideoRenderer(bid); + } + } + + return bidResponse; +} + +/** + * Builds bid response from the oRTB 2.5 bid response. + * + * @param buildResponse + * @param bidResponses + * @param ortbResponse + * @param context + * @returns * + */ +function response(buildResponse, bidResponses, ortbResponse, context) { + let response = buildResponse(bidResponses, ortbResponse, context); + + const pafTransmission = deepAccess(ortbResponse, 'ext.paf.transmission'); + response.bids.forEach(bid => { + if (typeof pafTransmission !== 'undefined' && typeof deepAccess(bid, 'meta.paf.content_id') !== 'undefined') { + deepSetValue(bid, 'meta.paf.transmission', pafTransmission); + } else { + delete bid.meta.paf; + } + }); + + return response; +} + /** @type {BidderSpec} */ export const spec = { code: BIDDER_CODE, @@ -58,15 +221,10 @@ export const spec = { getUserSyncs: function (syncOptions, _, gdprConsent, uspConsent, gppConsent = {}) { let { gppString = '', applicableSections = [] } = gppConsent; - if (syncOptions.iframeEnabled && hasPurpose1Consent(gdprConsent)) { - const fastBidVersion = config.getConfig('criteo.fastBidVersion'); - if (canFastBid(fastBidVersion)) { - return []; - } - - const refererInfo = getRefererInfo(); - const origin = 'criteoPrebidAdapter'; + const refererInfo = getRefererInfo(); + const origin = 'criteoPrebidAdapter'; + if (syncOptions.iframeEnabled && hasPurpose1Consent(gdprConsent)) { const queryParams = []; queryParams.push(`origin=${origin}`); queryParams.push(`topUrl=${refererInfo.domain}`); @@ -191,50 +349,25 @@ export const spec = { * @return {ServerRequest} */ buildRequests: (bidRequests, bidderRequest) => { - let url; - let data; - let fpd = bidderRequest.ortb2 || {}; - - Object.assign(bidderRequest, { - publisherExt: fpd.site?.ext, - userExt: fpd.user?.ext, - ceh: config.getConfig('criteo.ceh'), - coppa: config.getConfig('coppa') - }); - - // If publisher tag not already loaded try to get it from fast bid - const fastBidVersion = config.getConfig('criteo.fastBidVersion'); - const canLoadPublisherTag = canFastBid(fastBidVersion); - if (!publisherTagAvailable() && canLoadPublisherTag) { - window.Criteo = window.Criteo || {}; - window.Criteo.usePrebidEvents = false; - - tryGetCriteoFastBid(); + bidRequests.forEach(bidRequest => { + if (hasNativeMediaType(bidRequest)) { + if (!checkNativeSendId(bidRequest)) { + logWarn(LOG_PREFIX + 'all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)'); + } - const fastBidUrl = getFastBidUrl(fastBidVersion); - // Reload the PublisherTag after the timeout to ensure FastBid is up-to-date and tracking done properly - setTimeout(() => { - loadExternalScript(fastBidUrl, BIDDER_CODE); - }, bidderRequest.timeout); - } + // We support native request without assets requirements because we can fill them later on. + // This is a trick to fool oRTB converter isOpenRTBBidRequestValid(ortb) fn because it needs + // nativeOrtbRequest.assets to be non-empty. + if (deepAccess(bidRequest, 'nativeOrtbRequest.assets') == null) { + logWarn(LOG_PREFIX + 'native asset requirements are missing'); + deepSetValue(bidRequest, 'nativeOrtbRequest.assets', [{}]); + } + } + }); - if (publisherTagAvailable()) { - // eslint-disable-next-line no-undef - const adapter = new Criteo.PubTag.Adapters.Prebid( - PROFILE_ID_PUBLISHERTAG, - ADAPTER_VERSION, - bidRequests, - bidderRequest, - '$prebid.version$', - { createOutstreamVideoRenderer: createOutstreamVideoRenderer } - ); - url = adapter.buildCdbUrl(); - data = adapter.buildCdbRequest(); - } else { - const context = buildContext(bidRequests, bidderRequest); - url = buildCdbUrl(context); - data = buildCdbRequest(context, bidRequests, bidderRequest); - } + const context = buildContext(bidRequests, bidderRequest); + const url = buildCdbUrl(context); + const data = CONVERTER.toORTB({bidderRequest, bidRequests, context}); if (data) { return { method: 'POST', url, data, bidRequests }; @@ -247,131 +380,24 @@ export const spec = { * @return {Bid[] | {bids: Bid[], fledgeAuctionConfigs: object[]}} */ interpretResponse: (response, request) => { - const body = response.body || response; - - if (publisherTagAvailable()) { - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(request); - if (adapter) { - return adapter.interpretResponse(body, request); - } + if (typeof response?.body == 'undefined') { + return []; // no bid } - const bids = []; - const fledgeAuctionConfigs = []; - - if (body && body.slots && isArray(body.slots)) { - body.slots.forEach(slot => { - const bidRequest = getAssociatedBidRequest(request.bidRequests, slot); - if (bidRequest) { - const bidId = bidRequest.bidId; - const bid = { - requestId: bidId, - cpm: slot.cpm, - currency: slot.currency, - netRevenue: true, - ttl: slot.ttl || 60, - creativeId: slot.creativecode, - width: slot.width, - height: slot.height, - dealId: slot.deal, - }; - if (body.ext?.paf?.transmission && slot.ext?.paf?.content_id) { - const pafResponseMeta = { - content_id: slot.ext.paf.content_id, - transmission: response.ext.paf.transmission - }; - bid.meta = Object.assign({}, bid.meta, { paf: pafResponseMeta }); - } - if (slot.adomain) { - bid.meta = Object.assign({}, bid.meta, { advertiserDomains: [slot.adomain].flat() }); - } - if (slot.ext?.meta?.networkName) { - bid.meta = Object.assign({}, bid.meta, { networkName: slot.ext.meta.networkName }) - } - if (slot.ext?.dsa) { - bid.meta = Object.assign({}, bid.meta, { dsa: slot.ext.dsa }) - } - if (slot.native) { - if (bidRequest.params.nativeCallback) { - bid.ad = createNativeAd(bidId, slot.native, bidRequest.params.nativeCallback); - } else { - bid.native = createPrebidNativeAd(slot.native); - bid.mediaType = NATIVE; - } - } else if (slot.video) { - bid.vastUrl = slot.displayurl; - bid.mediaType = VIDEO; - const context = deepAccess(bidRequest, 'mediaTypes.video.context'); - // if outstream video, add a default render for it. - if (context === OUTSTREAM) { - bid.renderer = createOutstreamVideoRenderer(slot); - } - } else { - bid.ad = slot.creative; - } - bids.push(bid); - } - }); - } + const interpretedResponse = CONVERTER.fromORTB({response: response.body, request: request.data}); + const bids = interpretedResponse.bids || []; - if (isArray(body.ext?.igi)) { - body.ext.igi.forEach((igi) => { - if (isArray(igi?.igs)) { - igi.igs.forEach((igs) => { - fledgeAuctionConfigs.push(igs); - }); - } - }); - } - - if (fledgeAuctionConfigs.length) { + const fledgeAuctionConfigs = deepAccess(response.body, 'ext.igi')?.filter(igi => isArray(igi?.igs)) + .flatMap(igi => igi.igs); + if (fledgeAuctionConfigs?.length) { return { bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, }; } return bids; }, - /** - * @param {TimedOutBid} timeoutData - */ - onTimeout: (timeoutData) => { - if (publisherTagAvailable() && Array.isArray(timeoutData)) { - var auctionsIds = []; - timeoutData.forEach((bid) => { - if (auctionsIds.indexOf(bid.auctionId) === -1) { - auctionsIds.push(bid.auctionId); - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId); - adapter.handleBidTimeout(); - } - }); - } - }, - - /** - * @param {Bid} bid - */ - onBidWon: (bid) => { - if (publisherTagAvailable() && bid) { - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId); - adapter.handleBidWon(bid); - } - }, - - /** - * @param {Bid} bid - */ - onSetTargeting: (bid) => { - if (publisherTagAvailable()) { - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId); - adapter.handleSetTargeting(bid); - } - }, /** * @param {BidRequest[]} bidRequests @@ -412,43 +438,26 @@ function deleteFromAllStorages(name) { storage.removeDataFromLocalStorage(name); } -/** - * @return {boolean} - */ -function publisherTagAvailable() { - // eslint-disable-next-line no-undef - return typeof Criteo !== 'undefined' && Criteo.PubTag && Criteo.PubTag.Adapters && Criteo.PubTag.Adapters.Prebid; -} - /** * @param {BidRequest[]} bidRequests * @param bidderRequest */ function buildContext(bidRequests, bidderRequest) { - let referrer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.page; - } const queryString = parseUrl(bidderRequest?.refererInfo?.topmostLocation).search; - const context = { - url: referrer, + return { + url: bidderRequest?.refererInfo?.page || '', debug: queryString['pbt_debug'] === '1', noLog: queryString['pbt_nolog'] === '1', - amp: false, + fledgeEnabled: bidderRequest.paapi?.enabled, + amp: bidRequests.some(bidRequest => bidRequest.params.integrationMode === 'amp'), + networkId: bidRequests.find(bidRequest => bidRequest.params?.networkId)?.params.networkId, + publisherId: bidRequests.find(bidRequest => bidRequest.params?.pubid)?.params.pubid, }; - - bidRequests.forEach(bidRequest => { - if (bidRequest.params.integrationMode === 'amp') { - context.amp = true; - } - }); - - return context; } /** - * @param {CriteoContext} context + * @param {Object} context * @return {string} */ function buildCdbUrl(context) { @@ -484,6 +493,10 @@ function buildCdbUrl(context) { url += `&optout=1`; } + if (context.networkId) { + url += `&networkId=` + context.networkId; + } + return url; } @@ -499,185 +512,6 @@ function checkNativeSendId(bidRequest) { )); } -/** - * @param {CriteoContext} context - * @param {BidRequest[]} bidRequests - * @param bidderRequest - * @return {*} - */ -function buildCdbRequest(context, bidRequests, bidderRequest) { - let networkId; - let pubid; - let schain; - let userIdAsEids; - let regs = Object.assign({}, { - coppa: bidderRequest.coppa === true ? 1 : (bidderRequest.coppa === false ? 0 : undefined) - }, bidderRequest.ortb2?.regs); - const request = { - id: generateUUID(), - publisher: { - url: context.url, - ext: bidderRequest.publisherExt, - }, - regs: regs, - slots: bidRequests.map(bidRequest => { - if (!userIdAsEids) { - userIdAsEids = bidRequest.userIdAsEids; - } - networkId = bidRequest.params.networkId || networkId; - pubid = bidRequest.params.pubid || pubid; - schain = bidRequest.schain || schain; - const slot = { - slotid: bidRequest.bidId, - impid: bidRequest.adUnitCode, - transactionid: bidRequest.ortb2Imp?.ext?.tid - }; - if (bidRequest.params.zoneId) { - slot.zoneid = bidRequest.params.zoneId; - } - if (deepAccess(bidRequest, 'ortb2Imp.ext')) { - slot.ext = bidRequest.ortb2Imp.ext; - } - - if (deepAccess(bidRequest, 'ortb2Imp.rwdd')) { - slot.rwdd = bidRequest.ortb2Imp.rwdd; - } - - if (bidRequest.params.ext) { - slot.ext = Object.assign({}, slot.ext, bidRequest.params.ext); - } - if (bidRequest.nativeOrtbRequest?.assets) { - slot.ext = Object.assign({}, slot.ext, { assets: bidRequest.nativeOrtbRequest.assets }); - } - if (bidRequest.params.uid) { - slot.ext = Object.assign({}, slot.ext, { bidder: { uid: bidRequest.params.uid } }); - } - - if (bidRequest.params.publisherSubId) { - slot.publishersubid = bidRequest.params.publisherSubId; - } - - if (bidRequest.params.nativeCallback || hasNativeMediaType(bidRequest)) { - slot.native = true; - if (!checkNativeSendId(bidRequest)) { - logWarn(LOG_PREFIX + 'all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)'); - } - } - - if (hasBannerMediaType(bidRequest)) { - slot.sizes = parseSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes'), parseSize); - } else { - slot.sizes = []; - } - - if (hasVideoMediaType(bidRequest)) { - const video = { - context: bidRequest.mediaTypes.video.context, - playersizes: parseSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize'), parseSize), - mimes: bidRequest.mediaTypes.video.mimes, - protocols: bidRequest.mediaTypes.video.protocols, - maxduration: bidRequest.mediaTypes.video.maxduration, - api: bidRequest.mediaTypes.video.api, - skip: bidRequest.mediaTypes.video.skip, - placement: bidRequest.mediaTypes.video.placement, - minduration: bidRequest.mediaTypes.video.minduration, - playbackmethod: bidRequest.mediaTypes.video.playbackmethod, - startdelay: bidRequest.mediaTypes.video.startdelay, - plcmt: bidRequest.mediaTypes.video.plcmt, - w: bidRequest.mediaTypes.video.w, - h: bidRequest.mediaTypes.video.h, - linearity: bidRequest.mediaTypes.video.linearity, - skipmin: bidRequest.mediaTypes.video.skipmin, - skipafter: bidRequest.mediaTypes.video.skipafter, - minbitrate: bidRequest.mediaTypes.video.minbitrate, - maxbitrate: bidRequest.mediaTypes.video.maxbitrate, - delivery: bidRequest.mediaTypes.video.delivery, - pos: bidRequest.mediaTypes.video.pos, - playbackend: bidRequest.mediaTypes.video.playbackend, - adPodDurationSec: bidRequest.mediaTypes.video.adPodDurationSec, - durationRangeSec: bidRequest.mediaTypes.video.durationRangeSec, - }; - const paramsVideo = bidRequest.params.video; - if (paramsVideo !== undefined) { - video.skip = video.skip || paramsVideo.skip || 0; - video.placement = video.placement || paramsVideo.placement; - video.minduration = video.minduration || paramsVideo.minduration; - video.playbackmethod = video.playbackmethod || paramsVideo.playbackmethod; - video.startdelay = video.startdelay || paramsVideo.startdelay || 0; - } - - slot.video = video; - } - - enrichSlotWithFloors(slot, bidRequest); - - if (!bidderRequest.fledgeEnabled && slot.ext?.ae) { - delete slot.ext.ae; - } - - return slot; - }), - }; - if (networkId) { - request.publisher.networkid = networkId; - } - - request.source = { - tid: bidderRequest.ortb2?.source?.tid - }; - - if (schain) { - request.source.ext = { - schain: schain - }; - }; - request.user = bidderRequest.ortb2?.user || {}; - request.site = bidderRequest.ortb2?.site || {}; - request.app = bidderRequest.ortb2?.app || {}; - - if (pubid) { - request.site.publisher = {...request.site.publisher, ...{ id: pubid }}; - request.app.publisher = {...request.app.publisher, ...{ id: pubid }}; - } - - request.device = bidderRequest.ortb2?.device || {}; - if (bidderRequest && bidderRequest.ceh) { - request.user.ceh = bidderRequest.ceh; - } - if (bidderRequest && bidderRequest.gdprConsent) { - request.gdprConsent = {}; - if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { - request.gdprConsent.gdprApplies = !!(bidderRequest.gdprConsent.gdprApplies); - } - request.gdprConsent.version = bidderRequest.gdprConsent.apiVersion; - if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') { - request.gdprConsent.consentData = bidderRequest.gdprConsent.consentString; - } - } - if (bidderRequest && bidderRequest.uspConsent) { - request.user.uspIab = bidderRequest.uspConsent; - } - if (bidderRequest && bidderRequest.ortb2?.device?.sua) { - request.user.ext = request.user.ext || {}; - request.user.ext.sua = bidderRequest.ortb2?.device?.sua || {}; - } - if (userIdAsEids) { - request.user.ext = request.user.ext || {}; - request.user.ext.eids = [...userIdAsEids]; - } - if (bidderRequest && bidderRequest.ortb2?.bcat) { - request.bcat = bidderRequest.ortb2.bcat; - } - if (bidderRequest && bidderRequest.ortb2?.badv) { - request.badv = bidderRequest.ortb2.badv; - } - if (bidderRequest && bidderRequest.ortb2?.bapp) { - request.bapp = bidderRequest.ortb2.bapp; - } - request.tmax = bidderRequest.timeout; - return request; -} - function parseSizes(sizes, parser = s => s) { if (sizes == undefined) { return []; @@ -696,10 +530,6 @@ function hasVideoMediaType(bidRequest) { return deepAccess(bidRequest, 'mediaTypes.video') !== undefined; } -function hasBannerMediaType(bidRequest) { - return deepAccess(bidRequest, 'mediaTypes.banner') !== undefined; -} - function hasNativeMediaType(bidRequest) { return deepAccess(bidRequest, 'mediaTypes.native') !== undefined; } @@ -710,63 +540,22 @@ function hasValidVideoMediaType(bidRequest) { var requiredMediaTypesParams = ['mimes', 'playerSize', 'maxduration', 'protocols', 'api', 'skip', 'placement', 'playbackmethod']; requiredMediaTypesParams.forEach(function (param) { - if (deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined && deepAccess(bidRequest, 'params.video.' + param) === undefined) { - isValid = false; - logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' is required'); + if (param === 'placement') { + if (deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined && deepAccess(bidRequest, 'params.video.' + param) === undefined && deepAccess(bidRequest, 'mediaTypes.video.plcmt') === undefined && deepAccess(bidRequest, 'params.video.plcmt') === undefined) { + isValid = false; + logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' or mediaTypes.video.plcmt is required'); + } + } else { + if (deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined && deepAccess(bidRequest, 'params.video.' + param) === undefined) { + isValid = false; + logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' is required'); + } } }); return isValid; } -/** - * Create prebid compatible native ad with native payload - * @param {*} payload - * @returns prebid native ad assets - */ -function createPrebidNativeAd(payload) { - return { - sendTargetingKeys: false, // no key is added to KV by default - title: payload.products[0].title, - body: payload.products[0].description, - sponsoredBy: payload.advertiser.description, - icon: payload.advertiser.logo, - image: payload.products[0].image, - clickUrl: payload.products[0].click_url, - privacyLink: payload.privacy.optout_click_url, - privacyIcon: payload.privacy.optout_image_url, - cta: payload.products[0].call_to_action, - price: payload.products[0].price, - impressionTrackers: payload.impression_pixels.map(pix => pix.url) - }; -} - -/** - * @param {string} id - * @param {*} payload - * @param {*} callback - * @return {string} - */ -function createNativeAd(id, payload, callback) { - // Store the callback and payload in a global object to be later accessed from the creative - var slotsName = 'criteo_prebid_native_slots'; - window[slotsName] = window[slotsName] || {}; - window[slotsName][id] = { callback, payload }; - - // The creative is in an iframe so we have to get the callback and payload - // from the parent window (doesn't work with safeframes) - return ` -`; -} - function pickAvailableGetFloorFunc(bidRequest) { if (bidRequest.getFloor) { return bidRequest.getFloor; @@ -785,87 +574,58 @@ function pickAvailableGetFloorFunc(bidRequest) { return undefined; } -function enrichSlotWithFloors(slot, bidRequest) { +function getFloors(bidRequest) { try { - const slotFloors = {}; + const floors = {}; const getFloor = pickAvailableGetFloorFunc(bidRequest); if (getFloor) { if (bidRequest.mediaTypes?.banner) { - slotFloors.banner = {}; + floors.banner = {}; const bannerSizes = parseSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes')) - bannerSizes.forEach(bannerSize => slotFloors.banner[parseSize(bannerSize).toString()] = getFloor.call(bidRequest, { size: bannerSize, mediaType: BANNER })); + bannerSizes.forEach(bannerSize => floors.banner[parseSize(bannerSize).toString()] = getFloor.call(bidRequest, { size: bannerSize, mediaType: BANNER })); } if (bidRequest.mediaTypes?.video) { - slotFloors.video = {}; + floors.video = {}; const videoSizes = parseSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize')) - videoSizes.forEach(videoSize => slotFloors.video[parseSize(videoSize).toString()] = getFloor.call(bidRequest, { size: videoSize, mediaType: VIDEO })); + videoSizes.forEach(videoSize => floors.video[parseSize(videoSize).toString()] = getFloor.call(bidRequest, { size: videoSize, mediaType: VIDEO })); } if (bidRequest.mediaTypes?.native) { - slotFloors.native = {}; - slotFloors.native['*'] = getFloor.call(bidRequest, { size: '*', mediaType: NATIVE }); + floors.native = {}; + floors.native['*'] = getFloor.call(bidRequest, { size: '*', mediaType: NATIVE }); } - if (Object.keys(slotFloors).length > 0) { - if (!slot.ext) { - slot.ext = {} - } - Object.assign(slot.ext, { - floors: slotFloors - }); - } + return floors; } } catch (e) { logError('Could not parse floors from Prebid: ' + e); } } -export function canFastBid(fastBidVersion) { - return fastBidVersion !== FAST_BID_VERSION_NONE; -} - -export function getFastBidUrl(fastBidVersion) { - let version; - if (fastBidVersion === FAST_BID_VERSION_LATEST) { - version = ''; - } else if (fastBidVersion) { - let majorVersion = String(fastBidVersion).split('.')[0]; - if (majorVersion < 102) { - logWarn('Specifying a Fastbid version which is not supporting version selection.') - } - version = '.' + fastBidVersion; - } else { - version = '.' + FAST_BID_VERSION_CURRENT; - } - - return PUBLISHER_TAG_URL_TEMPLATE.replace(FAST_BID_VERSION_PLACEHOLDER, version); -} - -function createOutstreamVideoRenderer(slot) { - if (slot.ext.videoPlayerConfig === undefined || slot.ext.videoPlayerType === undefined) { +function createOutstreamVideoRenderer(bid) { + if (bid.ext?.videoPlayerConfig === undefined || bid.ext?.videoPlayerType === undefined) { return undefined; } const config = { - documentResolver: (bid, sourceDocument, renderDocument) => { + documentResolver: (_, sourceDocument, renderDocument) => { return renderDocument ?? sourceDocument; } } - const render = (bid, renderDocument) => { + const render = (_, renderDocument) => { let payload = { - slotid: slot.impid, - vastUrl: slot.displayurl, - vastXml: slot.creative, + slotid: bid.id, + vastUrl: bid.ext?.displayurl, + vastXml: bid.adm, documentContext: renderDocument, }; - let outstreamConfig = slot.ext.videoPlayerConfig; - - window.CriteoOutStream[slot.ext.videoPlayerType].play(payload, outstreamConfig) + let outstreamConfig = bid.ext.videoPlayerConfig; + window.CriteoOutStream[bid.ext.videoPlayerType].play(payload, outstreamConfig) }; const renderer = Renderer.install({ url: PUBLISHER_TAG_OUTSTREAM_SRC, config: config }); @@ -873,60 +633,4 @@ function createOutstreamVideoRenderer(slot) { return renderer; } -function getAssociatedBidRequest(bidRequests, slot) { - for (const request of bidRequests) { - if (request.adUnitCode === slot.impid) { - if (request.params.zoneId && parseInt(request.params.zoneId) === slot.zoneid) { - return request; - } else if (slot.native) { - if (request.mediaTypes?.native || request.nativeParams) { - return request; - } - } else if (slot.video) { - if (request.mediaTypes?.video) { - return request; - } - } else if (request.mediaTypes?.banner || request.sizes) { - return request; - } - } - } - return undefined; -} - -export function tryGetCriteoFastBid() { - // begin ref#1 - try { - const fastBidStorageKey = 'criteo_fast_bid'; - const hashPrefix = '// Hash: '; - const fastBidFromStorage = storage.getDataFromLocalStorage(fastBidStorageKey); - - if (fastBidFromStorage !== null) { - // The value stored must contain the file's encrypted hash as first line - const firstLineEndPosition = fastBidFromStorage.indexOf('\n'); - const firstLine = fastBidFromStorage.substr(0, firstLineEndPosition).trim(); - - if (firstLine.substr(0, hashPrefix.length) !== hashPrefix) { - logWarn('No hash found in FastBid'); - storage.removeDataFromLocalStorage(fastBidStorageKey); - } else { - // Remove the hash part from the locally stored value - const publisherTagHash = firstLine.substr(hashPrefix.length); - const publisherTag = fastBidFromStorage.substr(firstLineEndPosition + 1); - - if (verify(publisherTag, publisherTagHash, FAST_BID_PUBKEY_N, FAST_BID_PUBKEY_E)) { - logInfo('Using Criteo FastBid'); - eval(publisherTag); // eslint-disable-line no-eval - } else { - logWarn('Invalid Criteo FastBid found'); - storage.removeDataFromLocalStorage(fastBidStorageKey); - } - } - } - } catch (e) { - // Unable to get fast bid - } - // end ref#1 -} - registerBidder(spec); diff --git a/modules/cwireBidAdapter.js b/modules/cwireBidAdapter.js index f878be5f66a..191ff7758da 100644 --- a/modules/cwireBidAdapter.js +++ b/modules/cwireBidAdapter.js @@ -2,7 +2,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getStorageManager} from '../src/storageManager.js'; import {BANNER} from '../src/mediaTypes.js'; import {generateUUID, getParameterByName, isNumber, logError, logInfo} from '../src/utils.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -224,6 +224,8 @@ export const spec = { bid: bid } } + // TODO FIX THIS RULES VIOLATION + // eslint-disable-next-line prebid/no-member navigator.sendBeacon(EVENT_ENDPOINT, JSON.stringify(event)) }, @@ -236,6 +238,8 @@ export const spec = { bidderRequest: bidderRequest } } + // TODO FIX THIS RULES VIOLATION + // eslint-disable-next-line prebid/no-member navigator.sendBeacon(EVENT_ENDPOINT, JSON.stringify(event)) }, diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index bf8eaaebb55..4f8f73816fe 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -67,7 +67,7 @@ function getVideoMetadata(bidRequest, bidderRequest) { ? videoParams.isCreatedForKids : null, context: { - siteOrAppCat: deepAccess(contentObj, 'cat', ''), + siteOrAppCat: deepAccess(contentObj, 'cat', []), videoViewsInSession: ( typeof videoParams.videoViewsInSession === 'number' && videoParams.videoViewsInSession >= 0 @@ -130,76 +130,96 @@ export const spec = { * @param {BidderRequest} bidderRequest * @return ServerRequest Info describing the request to the server. */ - buildRequests: (validBidRequests = [], bidderRequest) => validBidRequests.map(bid => ({ - method: 'POST', - url: 'https://pb.dmxleo.com', - data: { - pbv: '$prebid.version$', - bidder_request: { - gdprConsent: { - apiVersion: deepAccess(bidderRequest, 'gdprConsent.apiVersion', 1), - consentString: deepAccess(bidderRequest, 'gdprConsent.consentString', ''), - // Cast boolean in any case (eg: if value is int) to ensure type - gdprApplies: !!deepAccess(bidderRequest, 'gdprConsent.gdprApplies'), - }, - refererInfo: { - page: deepAccess(bidderRequest, 'refererInfo.page', ''), + buildRequests: function(validBidRequests = [], bidderRequest) { + // check consent to be able to read user cookie + const allowCookieReading = + // No GDPR applies + !deepAccess(bidderRequest, 'gdprConsent.gdprApplies') || + // OR GDPR applies and we have global consent + deepAccess(bidderRequest, 'gdprConsent.vendorData.hasGlobalConsent') === true || + ( + // Vendor consent + deepAccess(bidderRequest, 'gdprConsent.vendorData.vendor.consents.573') === true && + // Purposes + [1, 3, 4].every(v => deepAccess(bidderRequest, `gdprConsent.vendorData.purpose.consents.${v}`) === true) && + // Flexible purposes + [2, 7, 9, 10].every(v => + deepAccess(bidderRequest, `gdprConsent.vendorData.purpose.consents.${v}`) === true || + deepAccess(bidderRequest, `gdprConsent.vendorData.purpose.legitimateInterests.${v}`) === true + ) + ); + + return validBidRequests.map(bid => ({ + method: 'POST', + url: 'https://pb.dmxleo.com', + data: { + pbv: '$prebid.version$', + bidder_request: { + gdprConsent: { + apiVersion: deepAccess(bidderRequest, 'gdprConsent.apiVersion', 1), + consentString: deepAccess(bidderRequest, 'gdprConsent.consentString', ''), + // Cast boolean in any case (eg: if value is int) to ensure type + gdprApplies: !!deepAccess(bidderRequest, 'gdprConsent.gdprApplies'), + }, + refererInfo: { + page: deepAccess(bidderRequest, 'refererInfo.page', ''), + }, + uspConsent: deepAccess(bidderRequest, 'uspConsent', ''), + gppConsent: { + gppString: deepAccess(bidderRequest, 'gppConsent.gppString') || + deepAccess(bidderRequest, 'ortb2.regs.gpp', ''), + applicableSections: deepAccess(bidderRequest, 'gppConsent.applicableSections') || + deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', []), + }, }, - uspConsent: deepAccess(bidderRequest, 'uspConsent', ''), - gppConsent: { - gppString: deepAccess(bidderRequest, 'gppConsent.gppString') || - deepAccess(bidderRequest, 'ortb2.regs.gpp', ''), - applicableSections: deepAccess(bidderRequest, 'gppConsent.applicableSections') || - deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', []), + config: { + api_key: bid.params.apiKey }, - }, - config: { - api_key: bid.params.apiKey - }, - // Cast boolean in any case (value should be 0 or 1) to ensure type - coppa: !!deepAccess(bidderRequest, 'ortb2.regs.coppa'), - // In app context, we need to retrieve additional informations - ...(!deepAccess(bidderRequest, 'ortb2.site') && !!deepAccess(bidderRequest, 'ortb2.app') ? { - appBundle: deepAccess(bidderRequest, 'ortb2.app.bundle', ''), - appStoreUrl: deepAccess(bidderRequest, 'ortb2.app.storeurl', ''), - } : {}), - ...(deepAccess(bidderRequest, 'ortb2.device') ? { - device: { - lmt: deepAccess(bidderRequest, 'ortb2.device.lmt', null), - ifa: deepAccess(bidderRequest, 'ortb2.device.ifa', ''), - atts: deepAccess(bidderRequest, 'ortb2.device.ext.atts', 0), - }, - } : {}), - request: { - adUnitCode: deepAccess(bid, 'adUnitCode', ''), - auctionId: deepAccess(bid, 'auctionId', ''), - bidId: deepAccess(bid, 'bidId', ''), - mediaTypes: { - video: { - api: bid.mediaTypes?.[VIDEO]?.api || [], - mimes: bid.mediaTypes?.[VIDEO]?.mimes || [], - minduration: bid.mediaTypes?.[VIDEO]?.minduration || 0, - maxduration: bid.mediaTypes?.[VIDEO]?.maxduration || 0, - playbackmethod: bid.mediaTypes?.[VIDEO]?.playbackmethod || [], - plcmt: bid.mediaTypes?.[VIDEO]?.plcmt || 1, // Fallback to instream considering logic of `isBidRequestValid` - protocols: bid.mediaTypes?.[VIDEO]?.protocols || [], - skip: bid.mediaTypes?.[VIDEO]?.skip || 0, - skipafter: bid.mediaTypes?.[VIDEO]?.skipafter || 0, - skipmin: bid.mediaTypes?.[VIDEO]?.skipmin || 0, - startdelay: bid.mediaTypes?.[VIDEO]?.startdelay || 0, - w: bid.mediaTypes?.[VIDEO]?.w || 0, - h: bid.mediaTypes?.[VIDEO]?.h || 0, + // Cast boolean in any case (value should be 0 or 1) to ensure type + coppa: !!deepAccess(bidderRequest, 'ortb2.regs.coppa'), + // In app context, we need to retrieve additional informations + ...(!deepAccess(bidderRequest, 'ortb2.site') && !!deepAccess(bidderRequest, 'ortb2.app') ? { + appBundle: deepAccess(bidderRequest, 'ortb2.app.bundle', ''), + appStoreUrl: deepAccess(bidderRequest, 'ortb2.app.storeurl', ''), + } : {}), + ...(deepAccess(bidderRequest, 'ortb2.device') ? { + device: { + lmt: deepAccess(bidderRequest, 'ortb2.device.lmt', null), + ifa: deepAccess(bidderRequest, 'ortb2.device.ifa', ''), + atts: deepAccess(bidderRequest, 'ortb2.device.ext.atts', 0), + }, + } : {}), + request: { + adUnitCode: deepAccess(bid, 'adUnitCode', ''), + auctionId: deepAccess(bid, 'auctionId', ''), + bidId: deepAccess(bid, 'bidId', ''), + mediaTypes: { + video: { + api: bid.mediaTypes?.[VIDEO]?.api || [], + mimes: bid.mediaTypes?.[VIDEO]?.mimes || [], + minduration: bid.mediaTypes?.[VIDEO]?.minduration || 0, + maxduration: bid.mediaTypes?.[VIDEO]?.maxduration || 0, + playbackmethod: bid.mediaTypes?.[VIDEO]?.playbackmethod || [], + plcmt: bid.mediaTypes?.[VIDEO]?.plcmt, + protocols: bid.mediaTypes?.[VIDEO]?.protocols || [], + skip: bid.mediaTypes?.[VIDEO]?.skip || 0, + skipafter: bid.mediaTypes?.[VIDEO]?.skipafter || 0, + skipmin: bid.mediaTypes?.[VIDEO]?.skipmin || 0, + startdelay: bid.mediaTypes?.[VIDEO]?.startdelay, + w: bid.mediaTypes?.[VIDEO]?.w || 0, + h: bid.mediaTypes?.[VIDEO]?.h || 0, + }, }, + sizes: bid.sizes || [], }, - sizes: bid.sizes || [], + video_metadata: getVideoMetadata(bid, bidderRequest), }, - video_metadata: getVideoMetadata(bid, bidderRequest), - }, - options: { - withCredentials: true, - crossOrigin: true, - }, - })), + options: { + withCredentials: allowCookieReading, + crossOrigin: true, + }, + })); + }, /** * Map the response from the server into a list of bids. @@ -224,7 +244,7 @@ export const spec = { const pixelSyncs = []; serverResponses.forEach((response) => { - (response.user_syncs || []).forEach((syncUrl) => { + (response?.body?.userSyncs || []).forEach((syncUrl) => { if (syncUrl.type === 'image') { pixelSyncs.push({ url: syncUrl.url, type: 'image' }); } diff --git a/modules/debugging/bidInterceptor.js b/modules/debugging/bidInterceptor.js index 67b24b3f222..102d1723eec 100644 --- a/modules/debugging/bidInterceptor.js +++ b/modules/debugging/bidInterceptor.js @@ -1,9 +1,9 @@ import { deepAccess, deepClone, - deepEqual, delayExecution, - mergeDeep + mergeDeep, + hasNonSerializableProperty } from '../../src/utils.js'; /** @@ -22,9 +22,9 @@ Object.assign(BidInterceptor.prototype, { }, serializeConfig(ruleDefs) { const isSerializable = (ruleDef, i) => { - const serializable = deepEqual(ruleDef, JSON.parse(JSON.stringify(ruleDef)), {checkTypes: true}); + const serializable = !hasNonSerializableProperty(ruleDef); if (!serializable && !deepAccess(ruleDef, 'options.suppressWarnings')) { - this.logger.logWarn(`Bid interceptor rule definition #${i + 1} is not serializable and will be lost after a refresh. Rule definition: `, ruleDef); + this.logger.logWarn(`Bid interceptor rule definition #${i + 1} contains non-serializable properties and will be lost after a refresh. Rule definition: `, ruleDef); } return serializable; } diff --git a/modules/debugging/debugging.js b/modules/debugging/debugging.js index 63887074f04..ced8f7bf4a0 100644 --- a/modules/debugging/debugging.js +++ b/modules/debugging/debugging.js @@ -31,6 +31,7 @@ export function disableDebugging({hook, logger}) { } } +// eslint-disable-next-line prebid/no-global function saveDebuggingConfig(debugConfig, {sessionStorage = window.sessionStorage, DEBUG_KEY} = {}) { if (!debugConfig.enabled) { try { @@ -49,6 +50,7 @@ function saveDebuggingConfig(debugConfig, {sessionStorage = window.sessionStorag } } +// eslint-disable-next-line prebid/no-global export function getConfig(debugging, {getStorage = () => window.sessionStorage, DEBUG_KEY, config, hook, logger} = {}) { if (debugging == null) return; let sessionStorage; @@ -70,6 +72,7 @@ export function getConfig(debugging, {getStorage = () => window.sessionStorage, export function sessionLoader({DEBUG_KEY, storage, config, hook, logger}) { let overrides; try { + // eslint-disable-next-line prebid/no-global storage = storage || window.sessionStorage; overrides = JSON.parse(storage.getItem(DEBUG_KEY)); } catch (e) { diff --git a/modules/deltaprojectsBidAdapter.js b/modules/deltaprojectsBidAdapter.js index 870378a13dd..15e94a5bc36 100644 --- a/modules/deltaprojectsBidAdapter.js +++ b/modules/deltaprojectsBidAdapter.js @@ -8,7 +8,8 @@ import { isFn, isNumber, logError, - logWarn + logWarn, + setOnAny } from '../src/utils.js'; import {config} from '../src/config.js'; @@ -234,16 +235,6 @@ export function getBidFloor(bid, mediaType, size, currency) { } } -/** -- Helper methods -- */ -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - /** -- Register -- */ export const spec = { code: BIDDER_CODE, diff --git a/modules/dfpAdServerVideo.js b/modules/dfpAdServerVideo.js index 6314ed15ff9..367520870e3 100644 --- a/modules/dfpAdServerVideo.js +++ b/modules/dfpAdServerVideo.js @@ -2,29 +2,28 @@ * This module adds [DFP support]{@link https://www.doubleclickbygoogle.com/} for Video to Prebid. */ -import {registerVideoSupport} from '../src/adServerManager.js'; -import {targeting} from '../src/targeting.js'; +import { DEFAULT_DFP_PARAMS, DFP_ENDPOINT, setGdprConsent } from '../libraries/dfpUtils/dfpUtils.js'; +import { getSignals } from '../libraries/gptUtils/gptUtils.js'; +import { registerVideoSupport } from '../src/adServerManager.js'; +import { gdprDataHandler } from '../src/adapterManager.js'; +import { getPPID } from '../src/adserver.js'; +import { auctionManager } from '../src/auctionManager.js'; +import { config } from '../src/config.js'; +import { EVENTS } from '../src/constants.js'; +import * as events from '../src/events.js'; +import { getHook } from '../src/hook.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { targeting } from '../src/targeting.js'; import { - isNumber, buildUrl, deepAccess, formatQS, isEmpty, + isNumber, logError, parseSizesInput, - parseUrl, - uniques + parseUrl } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {getHook, submodule} from '../src/hook.js'; -import {auctionManager} from '../src/auctionManager.js'; -import {gdprDataHandler} from '../src/adapterManager.js'; -import * as events from '../src/events.js'; -import { EVENTS } from '../src/constants.js'; -import {getPPID} from '../src/adserver.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {CLIENT_SECTIONS} from '../src/fpd/oneClient.js'; - /** * @typedef {Object} DfpVideoParams * @@ -54,16 +53,6 @@ import {CLIENT_SECTIONS} from '../src/fpd/oneClient.js'; * @param {string} [url] video adserver url */ -/** Safe defaults which work on pretty much all video calls. */ -const defaultParamConstants = { - env: 'vp', - gdfp_req: 1, - output: 'vast', - unviewed_position_start: 1, -}; - -export const adpodUtils = {}; - export const dep = { ri: getRefererInfo } @@ -115,7 +104,7 @@ export function buildDfpVideoUrl(options) { let encodedCustomParams = getCustParams(bid, options, urlSearchComponent && urlSearchComponent.cust_params); const queryParams = Object.assign({}, - defaultParamConstants, + DEFAULT_DFP_PARAMS, urlComponents.search, derivedParams, options.params, @@ -125,11 +114,7 @@ export function buildDfpVideoUrl(options) { const descriptionUrl = getDescriptionUrl(bid, options, 'params'); if (descriptionUrl) { queryParams.description_url = descriptionUrl; } const gdprConsent = gdprDataHandler.getConsentData(); - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies === 'boolean') { queryParams.gdpr = Number(gdprConsent.gdprApplies); } - if (gdprConsent.consentString) { queryParams.gdpr_consent = gdprConsent.consentString; } - if (gdprConsent.addtlConsent) { queryParams.addtl_consent = gdprConsent.addtlConsent; } - } + setGdprConsent(gdprConsent, queryParams); if (!queryParams.ppid) { const ppid = getPPID(); @@ -181,20 +166,7 @@ export function buildDfpVideoUrl(options) { const fpd = auctionManager.index.getBidRequest(options.bid || {})?.ortb2 ?? auctionManager.index.getAuction(options.bid || {})?.getFPD()?.global; - function getSegments(sections, segtax) { - return sections - .flatMap(section => deepAccess(fpd, section) || []) - .filter(datum => datum.ext?.segtax === segtax) - .flatMap(datum => datum.segment?.map(seg => seg.id)) - .filter(ob => ob) - .filter(uniques) - } - - const signals = Object.entries({ - IAB_AUDIENCE_1_1: getSegments(['user.data'], 4), - IAB_CONTENT_2_2: getSegments(CLIENT_SECTIONS.map(section => `${section}.content.data`), 6) - }).map(([taxonomy, values]) => values.length ? {taxonomy, values} : null) - .filter(ob => ob); + const signals = getSignals(fpd); if (signals.length) { queryParams.ppsj = btoa(JSON.stringify({ @@ -202,11 +174,7 @@ export function buildDfpVideoUrl(options) { })) } - return buildUrl(Object.assign({ - protocol: 'https', - host: 'securepubads.g.doubleclick.net', - pathname: '/gampad/ads' - }, urlComponents, { search: queryParams })); + return buildUrl(Object.assign({}, DFP_ENDPOINT, urlComponents, { search: queryParams })); } export function notifyTranslationModule(fn) { @@ -215,95 +183,6 @@ export function notifyTranslationModule(fn) { if (config.getConfig('brandCategoryTranslation.translationFile')) { getHook('registerAdserver').before(notifyTranslationModule); } -/** - * @typedef {Object} DfpAdpodOptions - * - * @param {string} code Ad Unit code - * @param {Object} params Query params which should be set on the DFP request. - * These will override this module's defaults whenever they conflict. - * @param {function} callback Callback function to execute when master tag is ready - */ - -/** - * Creates master tag url for long-form - * @param {DfpAdpodOptions} options - * @returns {string} A URL which calls DFP with custom adpod targeting key values to compete with rest of the demand in DFP - */ -export function buildAdpodVideoUrl({code, params, callback} = {}) { - // TODO: the public API for this does not take in enough info to fill all DFP params (adUnit/bid), - // and is marked "alpha": https://docs.prebid.org/dev-docs/publisher-api-reference/adServers.dfp.buildAdpodVideoUrl.html - if (!params || !callback) { - logError(`A params object and a callback is required to use pbjs.adServers.dfp.buildAdpodVideoUrl`); - return; - } - - const derivedParams = { - correlator: Date.now(), - sz: getSizeForAdUnit(code), - url: encodeURIComponent(location.href), - }; - - function getSizeForAdUnit(code) { - let adUnit = auctionManager.getAdUnits() - .filter((adUnit) => adUnit.code === code) - let sizes = deepAccess(adUnit[0], 'mediaTypes.video.playerSize'); - return parseSizesInput(sizes).join('|'); - } - - adpodUtils.getTargeting({ - 'codes': [code], - 'callback': createMasterTag - }); - - function createMasterTag(err, targeting) { - if (err) { - callback(err, null); - return; - } - - let initialValue = { - [adpodUtils.TARGETING_KEY_PB_CAT_DUR]: undefined, - [adpodUtils.TARGETING_KEY_CACHE_ID]: undefined - }; - let customParams = {}; - if (targeting[code]) { - customParams = targeting[code].reduce((acc, curValue) => { - if (Object.keys(curValue)[0] === adpodUtils.TARGETING_KEY_PB_CAT_DUR) { - acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] = (typeof acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] !== 'undefined') ? acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] + ',' + curValue[adpodUtils.TARGETING_KEY_PB_CAT_DUR] : curValue[adpodUtils.TARGETING_KEY_PB_CAT_DUR]; - } else if (Object.keys(curValue)[0] === adpodUtils.TARGETING_KEY_CACHE_ID) { - acc[adpodUtils.TARGETING_KEY_CACHE_ID] = curValue[adpodUtils.TARGETING_KEY_CACHE_ID] - } - return acc; - }, initialValue); - } - - let encodedCustomParams = encodeURIComponent(formatQS(customParams)); - - const queryParams = Object.assign({}, - defaultParamConstants, - derivedParams, - params, - { cust_params: encodedCustomParams } - ); - - const gdprConsent = gdprDataHandler.getConsentData(); - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies === 'boolean') { queryParams.gdpr = Number(gdprConsent.gdprApplies); } - if (gdprConsent.consentString) { queryParams.gdpr_consent = gdprConsent.consentString; } - if (gdprConsent.addtlConsent) { queryParams.addtl_consent = gdprConsent.addtlConsent; } - } - - const masterTag = buildUrl({ - protocol: 'https', - host: 'securepubads.g.doubleclick.net', - pathname: '/gampad/ads', - search: queryParams - }); - - callback(null, masterTag); - } -} - /** * Builds a video url from a base dfp video url and a winning bid, appending * Prebid-specific key-values. @@ -375,8 +254,4 @@ function getCustParams(bid, options, urlCustParams) { registerVideoSupport('dfp', { buildVideoUrl: buildDfpVideoUrl, - buildAdpodVideoUrl: buildAdpodVideoUrl, - getAdpodTargeting: (args) => adpodUtils.getTargeting(args) }); - -submodule('adpod', adpodUtils); diff --git a/modules/dfpAdpod.js b/modules/dfpAdpod.js new file mode 100644 index 00000000000..1675954459c --- /dev/null +++ b/modules/dfpAdpod.js @@ -0,0 +1,98 @@ +import {submodule} from '../src/hook.js'; +import {buildUrl, deepAccess, formatQS, logError, parseSizesInput} from '../src/utils.js'; +import {auctionManager} from '../src/auctionManager.js'; +import {DEFAULT_DFP_PARAMS, DFP_ENDPOINT, setGdprConsent} from '../libraries/dfpUtils/dfpUtils.js'; +import {gdprDataHandler} from '../src/consentHandler.js'; +import {registerVideoSupport} from '../src/adServerManager.js'; + +export const adpodUtils = {}; + +/** + * @typedef {Object} DfpAdpodOptions + * + * @param {string} code Ad Unit code + * @param {Object} params Query params which should be set on the DFP request. + * These will override this module's defaults whenever they conflict. + * @param {function} callback Callback function to execute when master tag is ready + */ + +/** + * Creates master tag url for long-form + * @param {DfpAdpodOptions} options + * @returns {string} A URL which calls DFP with custom adpod targeting key values to compete with rest of the demand in DFP + */ +export function buildAdpodVideoUrl({code, params, callback} = {}) { + // TODO: the public API for this does not take in enough info to fill all DFP params (adUnit/bid), + // and is marked "alpha": https://docs.prebid.org/dev-docs/publisher-api-reference/adServers.dfp.buildAdpodVideoUrl.html + if (!params || !callback) { + logError(`A params object and a callback is required to use pbjs.adServers.dfp.buildAdpodVideoUrl`); + return; + } + + const derivedParams = { + correlator: Date.now(), + sz: getSizeForAdUnit(code), + url: encodeURIComponent(location.href), + }; + + function getSizeForAdUnit(code) { + let adUnit = auctionManager.getAdUnits() + .filter((adUnit) => adUnit.code === code) + let sizes = deepAccess(adUnit[0], 'mediaTypes.video.playerSize'); + return parseSizesInput(sizes).join('|'); + } + + adpodUtils.getTargeting({ + 'codes': [code], + 'callback': createMasterTag + }); + + function createMasterTag(err, targeting) { + if (err) { + callback(err, null); + return; + } + + let initialValue = { + [adpodUtils.TARGETING_KEY_PB_CAT_DUR]: undefined, + [adpodUtils.TARGETING_KEY_CACHE_ID]: undefined + }; + let customParams = {}; + if (targeting[code]) { + customParams = targeting[code].reduce((acc, curValue) => { + if (Object.keys(curValue)[0] === adpodUtils.TARGETING_KEY_PB_CAT_DUR) { + acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] = (typeof acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] !== 'undefined') ? acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] + ',' + curValue[adpodUtils.TARGETING_KEY_PB_CAT_DUR] : curValue[adpodUtils.TARGETING_KEY_PB_CAT_DUR]; + } else if (Object.keys(curValue)[0] === adpodUtils.TARGETING_KEY_CACHE_ID) { + acc[adpodUtils.TARGETING_KEY_CACHE_ID] = curValue[adpodUtils.TARGETING_KEY_CACHE_ID] + } + return acc; + }, initialValue); + } + + let encodedCustomParams = encodeURIComponent(formatQS(customParams)); + + const queryParams = Object.assign({}, + DEFAULT_DFP_PARAMS, + derivedParams, + params, + { cust_params: encodedCustomParams } + ); + + const gdprConsent = gdprDataHandler.getConsentData(); + setGdprConsent(gdprConsent, queryParams); + + const masterTag = buildUrl({ + ...DFP_ENDPOINT, + search: queryParams + }); + + callback(null, masterTag); + } +} + +registerVideoSupport('dfp', { + buildAdpodVideoUrl: buildAdpodVideoUrl, + getAdpodTargeting: (args) => adpodUtils.getTargeting(args) +}); + +submodule('adpod', adpodUtils); diff --git a/modules/dgkeywordRtdProvider.js b/modules/dgkeywordRtdProvider.js index 14519ae2713..c97296f6982 100644 --- a/modules/dgkeywordRtdProvider.js +++ b/modules/dgkeywordRtdProvider.js @@ -101,6 +101,8 @@ export function getProfileApiUrl(customeUrl, enableReadFpid) { export function readFpidFromLocalStrage() { try { + // TODO: use storageManager + // eslint-disable-next-line prebid/no-global const fpid = window.localStorage.getItem('ope_fpid'); if (fpid) { return fpid; diff --git a/modules/dianomiBidAdapter.js b/modules/dianomiBidAdapter.js index d4b2a4a5da5..f4f81f20f87 100644 --- a/modules/dianomiBidAdapter.js +++ b/modules/dianomiBidAdapter.js @@ -10,6 +10,7 @@ import { parseSizesInput, deepSetValue, formatQS, + setOnAny } from '../src/utils.js'; import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; @@ -355,15 +356,6 @@ function parseNative(bid) { return result; } -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - function flatten(arr) { return [].concat(...arr); } diff --git a/modules/discoveryBidAdapter.js b/modules/discoveryBidAdapter.js index 3ac905ef6b5..696faa86a0a 100644 --- a/modules/discoveryBidAdapter.js +++ b/modules/discoveryBidAdapter.js @@ -2,6 +2,11 @@ import * as utils from '../src/utils.js'; import { getStorageManager } from '../src/storageManager.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { getHLen, getHC, getDM } from '../src/fpd/navigator.js'; +import { getPageTitle, getPageDescription, getPageKeywords, getConnectionDownLink, getReferrer } from '../libraries/fpdUtils/pageInfo.js'; +import { getDevice, getScreenSize } from '../libraries/fpdUtils/deviceInfo.js'; +import { getBidFloor } from '../libraries/currencyUtils/floor.js'; +import { transformSizes, normalAdSize } from '../libraries/sizeUtils/tranformSize.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -21,6 +26,9 @@ const MEDIATYPE = [BANNER, NATIVE]; const COOKIE_KEY_SSPPID = '_ss_pp_id'; export const COOKIE_KEY_MGUID = '__mguid_'; const COOKIE_KEY_PMGUID = '__pmguid_'; +const COOKIE_KEY_PBUID = 'pub_pp_tag'; +const STORAGE_KEY_FTUID = 'fluct_ppUUIDv4'; +const STORAGE_KEY_IMUID = '__im_ppid'; const COOKIE_RETENTION_TIME = 365 * 24 * 60 * 60 * 1000; // 1 year const COOKY_SYNC_IFRAME_URL = 'https://asset.popin.cc/js/cookieSync.html'; export const THIRD_PARTY_COOKIE_ORIGIN = 'https://asset.popin.cc'; @@ -67,64 +75,6 @@ const NATIVERET = { ext: {}, }; -/** - * get page title111 - * @returns {string} - */ - -export function getPageTitle(win = window) { - try { - const ogTitle = win.top.document.querySelector('meta[property="og:title"]') - return win.top.document.title || (ogTitle && ogTitle.content) || ''; - } catch (e) { - const ogTitle = document.querySelector('meta[property="og:title"]') - return document.title || (ogTitle && ogTitle.content) || ''; - } -} - -/** - * get page description - * @returns {string} - */ -export function getPageDescription(win = window) { - let element; - - try { - element = win.top.document.querySelector('meta[name="description"]') || - win.top.document.querySelector('meta[property="og:description"]') - } catch (e) { - element = document.querySelector('meta[name="description"]') || - document.querySelector('meta[property="og:description"]') - } - - return (element && element.content) || ''; -} - -/** - * get page keywords - * @returns {string} - */ -export function getPageKeywords(win = window) { - let element; - - try { - element = win.top.document.querySelector('meta[name="keywords"]'); - } catch (e) { - element = document.querySelector('meta[name="keywords"]'); - } - - return (element && element.content) || ''; -} - -/** - * get connection downlink - * @returns {number} - */ -export function getConnectionDownLink(win = window) { - const nav = win.navigator || {}; - return nav && nav.connection && nav.connection.downlink >= 0 ? nav.connection.downlink.toString() : undefined; -} - /** * get pmg uid * 获取并生成用户的id @@ -139,7 +89,7 @@ export const getPmgUID = () => { } // Extend the expiration time of pmguid try { - storage.setCookie(COOKIE_KEY_PMGUID, pmgUid, getCurrentTimeToUTCString()); + storage.setCookie(COOKIE_KEY_PMGUID, pmgUid, getCookieTimeToUTCString()); } catch (e) {} return pmgUid; }; @@ -165,150 +115,14 @@ function getKv(obj, ...keys) { return o; } -/** - * get device - * @return {boolean} - */ -function getDevice() { - let check = false; - (function (a) { - let reg1 = new RegExp( - [ - '(android|bbd+|meego)', - '.+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)', - '|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone', - '|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up.(browser|link)|vodafone|wap', - '|windows ce|xda|xiino|android|ipad|playbook|silk', - ].join(''), - 'i' - ); - let reg2 = new RegExp( - [ - '1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)', - '|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )', - '|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell', - '|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)', - '|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene', - '|gf-5|g-mo|go(.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c', - '|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom', - '|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)', - '|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)', - '|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]', - '|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)', - '|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio', - '|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms', - '|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al', - '|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)', - '|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(.b|g1|si)|utst|', - 'v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)', - '|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-', - '|your|zeto|zte-', - ].join(''), - 'i' - ); - if (reg1.test(a) || reg2.test(a.substr(0, 4))) { - check = true; - } - })(navigator.userAgent || navigator.vendor || window.opera); - return check; -} - -/** - * get BidFloor - * @param {*} bid - * @param {*} mediaType - * @param {*} sizes - * @returns - */ -function getBidFloor(bid) { - if (!utils.isFn(bid.getFloor)) { - return utils.deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0; - } -} - -/** - * get sizes for rtb - * @param {Array|Object} requestSizes - * @return {Object} - */ -function transformSizes(requestSizes) { - let sizes = []; - let sizeObj = {}; - - if ( - utils.isArray(requestSizes) && - requestSizes.length === 2 && - !utils.isArray(requestSizes[0]) - ) { - sizeObj.width = parseInt(requestSizes[0], 10); - sizeObj.height = parseInt(requestSizes[1], 10); - sizes.push(sizeObj); - } else if (typeof requestSizes === 'object') { - for (let i = 0; i < requestSizes.length; i++) { - let size = requestSizes[i]; - sizeObj = {}; - sizeObj.width = parseInt(size[0], 10); - sizeObj.height = parseInt(size[1], 10); - sizes.push(sizeObj); - } - } - - return sizes; -} - // Support sizes -const popInAdSize = [ - { w: 300, h: 250 }, - { w: 300, h: 600 }, - { w: 728, h: 90 }, - { w: 970, h: 250 }, - { w: 320, h: 50 }, - { w: 160, h: 600 }, - { w: 320, h: 180 }, - { w: 320, h: 100 }, - { w: 336, h: 280 }, -]; +const popInAdSize = normalAdSize; /** - * get screen size - * - * @returns {Array} eg: "['widthxheight']" - */ -function getScreenSize() { - return utils.parseSizesInput([window.screen.width, window.screen.height]); -} - -/** - * @param {BidRequest} bidRequest - * @param bidderRequest - * @returns {string} - */ -function getReferrer(bidRequest = {}, bidderRequest = {}) { - let pageUrl; - if (bidRequest.params && bidRequest.params.referrer) { - pageUrl = bidRequest.params.referrer; - } else { - pageUrl = utils.deepAccess(bidderRequest, 'refererInfo.page'); - } - return pageUrl; -} - -/** - * get current time to UTC string + * get cookie time to UTC string * @returns utc string */ -export function getCurrentTimeToUTCString() { +export function getCookieTimeToUTCString() { const date = new Date(); date.setTime(date.getTime() + COOKIE_RETENTION_TIME); return date.toUTCString(); @@ -381,9 +195,8 @@ function getItems(validBidRequests, bidderRequest) { } } if (!matchSize) { - matchSize = sizes[0] - ? { h: sizes[0].height || 0, w: sizes[0].width || 0 } - : { h: 0, w: 0 }; + const { height = 0, width = 0 } = sizes[0] || {}; + matchSize = { h: height, w: width }; } ret = { id: id, @@ -423,7 +236,7 @@ export const buildUTMTagData = (url) => { }); UTMValue = JSON.parse(storage.getCookie(UTM_KEY) || '{}'); Object.assign(UTMValue, UTMParams); - storage.setCookie(UTM_KEY, JSON.stringify(UTMValue), getCurrentTimeToUTCString()); + storage.setCookie(UTM_KEY, JSON.stringify(UTMValue), getCookieTimeToUTCString()); } /** @@ -434,10 +247,10 @@ export const buildUTMTagData = (url) => { * @return {Object} */ function getParam(validBidRequests, bidderRequest) { - const pubcid = utils.deepAccess(validBidRequests[0], 'crumbs.pubcid'); const sharedid = utils.deepAccess(validBidRequests[0], 'userId.sharedid.id') || - utils.deepAccess(validBidRequests[0], 'userId.pubcid'); + utils.deepAccess(validBidRequests[0], 'userId.pubcid') || + utils.deepAccess(validBidRequests[0], 'crumbs.pubcid'); const eids = validBidRequests[0].userIdAsEids || validBidRequests[0].userId; let isMobile = getDevice() ? 1 : 0; @@ -455,11 +268,34 @@ function getParam(validBidRequests, bidderRequest) { const referer = utils.deepAccess(bidderRequest, 'refererInfo.ref'); const firstPartyData = bidderRequest.ortb2; const tpData = utils.deepAccess(bidderRequest, 'ortb2.user.data') || undefined; - const topWindow = window.top; const title = getPageTitle(); const desc = getPageDescription(); const keywords = getPageKeywords(); - + let ext = {}; + try { + ext = { + eids, + firstPartyData, + ssppid: storage.getCookie(COOKIE_KEY_SSPPID) || undefined, + pmguid: getPmgUID(), + ssftUid: storage.getDataFromLocalStorage(STORAGE_KEY_FTUID) || undefined, + ssimUid: storage.getDataFromLocalStorage(STORAGE_KEY_IMUID) || undefined, + sspbid: storage.getCookie(COOKIE_KEY_PBUID) || undefined, + tpData, + utm: storage.getCookie(UTM_KEY), + page: { + title: title ? title.slice(0, 150) : undefined, + desc: desc ? desc.slice(0, 300) : undefined, + keywords: keywords ? keywords.slice(0, 100) : undefined, + hLen: getHLen(), + }, + device: { + nbw: getConnectionDownLink(), + hc: getHC(), + dm: getDM() + } + } + } catch (error) {} try { buildUTMTagData(page); } catch (error) { } @@ -480,28 +316,10 @@ function getParam(validBidRequests, bidderRequest) { ua: navigator.userAgent, language: /en/.test(navigator.language) ? 'en' : navigator.language, }, - ext: { - eids, - firstPartyData, - ssppid: storage.getCookie(COOKIE_KEY_SSPPID) || undefined, - pmguid: getPmgUID(), - tpData, - utm: storage.getCookie(UTM_KEY), - page: { - title: title ? title.slice(0, 100) : undefined, - desc: desc ? desc.slice(0, 300) : undefined, - keywords: keywords ? keywords.slice(0, 100) : undefined, - hLen: topWindow.history?.length || undefined, - }, - device: { - nbw: getConnectionDownLink(), - hc: topWindow.navigator?.hardwareConcurrency || undefined, - dm: topWindow.navigator?.deviceMemory || undefined, - } - }, + ext, user: { buyeruid: storage.getCookie(COOKIE_KEY_MGUID) || undefined, - id: sharedid || pubcid, + id: sharedid, }, tmax: timeout, site: { @@ -562,14 +380,15 @@ export const spec = { * @return ServerRequest Info describing the request to the server. */ buildRequests: function (validBidRequests, bidderRequest) { - if (!globals['token']) return; + const pbToken = globals['token']; + if (!pbToken) return; let payload = getParam(validBidRequests, bidderRequest); - const payloadString = JSON.stringify(payload); + return { method: 'POST', - url: ENDPOINT_URL + globals['token'], + url: `${ENDPOINT_URL}${pbToken}`, data: payloadString, }; }, @@ -693,7 +512,7 @@ export const spec = { const response = event.data; if (!response.optout && response.mguid) { - storage.setCookie(COOKIE_KEY_MGUID, response.mguid, getCurrentTimeToUTCString()); + storage.setCookie(COOKIE_KEY_MGUID, response.mguid, getCookieTimeToUTCString()); } }, true); return [ diff --git a/modules/dspxBidAdapter.js b/modules/dspxBidAdapter.js index ea47c64094d..b2610610cf2 100644 --- a/modules/dspxBidAdapter.js +++ b/modules/dspxBidAdapter.js @@ -1,4 +1,5 @@ -import {deepAccess, getBidIdParameter, isFn, logError, logMessage, logWarn} from '../src/utils.js'; +import {deepAccess, getBidIdParameter, isFn, logError, logMessage, logWarn, isEmptyStr, isArray} from '../src/utils.js'; + import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {Renderer} from '../src/Renderer.js'; @@ -7,12 +8,11 @@ import {includes} from '../src/polyfill.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest */ - const BIDDER_CODE = 'dspx'; const ENDPOINT_URL = 'https://buyer.dspx.tv/request/'; const ENDPOINT_URL_DEV = 'https://dcbuyer.dspx.tv/request/'; const GVLID = 602; -const VIDEO_ORTB_PARAMS = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', +const VIDEO_ORTB_PARAMS = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'plcmt', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype', 'ext']; @@ -63,24 +63,18 @@ export const spec = { rnd: rnd, ref: referrer, bid_id: bidId, - pbver: '$prebid.version$' + pbver: '$prebid.version$', }; + payload.pfilter = {}; if (params.pfilter !== undefined) { payload.pfilter = params.pfilter; } if (bidderRequest && bidderRequest.gdprConsent) { - if (payload.pfilter !== undefined) { - if (!payload.pfilter.gdpr_consent) { - payload.pfilter.gdpr_consent = bidderRequest.gdprConsent.consentString; - payload.pfilter.gdpr = bidderRequest.gdprConsent.gdprApplies; - } - } else { - payload.pfilter = { - 'gdpr_consent': bidderRequest.gdprConsent.consentString, - 'gdpr': bidderRequest.gdprConsent.gdprApplies - }; + if (!payload.pfilter.gdpr_consent) { + payload.pfilter.gdpr_consent = bidderRequest.gdprConsent.consentString; + payload.pfilter.gdpr = bidderRequest.gdprConsent.gdprApplies; } } @@ -94,48 +88,10 @@ export const spec = { payload.prebidDevMode = 1; } - // fill userId params - if (bidRequest.userId) { - if (bidRequest.userId.netId) { - payload.did_netid = bidRequest.userId.netId; - } - if (bidRequest.userId.id5id) { - payload.did_id5 = bidRequest.userId.id5id.uid || '0'; - if (bidRequest.userId.id5id.ext.linkType !== undefined) { - payload.did_id5_linktype = bidRequest.userId.id5id.ext.linkType; - } - } - let uId2 = deepAccess(bidRequest, 'userId.uid2.id'); - if (uId2) { - payload.did_uid2 = uId2; - } - let sharedId = deepAccess(bidRequest, 'userId.sharedid.id'); - if (sharedId) { - payload.did_sharedid = sharedId; - } - let pubcId = deepAccess(bidRequest, 'userId.pubcid'); - if (pubcId) { - payload.did_pubcid = pubcId; - } - let crumbsPubcid = deepAccess(bidRequest, 'crumbs.pubcid'); - if (crumbsPubcid) { - payload.did_cpubcid = crumbsPubcid; - } - } - - if (bidRequest.schain) { - payload.schain = bidRequest.schain; - } - - if (payload.pfilter === undefined || !payload.pfilter.floorprice) { + if (!payload.pfilter.floorprice) { let bidFloor = getBidFloor(bidRequest); if (bidFloor > 0) { - if (payload.pfilter !== undefined) { - payload.pfilter.floorprice = bidFloor; - } else { - payload.pfilter = { 'floorprice': bidFloor }; - } - // payload.bidFloor = bidFloor; + payload.pfilter.floorprice = bidFloor; } } @@ -146,6 +102,7 @@ export const spec = { payload.pbcode = pbcode; } + // media types payload.media_types = convertMediaInfoForRequest(mediaTypesInfo); if (mediaTypesInfo[VIDEO] !== undefined) { payload.vctx = getVideoContext(bidRequest); @@ -159,6 +116,33 @@ export const spec = { .forEach(key => payload.vpl[key] = videoParams[key]); } + // iab content + let content = deepAccess(bidderRequest, 'ortb2.site.content'); + if (content) { + let stringContent = siteContentToString(content); + if (stringContent) { + payload.pfilter.iab_content = stringContent; + } + } + + // Google Topics + const segments = extractUserSegments(bidderRequest); + if (segments) { + assignDefinedValues(payload, { + segtx: segments.segtax, + segcl: segments.segclass, + segs: segments.segments + }); + } + + // schain + if (bidRequest.schain) { + payload.schain = bidRequest.schain; + } + + // fill userId params + fillUsersIds(bidRequest, payload); + return { method: 'GET', url: endpoint, @@ -257,6 +241,74 @@ export const spec = { } } +/** + * Adds userIds to payload + * + * @param bidRequest + * @param payload + */ +function fillUsersIds(bidRequest, payload) { + if (bidRequest.hasOwnProperty('userId')) { + let didMapping = { + did_netid: 'userId.netId', + did_id5: 'userId.id5id.uid', + did_id5_linktype: 'userId.id5id.ext.linkType', + did_uid2: 'userId.uid2', + did_sharedid: 'userId.sharedid', + did_pubcid: 'userId.pubcid', + did_uqid: 'userId.utiq', + did_cruid: 'userId.criteoid', + did_euid: 'userId.euid', + // did_tdid: 'unifiedId', + did_tdid: 'userId.tdid', + did_ppuid: function() { + let path = 'userId.pubProvidedId'; + let value = deepAccess(bidRequest, path); + if (isArray(value)) { + for (const rec of value) { + if (rec.uids && rec.uids.length > 0) { + for (let i = 0; i < rec.uids.length; i++) { + if ('id' in rec.uids[i] && deepAccess(rec.uids[i], 'ext.stype') === 'ppuid') { + return (rec.uids[i].atype ?? '') + ':' + rec.source + ':' + rec.uids[i].id; + } + } + } + } + } + return undefined; + }, + did_cpubcid: 'crumbs.pubcid' + }; + for (let paramName in didMapping) { + let path = didMapping[paramName]; + + // handle function + if (typeof path == 'function') { + let value = path(paramName); + if (value) { + payload[paramName] = value; + } + continue; + } + // direct access + let value = deepAccess(bidRequest, path); + if (typeof value == 'string' || typeof value == 'number') { + payload[paramName] = value; + } else if (typeof value == 'object') { + // trying to find string ID value + if (typeof deepAccess(bidRequest, path + '.id') == 'string') { + payload[paramName] = deepAccess(bidRequest, path + '.id'); + } else { + if (Object.keys(value).length > 0) { + logError(`DSPx: WARNING: fillUserIds had to use first key in user object to get value for bid.userId key: ${path}.`); + payload[paramName] = value[Object.keys(value)[0]]; + } + } + } + } + } +} + function appendToUrl(url, what) { if (!what) { return url; @@ -276,7 +328,7 @@ function objectToQueryString(obj, prefix) { : encodeURIComponent(k) + '=' + encodeURIComponent(v)); } } - return str.join('&'); + return str.filter(n => n).join('&'); } /** @@ -508,4 +560,74 @@ function createOutstreamEmbedCode(bid) { return fragment; } +/** + * Convert site.content to string + * @param content + */ +function siteContentToString(content) { + if (!content) { + return ''; + } + let stringKeys = ['id', 'title', 'series', 'season', 'artist', 'genre', 'isrc', 'url', 'keywords']; + let intKeys = ['episode', 'context', 'livestream']; + let arrKeys = ['cat']; + let retArr = []; + arrKeys.forEach(k => { + let val = deepAccess(content, k); + if (val && Array.isArray(val)) { + retArr.push(k + ':' + val.join('|')); + } + }); + intKeys.forEach(k => { + let val = deepAccess(content, k); + if (val && typeof val === 'number') { + retArr.push(k + ':' + val); + } + }); + stringKeys.forEach(k => { + let val = deepAccess(content, k); + if (val && typeof val === 'string') { + retArr.push(k + ':' + encodeURIComponent(val)); + } + }); + return retArr.join(','); +} + +/** + * Assigns multiple values to the specified keys on an object if the values are not undefined. + * @param {Object} target - The object to which the values will be assigned. + * @param {Object} values - An object containing key-value pairs to be assigned. + */ +function assignDefinedValues(target, values) { + for (const key in values) { + if (values[key] !== undefined) { + target[key] = values[key]; + } + } +} + +/** + * Extracts user segments/topics from the bid request object + * @param {Object} bid - The bid request object + * @returns {{segclass: *, segtax: *, segments: *}|undefined} - User segments/topics or undefined if not found + */ +function extractUserSegments(bid) { + const userData = deepAccess(bid, 'ortb2.user.data') || []; + for (const dataObj of userData) { + if (dataObj.segment && isArray(dataObj.segment) && dataObj.segment.length > 0) { + const segments = dataObj.segment + .filter(seg => seg.id && !isEmptyStr(seg.id) && isFinite(seg.id)) + .map(seg => Number(seg.id)); + if (segments.length > 0) { + return { + segtax: deepAccess(dataObj, 'ext.segtax'), + segclass: deepAccess(dataObj, 'ext.segclass'), + segments: segments.join(',') + }; + } + } + } + return undefined; +} + registerBidder(spec); diff --git a/modules/e_volutionBidAdapter.js b/modules/e_volutionBidAdapter.js index 26a1f9c5718..e87e39599a0 100644 --- a/modules/e_volutionBidAdapter.js +++ b/modules/e_volutionBidAdapter.js @@ -1,202 +1,19 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { isBidRequestValid, buildRequests, interpretResponse } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'e_volution'; const GVLID = 957; const AD_URL = 'https://service.e-volution.ai/?c=o&m=multi'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes, transactionId, userIdAsEids } = bid; - const schain = bid.schain || {}; - const { placementId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - placementId, - bidId, - schain, - bidfloor - }; - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.plcmt = mediaTypes[VIDEO].plcmt; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - if (transactionId) { - placement.ext = placement.ext || {}; - placement.ext.tid = transactionId; - } - - if (userIdAsEids && userIdAsEids.length) { - placement.eids = userIdAsEids; - } - - return placement; -} - -function getBidFloor(bid) { - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, gvlid: GVLID, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && params.placementId); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0, - tmax: bidderRequest.timeout - }; - - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - - if (bidderRequest.gdprConsent) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse }; registerBidder(spec); diff --git a/modules/ebdrBidAdapter.js b/modules/ebdrBidAdapter.js deleted file mode 100644 index e830f8a94f7..00000000000 --- a/modules/ebdrBidAdapter.js +++ /dev/null @@ -1,156 +0,0 @@ -import {getBidIdParameter, logInfo} from '../src/utils.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -const BIDDER_CODE = 'ebdr'; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], - isBidRequestValid: function(bid) { - return !!(bid && bid.params && bid.params.zoneid); - }, - buildRequests: function(bids) { - const rtbServerDomain = 'dsp.bnmla.com'; - let domain = window.location.host; - let page = window.location.pathname + location.search + location.hash; - let ebdrImps = []; - const ebdrReq = {}; - let ebdrParams = {}; - let zoneid = ''; - let requestId = ''; - bids.forEach(bid => { - logInfo('Log bid', bid); - let bidFloor = getBidIdParameter('bidfloor', bid.params); - let whArr = getWidthAndHeight(bid); - let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video) ? VIDEO : BANNER; - zoneid = getBidIdParameter('zoneid', bid.params); - requestId = bid.bidderRequestId; - ebdrImps.push({ - id: bid.bidId, - [_mediaTypes]: { - w: whArr[0], - h: whArr[1] - }, - bidfloor: bidFloor - }); - ebdrReq[bid.bidId] = {mediaTypes: _mediaTypes, - w: whArr[0], - h: whArr[1] - }; - // TODO: fix lat and long to only come from request - ebdrParams['latitude'] = '0'; - ebdrParams['longitude'] = '0'; - ebdrParams['ifa'] = (getBidIdParameter('IDFA', bid.params).length > getBidIdParameter('ADID', bid.params).length) ? getBidIdParameter('IDFA', bid.params) : getBidIdParameter('ADID', bid.params); - }); - let ebdrBidReq = { - id: requestId, - imp: ebdrImps, - site: { - domain: domain, - page: page - }, - device: { - geo: { - lat: ebdrParams.latitude, - log: ebdrParams.longitude - }, - ifa: ebdrParams.ifa - } - }; - return { - method: 'GET', - url: 'https://' + rtbServerDomain + '/hb?' + '&zoneid=' + zoneid + '&br=' + encodeURIComponent(JSON.stringify(ebdrBidReq)), - bids: ebdrReq - }; - }, - interpretResponse: function(serverResponse, bidRequest) { - logInfo('Log serverResponse', serverResponse); - logInfo('Log bidRequest', bidRequest); - let ebdrResponseImps = []; - const ebdrResponseObj = serverResponse.body; - if (!ebdrResponseObj || !ebdrResponseObj.seatbid || ebdrResponseObj.seatbid.length === 0 || !ebdrResponseObj.seatbid[0].bid || ebdrResponseObj.seatbid[0].bid.length === 0) { - return []; - } - ebdrResponseObj.seatbid[0].bid.forEach(ebdrBid => { - let responseCPM; - responseCPM = parseFloat(ebdrBid.price); - let adm; - let type; - let _mediaTypes; - let vastURL; - if (bidRequest.bids[ebdrBid.id].mediaTypes == BANNER) { - adm = decodeURIComponent(ebdrBid.adm) - type = 'ad'; - _mediaTypes = BANNER; - } else { - adm = ebdrBid.adm - type = 'vastXml' - _mediaTypes = VIDEO; - if (ebdrBid.nurl) { - vastURL = ebdrBid.nurl; - } - } - let response = { - requestId: ebdrBid.id, - [type]: adm, - mediaType: _mediaTypes, - creativeId: ebdrBid.crid, - cpm: responseCPM, - width: ebdrBid.w, - height: ebdrBid.h, - currency: 'USD', - netRevenue: true, - ttl: 3600, - meta: { - advertiserDomains: ebdrBid.adomain || [] - } - }; - if (vastURL) { - response.vastUrl = vastURL; - } - ebdrResponseImps.push(response); - }); - return ebdrResponseImps; - }, - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = [] - if (syncOptions.pixelEnabled) { - const ebdrResponseObj = serverResponses.body; - if (!ebdrResponseObj || !ebdrResponseObj.seatbid || ebdrResponseObj.seatbid.length === 0 || !ebdrResponseObj.seatbid[0].bid || ebdrResponseObj.seatbid[0].bid.length === 0) { - return []; - } - ebdrResponseObj.seatbid[0].bid.forEach(ebdrBid => { - if (ebdrBid.iurl && ebdrBid.iurl.length > 0) { - syncs.push({ - type: 'image', - url: ebdrBid.iurl - }); - } - }); - } - return syncs; - } -} -function getWidthAndHeight(bid) { - let adW = null; - let adH = null; - // Handing old bidder only has size object - if (bid.sizes && bid.sizes.length) { - let sizeArrayLength = bid.sizes.length; - if (sizeArrayLength === 2 && typeof bid.sizes[0] === 'number' && typeof bid.sizes[1] === 'number') { - adW = bid.sizes[0]; - adH = bid.sizes[1]; - } - } - let _mediaTypes = bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER; - if (bid.mediaTypes && bid.mediaTypes[_mediaTypes]) { - if (_mediaTypes == BANNER && bid.mediaTypes[_mediaTypes].sizes && bid.mediaTypes[_mediaTypes].sizes[0] && bid.mediaTypes[_mediaTypes].sizes[0].length === 2) { - adW = bid.mediaTypes[_mediaTypes].sizes[0][0]; - adH = bid.mediaTypes[_mediaTypes].sizes[0][1]; - } else if (_mediaTypes == VIDEO && bid.mediaTypes[_mediaTypes].playerSize && bid.mediaTypes[_mediaTypes].playerSize.length === 2) { - adW = bid.mediaTypes[_mediaTypes].playerSize[0]; - adH = bid.mediaTypes[_mediaTypes].playerSize[1]; - } - } - return [adW, adH]; -} -registerBidder(spec); diff --git a/modules/ebdrBidAdapter.md b/modules/ebdrBidAdapter.md deleted file mode 100644 index 64483797b25..00000000000 --- a/modules/ebdrBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: EngageBDR Bid Adapter -Module Type: Bidder Adapter -Maintainer: tech@engagebdr.com -``` - -# Description - -Adapter that connects to EngageBDR's demand sources. - -# Test Parameters -``` - var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - bids: [{ - bidder: 'ebdr', - params: { - zoneid: '99999', - bidfloor: '1.00', - IDFA:'xxx-xxx', - ADID:'xxx-xxx', - latitude:'34.089811', - longitude:'-118.392805' - } - }] - },{ - code: 'test-video', - mediaTypes: { - video: { - context: 'instream', - playerSize: [300, 250] - } - }, - bids: [{ - bidder: 'ebdr', - params: { - zoneid: '99998', - bidfloor: '1.00', - IDFA:'xxx-xxx', - ADID:'xxx-xxx', - latitude:'34.089811', - longitude:'-118.392805' - } - }] - }]; -``` diff --git a/modules/edge226BidAdapter.js b/modules/edge226BidAdapter.js index 6d1e2466abe..f0b91183a3e 100644 --- a/modules/edge226BidAdapter.js +++ b/modules/edge226BidAdapter.js @@ -57,6 +57,7 @@ function getPlacementReqData(bid) { placement.protocols = mediaTypes[VIDEO].protocols; placement.startdelay = mediaTypes[VIDEO].startdelay; placement.placement = mediaTypes[VIDEO].placement; + placement.plcmt = mediaTypes[VIDEO].plcmt; placement.skip = mediaTypes[VIDEO].skip; placement.skipafter = mediaTypes[VIDEO].skipafter; placement.minbitrate = mediaTypes[VIDEO].minbitrate; diff --git a/modules/eightPodAnalyticsAdapter.js b/modules/eightPodAnalyticsAdapter.js index a1ea76daed1..6dab3b0c107 100644 --- a/modules/eightPodAnalyticsAdapter.js +++ b/modules/eightPodAnalyticsAdapter.js @@ -1,4 +1,4 @@ -import {logError, logInfo} from '../src/utils.js'; +import {logError, logInfo, logMessage} from '../src/utils.js'; import {ajax} from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; @@ -9,13 +9,11 @@ import {getStorageManager} from '../src/storageManager.js'; const analyticsType = 'endpoint'; const MODULE_NAME = `eightPod`; const MODULE = `${MODULE_NAME}AnalyticProvider`; -let interval; /** * Custom tracking server that gets internal events from EightPod's ad unit */ const trackerUrl = 'https://demo.8pod.com/tracker/track'; - export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME}) const { @@ -23,12 +21,12 @@ const { } = EVENTS; export let queue = []; -export let context; +let context = {}; /** * Create eightPod Analytic adapter */ -let eightPodAnalytics = Object.assign(adapter({ analyticsType }), { +let eightPodAnalytics = Object.assign(adapter({url: trackerUrl, analyticsType}), { /** * Execute on bid won - setup basic settings, save context about EightPod's bid. We will send it with our events later */ @@ -36,45 +34,47 @@ let eightPodAnalytics = Object.assign(adapter({ analyticsType }), { switch (eventType) { case BID_WON: if (args.bidder === 'eightPod') { + context[args.adUnitCode] = makeContext(args); + eightPodAnalytics.setupPage(args); - context = makeContext(args); break; } } }, /** - * Execute on bid won - subscribe on events from adUnit + * Execute on bid won upload events from local storage */ setupPage() { - eightPodAnalytics.eventSubscribe(); - queue = getEventFromLocalStorage(); + queue = this.getEventFromLocalStorage(); }, + /** * Subscribe on internal ad unit tracking events */ eventSubscribe() { window.addEventListener('message', async (event) => { - const data = event?.data; + const data = event.data; - if (!data?.detail?.name) { - return; - } + const frameElement = event.source?.frameElement; + const parentElement = frameElement?.parentElement; + const adUnitCode = parentElement?.id; - trackEvent(data); + trackEvent(data, adUnitCode); }); - // Send queue of event every 10 seconds - if (!interval) { - interval = setInterval(sendEvents, 10_000); - } + setInterval(sendEvents, 10_000); }, resetQueue() { queue = []; }, getContext() { return context; - } + }, + resetContext() { + context = {}; + }, + getEventFromLocalStorage, }); /** @@ -84,8 +84,8 @@ function makeContext(args) { const params = args?.params?.[0]; return { bidId: args.seatBidId, - variantId: args.creativeId || 'variantId', - campaignId: 'campaignId', + variantId: args.creativeId || '', + campaignId: args.cid || '', publisherId: params.publisherId, placementId: params.placementId, }; @@ -94,12 +94,13 @@ function makeContext(args) { /** * Create event, add context and push it to queue */ -export function trackEvent(event) { +export function trackEvent(event, adUnitCode) { if (!event.detail) { return; } + const fullEvent = { - context: eightPodAnalytics.getContext(), + context: eightPodAnalytics.getContext()[adUnitCode], eventType: event.detail.type, eventClass: 'adunit', timestamp: new Date().getTime(), @@ -107,6 +108,7 @@ export function trackEvent(event) { payload: event.detail.payload }; + logMessage(fullEvent); addEvent(fullEvent); } @@ -158,7 +160,7 @@ function sendEvents() { * Send event to our custom tracking server */ function sendEventsApi(eventList, callbacks) { - ajax(trackerUrl, callbacks, JSON.stringify(eventList)); + ajax(trackerUrl, callbacks, JSON.stringify(eventList), {keepalive: true}); } /** @@ -173,21 +175,13 @@ eightPodAnalytics.originEnableAnalytics = eightPodAnalytics.enableAnalytics; eightPodAnalytics.eventsStorage = []; // override enableAnalytics so we can get access to the config passed in from the page +// Subscribe on events from adUnit eightPodAnalytics.enableAnalytics = function (config) { eightPodAnalytics.originEnableAnalytics(config); logInfo(MODULE, 'init', config); + eightPodAnalytics.eventSubscribe(); }; -eightPodAnalytics.disableAnalytics = (function (orig) { - return function (...args) { - if (interval) { - clearInterval(interval); - interval = null; - } - return orig.apply(this, args); - }; -})(eightPodAnalytics.disableAnalytics); - /** * Register Analytics Adapter */ diff --git a/modules/eightPodBidAdapter.js b/modules/eightPodBidAdapter.js index 02f0954af07..536bc4b4036 100644 --- a/modules/eightPodBidAdapter.js +++ b/modules/eightPodBidAdapter.js @@ -4,7 +4,7 @@ import { BANNER } from '../src/mediaTypes.js' import * as utils from '../src/utils.js' export const BIDDER_CODE = 'eightPod' -const url = 'https://demo.8pod.com/bidder/rtb/eightpod_exchange/bid?trace=true'; +const url = 'https://demo.8pod.com/bidder/rtb/eightpod_exchange/bid'; export const spec = { code: BIDDER_CODE, @@ -49,8 +49,9 @@ function isBidRequestValid(bidRequest) { function buildRequests(bids, bidderRequest) { let bannerBids = bids.filter((bid) => isBannerBid(bid)) let requests = bannerBids.length - ? [createRequest(bannerBids, bidderRequest, BANNER)] + ? createRequest(bannerBids, bidderRequest, BANNER) : [] + return requests } @@ -61,8 +62,10 @@ function bidResponse(buildBidResponse, bid, context) { bidResponse.height = context?.imp?.banner?.format?.[0].h; bidResponse.width = context?.imp?.banner?.format?.[0].w; + bidResponse.cid = bid.cid; bidResponse.burl = replacePriceInUrl(bid.burl, bidResponse.originalCpm || bidResponse.cpm); + return bidResponse; } @@ -119,64 +122,75 @@ export function getPageKeywords(win = window) { } function createRequest(bidRequests, bidderRequest, mediaType) { - const data = converter.toORTB({ - bidRequests, - bidderRequest, - context: { mediaType }, - }); - - data.adSlotPositionOnScreen = 'ABOVE_THE_FOLD'; - data.at = 1; - - const params = getBidderParams(bidRequests); - - data.device = { - ...data.device, - model: parseUserAgent().device, - os: parseUserAgent().platform, - osv: parseUserAgent().version, - geo: { - country: params.country || 'GRB' - }, - language: params.language || data.device.language, - } - data.site = { - ...data.site, - keywords: getPageKeywords(window), - } - data.imp = [ - { - ...data.imp?.[0], - pmp: params.dealId - ? { - ...data.pmp, - deals: [ - { - bidfloor: 0.5, - at: 2, - id: params.dealId, - }, - ], - private_auction: 1, - } - : data.pmp, + const requests = bidRequests.map((bidRequest) => { + const data = converter.toORTB({ + bidRequests: [bidRequest], + bidderRequest, + context: { mediaType }, + }); + + data.adSlotPositionOnScreen = 'ABOVE_THE_FOLD'; + data.at = 1; + + const userId = + utils.deepAccess(bidRequest, 'userId.unifiedId.id') || + utils.deepAccess(bidRequest, 'userId.id5id.uid') || + utils.deepAccess(bidRequest, 'userId.idl_env'); + + const params = getBidderParams(bidRequest); + data.device = { + ...data.device, + devicetype: 4, + geo: { + country: params.country || 'GRB' + }, + language: params.language || data.device.language, + } + data.site = { + ...data.site, + keywords: getPageKeywords(window), + publisher: { + id: params.publisherId + } + } + data.imp = [ + { + ...data.imp?.[0], + secure: 1, + pmp: params.dealId + ? { + ...data.pmp, + deals: [ + { + id: params.dealId, + }, + ], + private_auction: 1, + } + : data.pmp, + } + ] + data.adSlotPlacementId = params.placementId; + + if (userId) { + data.user = { + id: userId + } } - ] - data.adSlotPlacementId = params.placementId; - const req = { - method: 'POST', - url, - data - } - return req -} + const req = { + method: 'POST', + url: url && params.trace ? url + '?trace=true' : url, + options: { withCredentials: false }, + data + } + return req + }) -function getBidderParams(bidRequests) { - const bid = bidRequests.find(bid => { - return bid.bidder === BIDDER_CODE - }); + return requests; +} +function getBidderParams(bid) { return bid?.params ? bid.params : undefined; } @@ -189,5 +203,47 @@ function isBannerBid(bid) { } function interpretResponse(resp, req) { - return converter.fromORTB({ request: req.data, response: resp.body }) + const impressionId = resp.body.seatbid[0].bid[0].impid; + const bidResponses = converter.fromORTB({ request: req.data, response: resp.body }); + const ad = bidResponses[0].ad; + const trackingTag = ` + + + + + ` + + bidResponses[0].ad = ad.replace(' ', trackingTag + ' '); + return bidResponses; } diff --git a/modules/emtvBidAdapter.js b/modules/emtvBidAdapter.js index 7a2fdae8adf..822fa683d9e 100644 --- a/modules/emtvBidAdapter.js +++ b/modules/emtvBidAdapter.js @@ -1,211 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'emtv'; const AD_URL = 'https://us-east-ep.engagemedia.tv/pbjs'; const SYNC_URL = 'https://cs.engagemedia.tv'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: config.getConfig('bidderTimeout') - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/enrichmentFpdModule.js b/modules/enrichmentFpdModule.js deleted file mode 100644 index 59d5d326109..00000000000 --- a/modules/enrichmentFpdModule.js +++ /dev/null @@ -1,2 +0,0 @@ -// Logic from this module was moved into core since approx. 7.27 -// TODO: remove this in v8 diff --git a/modules/eplanningAnalyticsAdapter.js b/modules/eplanningAnalyticsAdapter.js deleted file mode 100644 index 45a0be54715..00000000000 --- a/modules/eplanningAnalyticsAdapter.js +++ /dev/null @@ -1,130 +0,0 @@ -import { logError } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import { EVENTS } from '../src/constants.js'; - -const analyticsType = 'endpoint'; -const EPL_HOST = 'https://ads.us.e-planning.net/hba/1/'; - -function auctionEndHandler(args) { - return {auctionId: args.auctionId}; -} - -function auctionInitHandler(args) { - return { - auctionId: args.auctionId, - time: args.timestamp - }; -} - -function bidRequestedHandler(args) { - return { - auctionId: args.auctionId, - time: args.start, - bidder: args.bidderCode, - bids: args.bids.map(function(bid) { - return { - time: bid.startTime, - bidder: bid.bidder, - placementCode: bid.placementCode, - auctionId: bid.auctionId, - sizes: bid.sizes - }; - }), - }; -} - -function bidResponseHandler(args) { - return { - bidder: args.bidder, - size: args.size, - auctionId: args.auctionId, - cpm: args.cpm, - time: args.responseTimestamp, - }; -} - -function bidWonHandler(args) { - return { - auctionId: args.auctionId, - size: args.width + 'x' + args.height, - }; -} - -function bidTimeoutHandler(args) { - return args.map(function(bid) { - return { - bidder: bid.bidder, - auctionId: bid.auctionId - }; - }) -} - -function callHandler(evtype, args) { - let handler = null; - - if (evtype === EVENTS.AUCTION_INIT) { - handler = auctionInitHandler; - eplAnalyticsAdapter.context.events = []; - } else if (evtype === EVENTS.AUCTION_END) { - handler = auctionEndHandler; - } else if (evtype === EVENTS.BID_REQUESTED) { - handler = bidRequestedHandler; - } else if (evtype === EVENTS.BID_RESPONSE) { - handler = bidResponseHandler - } else if (evtype === EVENTS.BID_TIMEOUT) { - handler = bidTimeoutHandler; - } else if (evtype === EVENTS.BID_WON) { - handler = bidWonHandler; - } - - if (handler) { - eplAnalyticsAdapter.context.events.push({ec: evtype, p: handler(args)}); - } -} - -var eplAnalyticsAdapter = Object.assign(adapter( - { - EPL_HOST, - analyticsType - }), -{ - track({eventType, args}) { - if (typeof args !== 'undefined') { - callHandler(eventType, args); - } - - if (eventType === EVENTS.AUCTION_END) { - try { - let strjson = JSON.stringify(eplAnalyticsAdapter.context.events); - ajax(eplAnalyticsAdapter.context.host + eplAnalyticsAdapter.context.ci + '?d=' + encodeURIComponent(strjson)); - } catch (err) {} - } - } -} -); - -eplAnalyticsAdapter.originEnableAnalytics = eplAnalyticsAdapter.enableAnalytics; - -eplAnalyticsAdapter.enableAnalytics = function (config) { - if (!config.options.ci) { - logError('Client ID (ci) option is not defined. Analytics won\'t work'); - return; - } - - eplAnalyticsAdapter.context = { - events: [], - host: config.options.host || EPL_HOST, - ci: config.options.ci - }; - - eplAnalyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: eplAnalyticsAdapter, - code: 'eplanning' -}); - -export default eplAnalyticsAdapter; diff --git a/modules/etargetBidAdapter.js b/modules/etargetBidAdapter.js index 6f2d217993f..1653d849297 100644 --- a/modules/etargetBidAdapter.js +++ b/modules/etargetBidAdapter.js @@ -1,4 +1,4 @@ -import { deepSetValue, isFn, isPlainObject } from '../src/utils.js'; +import { deepClone, deepSetValue, isFn, isPlainObject } from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; @@ -28,7 +28,7 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { var i, l, bid, reqParams, netRevenue, gdprObject; var request = []; - var bids = JSON.parse(JSON.stringify(validBidRequests)); + var bids = deepClone(validBidRequests); var lastCountry = 'sk'; var floors = []; for (i = 0, l = bids.length; i < l; i++) { diff --git a/modules/euidIdSystem.js b/modules/euidIdSystem.js index d98dc02cdce..281fa04a12a 100644 --- a/modules/euidIdSystem.js +++ b/modules/euidIdSystem.js @@ -14,6 +14,13 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js'; // eslint-disable-next-line prebid/validate-imports import { Uid2GetId, Uid2CodeVersion, extractIdentityFromParams } from './uid2IdSystem_shared.js'; +/** + * @typedef {import('../modules/userId/index.js').Submodule} Submodule + * @typedef {import('../modules/userId/index.js').SubmoduleConfig} SubmoduleConfig + * @typedef {import('../modules/userId/index.js').ConsentData} ConsentData + * @typedef {import('../modules/userId/index.js').IdResponse} IdResponse + */ + const MODULE_NAME = 'euid'; const MODULE_REVISION = Uid2CodeVersion; const PREBID_VERSION = '$prebid.version$'; @@ -75,9 +82,9 @@ export const euidIdSubmodule = { /** * performs action to obtain id and return a value. * @function - * @param {SubmoduleConfig} [configparams] + * @param {SubmoduleConfig} [config] * @param {ConsentData|undefined} consentData - * @returns {euidId} + * @returns {IdResponse} */ getId(config, consentData) { if (consentData?.gdprApplies !== true) { @@ -103,7 +110,6 @@ export const euidIdSubmodule = { mappedConfig.cstg = { serverPublicKey: config?.params?.serverPublicKey, subscriptionId: config?.params?.subscriptionId, - optoutCheck: 1, ...extractIdentityFromParams(config?.params ?? {}) } } diff --git a/modules/finativeBidAdapter.js b/modules/finativeBidAdapter.js index 87580a209bb..e7613bf9cce 100644 --- a/modules/finativeBidAdapter.js +++ b/modules/finativeBidAdapter.js @@ -3,7 +3,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {NATIVE} from '../src/mediaTypes.js'; -import {_map, deepAccess, deepSetValue, isEmpty} from '../src/utils.js'; +import {_map, deepSetValue, isEmpty, setOnAny} from '../src/utils.js'; import {config} from '../src/config.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; @@ -224,15 +224,6 @@ function parseNative(bid) { return result; } -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - function flatten(arr) { return [].concat(...arr); } diff --git a/modules/fintezaAnalyticsAdapter.js b/modules/fintezaAnalyticsAdapter.js index ab41272c85f..78777cd6478 100644 --- a/modules/fintezaAnalyticsAdapter.js +++ b/modules/fintezaAnalyticsAdapter.js @@ -70,7 +70,8 @@ function initFirstVisit() { let cookies; try { - cookies = parseCookies(document.cookie); + // TODO: commented out because of rule violations + cookies = {} // parseCookies(document.cookie); } catch (a) { cookies = {}; } @@ -91,7 +92,8 @@ function initFirstVisit() { return visitDate; } - +// TODO: commented out because of rule violations +/* function trim(string) { if (string.trim) { return string.trim(); @@ -130,6 +132,7 @@ function parseCookies(cookie) { return values; } +*/ function getRandAsStr(digits) { let str = ''; @@ -172,7 +175,8 @@ function initSession() { let isNew = false; try { - cookies = parseCookies(document.cookie); + // TODO: commented out because of rule violations + cookies = {} // parseCookies(document.cookie); } catch (a) { cookies = {}; } @@ -263,7 +267,8 @@ function getTrackRequestLastTime() { ); } - cookie = parseCookies(document.cookie); + // TODO: commented out because of rule violations + cookie = {} // parseCookies(document.cookie); cookie = cookie[ TRACK_TIME_KEY ]; if (cookie) { return parseInt(cookie, 10); diff --git a/modules/fpdModule/index.md b/modules/fpdModule/index.md index 238881db96b..42ae663b090 100644 --- a/modules/fpdModule/index.md +++ b/modules/fpdModule/index.md @@ -44,6 +44,5 @@ pbjs.setConfig({ At least one of the submodules must be included in order to successfully run the corresponding above operations. -enrichmentFpdModule validationFpdModule -topicsFpdModule \ No newline at end of file +topicsFpdModule diff --git a/modules/globalsunBidAdapter.js b/modules/globalsunBidAdapter.js index 5b5d97c2cac..1684509b7b9 100644 --- a/modules/globalsunBidAdapter.js +++ b/modules/globalsunBidAdapter.js @@ -1,212 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'globalsun'; const AD_URL = 'https://endpoint.globalsun.io/pbjs'; const SYNC_URL = 'https://cs.globalsun.io'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/goldbachBidAdapter.js b/modules/goldbachBidAdapter.js index df0336c6cd4..07ad6b2fa97 100644 --- a/modules/goldbachBidAdapter.js +++ b/modules/goldbachBidAdapter.js @@ -21,7 +21,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {ADPOD, BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {find, includes} from '../src/polyfill.js'; import {INSTREAM, OUTSTREAM} from '../src/video.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; import {APPNEXUS_CATEGORY_MAPPING} from '../libraries/categoryTranslationMapping/index.js'; import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; @@ -742,7 +742,7 @@ function bidToTag(bid) { } tag.keywords = getANKeywordParam(bid.ortb2, bid.params.keywords); - let gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); + let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); if (gpid) { tag.gpid = gpid; } diff --git a/modules/gothamadsBidAdapter.js b/modules/gothamadsBidAdapter.js index ab59c6febec..bcd382e507a 100644 --- a/modules/gothamadsBidAdapter.js +++ b/modules/gothamadsBidAdapter.js @@ -1,4 +1,4 @@ -import { logMessage, deepSetValue, deepAccess, _map, logWarn } from '../src/utils.js'; +import { deepSetValue, deepAccess, _map, logWarn } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; @@ -80,18 +80,9 @@ export const spec = { if (validBidRequests && validBidRequests.length === 0) return [] let accuontId = validBidRequests[0].params.accountId; const endpointURL = URL_ENDPOINT.replace(ACCOUNTID_MACROS, accuontId); - let winTop = window; let location; - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page) - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; - + location = bidderRequest?.refererInfo ?? null; let bids = []; for (let bidRequest of validBidRequests) { let impObject = prepareImpObject(bidRequest); @@ -105,8 +96,8 @@ export const spec = { language: (navigator && navigator.language) ? navigator.language.indexOf('-') != -1 ? navigator.language.split('-')[0] : navigator.language : '', }, site: { - page: location.pathname, - host: location.host + page: location?.page, + host: location?.domain }, source: { tid: bidderRequest?.ortb2?.source?.tid, @@ -332,7 +323,7 @@ const parseSizes = (bid, mediaType) => { const addVideoParameters = (bidRequest) => { let videoObj = {}; - let supportParamsList = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'placement', 'skip', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity'] + let supportParamsList = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'skip', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity'] for (let param of supportParamsList) { if (bidRequest.mediaTypes.video[param] !== undefined) { diff --git a/modules/gptPreAuction.js b/modules/gptPreAuction.js index bf5b4a55dbb..29b9257d325 100644 --- a/modules/gptPreAuction.js +++ b/modules/gptPreAuction.js @@ -1,19 +1,68 @@ +import { getSignals as getSignalsFn, getSegments as getSegmentsFn, taxonomies } from '../libraries/gptUtils/gptUtils.js'; +import { auctionManager } from '../src/auctionManager.js'; +import { config } from '../src/config.js'; +import { TARGETING_KEYS } from '../src/constants.js'; +import { getHook } from '../src/hook.js'; +import { find } from '../src/polyfill.js'; import { deepAccess, + deepSetValue, isAdUnitCodeMatchingSlot, isGptPubadsDefined, logInfo, + logWarn, pick, - deepSetValue + uniques } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {getHook} from '../src/hook.js'; -import {find} from '../src/polyfill.js'; const MODULE_NAME = 'GPT Pre-Auction'; export let _currentConfig = {}; let hooksAdded = false; +export function getSegments(fpd, sections, segtax) { + return getSegmentsFn(fpd, sections, segtax); +} + +export function getSignals(fpd) { + return getSignalsFn(fpd); +} + +export function getSignalsArrayByAuctionsIds(auctionIds, index = auctionManager.index) { + const signals = auctionIds + .map(auctionId => index.getAuction({ auctionId })?.getFPD()?.global) + .map(getSignals) + .filter(fpd => fpd); + + return signals; +} + +export function getSignalsIntersection(signals) { + const result = {}; + taxonomies.forEach((taxonomy) => { + const allValues = signals + .flatMap(x => x) + .filter(x => x.taxonomy === taxonomy) + .map(x => x.values); + result[taxonomy] = allValues.length ? ( + allValues.reduce((commonElements, subArray) => { + return commonElements.filter(element => subArray.includes(element)); + }) + ) : [] + result[taxonomy] = { values: result[taxonomy] }; + }) + return result; +} + +export function getAuctionsIdsFromTargeting(targeting, am = auctionManager) { + return Object.values(targeting) + .flatMap(x => Object.entries(x)) + .filter((entry) => entry[0] === TARGETING_KEYS.AD_ID || entry[0].startsWith(TARGETING_KEYS.AD_ID + '_')) + .flatMap(entry => entry[1]) + .map(adId => am.findBidByAdId(adId)?.auctionId) + .filter(id => id != null) + .filter(uniques); +} + export const appendGptSlots = adUnits => { const { customGptSlotMatching } = _currentConfig; @@ -113,6 +162,10 @@ export const appendPbAdSlot = adUnit => { return true; }; +function warnDeprecation(adUnit) { + logWarn(`pbadslot is deprecated and will soon be removed, use gpid instead`, adUnit) +} + export const makeBidRequestsHook = (fn, adUnits, ...args) => { appendGptSlots(adUnits); const { useDefaultPreAuction, customPreAuction } = _currentConfig; @@ -122,15 +175,18 @@ export const makeBidRequestsHook = (fn, adUnits, ...args) => { adUnit.ortb2Imp.ext = adUnit.ortb2Imp.ext || {}; adUnit.ortb2Imp.ext.data = adUnit.ortb2Imp.ext.data || {}; const context = adUnit.ortb2Imp.ext; - // if neither new confs set do old stuff if (!customPreAuction && !useDefaultPreAuction) { + warnDeprecation(adUnit); const usedAdUnitCode = appendPbAdSlot(adUnit); // gpid should be set to itself if already set, or to what pbadslot was (as long as it was not adUnit code) if (!context.gpid && !usedAdUnitCode) { context.gpid = context.data.pbadslot; } } else { + if (context.data?.pbadslot) { + warnDeprecation(adUnit); + } let adserverSlot = deepAccess(context, 'data.adserver.adslot'); let result; if (customPreAuction) { @@ -146,6 +202,14 @@ export const makeBidRequestsHook = (fn, adUnits, ...args) => { return fn.call(this, adUnits, ...args); }; +const setPpsConfigFromTargetingSet = (next, targetingSet) => { + // set gpt config + const auctionsIds = getAuctionsIdsFromTargeting(targetingSet); + const signals = getSignalsIntersection(getSignalsArrayByAuctionsIds(auctionsIds)); + window.googletag.setConfig && window.googletag.setConfig({pps: { taxonomies: signals }}); + next(targetingSet); +}; + const handleSetGptConfig = moduleConfig => { _currentConfig = pick(moduleConfig, [ 'enabled', enabled => enabled !== false, @@ -153,18 +217,20 @@ const handleSetGptConfig = moduleConfig => { typeof customGptSlotMatching === 'function' && customGptSlotMatching, 'customPbAdSlot', customPbAdSlot => typeof customPbAdSlot === 'function' && customPbAdSlot, 'customPreAuction', customPreAuction => typeof customPreAuction === 'function' && customPreAuction, - 'useDefaultPreAuction', useDefaultPreAuction => useDefaultPreAuction === true, + 'useDefaultPreAuction', useDefaultPreAuction => useDefaultPreAuction ?? true, ]); if (_currentConfig.enabled) { if (!hooksAdded) { getHook('makeBidRequests').before(makeBidRequestsHook); + getHook('targetingDone').after(setPpsConfigFromTargetingSet) hooksAdded = true; } } else { logInfo(`${MODULE_NAME}: Turning off module`); _currentConfig = {}; getHook('makeBidRequests').getHooks({hook: makeBidRequestsHook}).remove(); + getHook('targetingDone').getHooks({hook: setPpsConfigFromTargetingSet}).remove(); hooksAdded = false; } }; diff --git a/modules/greenbidsAnalyticsAdapter.js b/modules/greenbidsAnalyticsAdapter.js index d6293adac82..0aac98b453e 100644 --- a/modules/greenbidsAnalyticsAdapter.js +++ b/modules/greenbidsAnalyticsAdapter.js @@ -6,7 +6,7 @@ import {deepClone, generateUUID, logError, logInfo, logWarn, getParameterByName} const analyticsType = 'endpoint'; -export const ANALYTICS_VERSION = '2.2.1'; +export const ANALYTICS_VERSION = '2.3.0'; const ANALYTICS_SERVER = 'https://a.greenbids.ai'; @@ -116,6 +116,7 @@ export const greenbidsAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER bidder: bid.bidder, isTimeout: (status === BIDDER_STATUS.TIMEOUT), hasBid: (status === BIDDER_STATUS.BID), + params: (bid.params && Object.keys(bid.params).length > 0) ? bid.params : {}, }; }, addBidResponseToMessage(message, bid, status) { @@ -133,8 +134,11 @@ export const greenbidsAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER if (bidderIndex === -1) { message.adUnits[adUnitIndex].bidders.push(this.serializeBidResponse(bid, status)); } else { + message.adUnits[adUnitIndex].bidders[bidderIndex].params = (bid.params && Object.keys(bid.params).length > 0) ? bid.params : {}; if (status === BIDDER_STATUS.BID) { message.adUnits[adUnitIndex].bidders[bidderIndex].hasBid = true; + message.adUnits[adUnitIndex].bidders[bidderIndex].cpm = bid.cpm; + message.adUnits[adUnitIndex].bidders[bidderIndex].currency = bid.currency; } else if (status === BIDDER_STATUS.TIMEOUT) { message.adUnits[adUnitIndex].bidders[bidderIndex].isTimeout = true; } diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js index f7db6d878f1..4c1876dfb6f 100644 --- a/modules/gridBidAdapter.js +++ b/modules/gridBidAdapter.js @@ -15,6 +15,7 @@ import { Renderer } from '../src/Renderer.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; import { getStorageManager } from '../src/storageManager.js'; +import { getBidFromResponse } from '../libraries/processResponse/index.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -441,7 +442,7 @@ export const spec = { if (!errorMessage && serverResponse.seatbid) { serverResponse.seatbid.forEach(respItem => { - _addBidResponse(_getBidFromResponse(respItem), bidRequest, bidResponses, RendererConst, bidderCode); + _addBidResponse(getBidFromResponse(respItem, LOG_ERROR_MESS), bidRequest, bidResponses, RendererConst, bidderCode); }); } if (errorMessage) logError(errorMessage); @@ -512,17 +513,6 @@ function _getFloor (mediaTypes, bid) { return floor; } -function _getBidFromResponse(respItem) { - if (!respItem) { - logError(LOG_ERROR_MESS.emptySeatbid); - } else if (!respItem.bid) { - logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); - } else if (!respItem.bid[0]) { - logError(LOG_ERROR_MESS.noBid); - } - return respItem && respItem.bid && respItem.bid[0]; -} - function _addBidResponse(serverBid, bidRequest, bidResponses, RendererConst, bidderCode) { if (!serverBid) return; let errorMessage; diff --git a/modules/growthCodeAnalyticsAdapter.js b/modules/growthCodeAnalyticsAdapter.js index d2cd160a364..0b1f343e4dc 100644 --- a/modules/growthCodeAnalyticsAdapter.js +++ b/modules/growthCodeAnalyticsAdapter.js @@ -31,7 +31,7 @@ let analyticsType = 'endpoint'; let growthCodeAnalyticsAdapter = Object.assign(adapter({url: url, analyticsType}), { track({eventType, args}) { - let eventData = args ? JSON.parse(JSON.stringify(args)) : {}; + let eventData = args ? utils.deepClone(args) : {}; let data = {}; if (!trackEvents.includes(eventType)) return; switch (eventType) { @@ -140,7 +140,7 @@ function logToServer() { if (pid === DEFAULT_PID) return; if (eventQueue.length >= 1) { // Get the correct GCID - let gcid = localStorage.getItem('gcid') + let gcid = storage.getDataFromLocalStorage('gcid'); let data = { session: sessionId, diff --git a/modules/growthCodeRtdProvider.js b/modules/growthCodeRtdProvider.js index b12b25a0951..a8893b9648e 100644 --- a/modules/growthCodeRtdProvider.js +++ b/modules/growthCodeRtdProvider.js @@ -75,7 +75,7 @@ function callServer(configParams, items, expiresAt, userConsent) { storage.removeDataFromLocalStorage(RTD_EXPIRE_KEY, null) } if ((items === null) && (isNaN(expiresAt))) { - let gcid = localStorage.getItem('gcid') + let gcid = storage.getDataFromLocalStorage('gcid') let url = configParams.url ? configParams.url : ENDPOINT_URL; url = tryAppendQueryString(url, 'pid', configParams.pid); diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index b1ed98bc743..ecab3d0b970 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -215,11 +215,12 @@ function _getVidParams(attributes) { } /** - * Gets bidfloor - * @param {Object} mediaTypes - * @param {Number} bidfloor - * @param {Object} bid - * @returns {Number} floor + * Retrieves the bid floor value, which is the minimum acceptable bid for an ad unit. + * This function calculates the bid floor based on the given media types and other bidding parameters. + * @param {Object} mediaTypes - The media types specified for the bid, which might influence floor calculations. + * @param {number} staticBidFloor - The default or static bid floor set for the bid. + * @param {Object} bid - The bid object which may contain a method to get dynamic floor values. + * @returns {Object} An object containing the calculated bid floor and its currency. */ function _getFloor(mediaTypes, staticBidFloor, bid) { const curMediaType = Object.keys(mediaTypes)[0] || 'banner'; @@ -290,10 +291,10 @@ function getEids(userId) { } /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. + * Builds requests for bids. + * @param {validBidRequests[]} validBidRequests - An array of valid bid requests. + * @param {Object} bidderRequest - The bidder's request information. + * @returns {Object[]} An array of server requests. */ function buildRequests(validBidRequests, bidderRequest) { const bids = []; @@ -316,6 +317,7 @@ function buildRequests(validBidRequests, bidderRequest) { const { currency, floor } = _getFloor(mediaTypes, params.bidfloor, bidRequest); const eids = getEids(userId); const gpid = deepAccess(ortb2Imp, 'ext.gpid') || deepAccess(ortb2Imp, 'ext.data.pbadslot'); + const paapiEligible = deepAccess(ortb2Imp, 'ext.ae') === 1 let sizes = [1, 1]; let data = {}; data.displaymanager = 'Prebid.js - gumgum'; @@ -373,15 +375,12 @@ function buildRequests(validBidRequests, bidderRequest) { data.fp = floor; data.fpc = currency; } - + if (bidderRequest && bidderRequest.ortb2 && bidderRequest.ortb2.site) { + setIrisId(data, bidderRequest.ortb2.site, params); + } if (params.iriscat && typeof params.iriscat === 'string') { data.iriscat = params.iriscat; } - - if (params.irisid && typeof params.irisid === 'string') { - data.irisid = params.irisid; - } - if (params.zone || params.pubId) { params.zone ? (data.t = params.zone) : (data.pubId = params.pubId); @@ -405,7 +404,9 @@ function buildRequests(validBidRequests, bidderRequest) { } else { // legacy params data = { ...data, ...handleLegacyParams(params, sizes) }; } - + if (paapiEligible) { + data.ae = paapiEligible + } if (gdprConsent) { data.gdprApplies = gdprConsent.gdprApplies ? 1 : 0; } @@ -447,6 +448,27 @@ function buildRequests(validBidRequests, bidderRequest) { }); return bids; } +export function getCids(site) { + if (site.content && Array.isArray(site.content.data)) { + for (const dataItem of site.content.data) { + if (dataItem.name.includes('iris.com') || dataItem.name.includes('iris.tv')) { + return dataItem.ext.cids.join(','); + } + } + } + return null; +} +export function setIrisId(data, site, params) { + let irisID = getCids(site); + if (irisID) { + data.irisid = irisID; + } else { + // Just adding this chechk for safty and if needed we can remove + if (params.irisid && typeof params.irisid === 'string') { + data.irisid = params.irisid; + } + } +} function handleLegacyParams(params, sizes) { const data = {}; diff --git a/modules/hadronAnalyticsAdapter.js b/modules/hadronAnalyticsAdapter.js index d9fd4fa6f19..95a1dfaa5e2 100644 --- a/modules/hadronAnalyticsAdapter.js +++ b/modules/hadronAnalyticsAdapter.js @@ -53,7 +53,7 @@ let analyticsType = 'endpoint'; let hadronAnalyticsAdapter = Object.assign(adapter({url: HADRON_ANALYTICS_URL, analyticsType}), { track({eventType, args}) { - args = args ? JSON.parse(JSON.stringify(args)) : {}; + args = args ? utils.deepClone(args) : {}; var data = {}; if (!eventsToTrack.includes(eventType)) return; switch (eventType) { diff --git a/modules/hadronRtdProvider.js b/modules/hadronRtdProvider.js index 5c604709b4b..930e0922829 100644 --- a/modules/hadronRtdProvider.js +++ b/modules/hadronRtdProvider.js @@ -24,7 +24,7 @@ const SUBMODULE_NAME = 'hadron'; const AU_GVLID = 561; const HADRON_ID_DEFAULT_URL = 'https://id.hadron.ad.gt/api/v1/hadronid?_it=prebid'; const HADRON_SEGMENT_URL = 'https://id.hadron.ad.gt/api/v1/rtd'; -export const HALOID_LOCAL_NAME = 'auHadronId'; +export const HADRONID_LOCAL_NAME = 'auHadronId'; export const RTD_LOCAL_NAME = 'auHadronRtd'; export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME}); @@ -132,7 +132,6 @@ export function addRealTimeData(bidConfig, rtd, rtdConfig) { if (rtdConfig.params && rtdConfig.params.handleRtd) { rtdConfig.params.handleRtd(bidConfig, rtd, rtdConfig, config); } else { - // TODO: this and haloRtdProvider are a copy-paste of each other if (isPlainObject(rtd.ortb2)) { mergeLazy(bidConfig.ortb2Fragments?.global, rtd.ortb2); } @@ -165,9 +164,9 @@ export function getRealTimeData(bidConfig, onDone, rtdConfig, userConsent) { } } - const userIds = typeof getGlobal().getUserIds === 'function' ? (getGlobal()).getUserIds() : {}; + const userIds = {}; - let hadronId = storage.getDataFromLocalStorage(HALOID_LOCAL_NAME); + let hadronId = storage.getDataFromLocalStorage(HADRONID_LOCAL_NAME); if (isStr(hadronId)) { if (typeof getGlobal().refreshUserIds === 'function') { (getGlobal()).refreshUserIds({submoduleNames: 'hadronId'}); diff --git a/modules/holidBidAdapter.js b/modules/holidBidAdapter.js index f046c860562..c72d21d08b4 100644 --- a/modules/holidBidAdapter.js +++ b/modules/holidBidAdapter.js @@ -5,8 +5,6 @@ import { logMessage, triggerPixel, } from '../src/utils.js'; -import * as events from '../src/events.js'; -import { EVENTS } from '../src/constants.js'; import {BANNER} from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; @@ -19,8 +17,6 @@ const TIME_TO_LIVE = 300 const TMAX = 500 let wurlMap = {} -events.on(EVENTS.BID_WON, bidWonHandler) - export const spec = { code: BIDDER_CODE, gvlid: GVLID, @@ -120,6 +116,15 @@ export const spec = { return syncs }, + + onBidWon(bid) { + const wurl = getWurl(bid.requestId) + if (wurl) { + logMessage(`Invoking image pixel for wurl on BID_WIN: "${wurl}"`) + triggerPixel(wurl) + removeWurl(bid.requestId) + } + } } function getImp(bid) { @@ -176,13 +181,4 @@ function getWurl(requestId) { } } -function bidWonHandler(bid) { - const wurl = getWurl(bid.requestId) - if (wurl) { - logMessage(`Invoking image pixel for wurl on BID_WIN: "${wurl}"`) - triggerPixel(wurl) - removeWurl(bid.requestId) - } -} - registerBidder(spec) diff --git a/modules/id5AnalyticsAdapter.js b/modules/id5AnalyticsAdapter.js index 70da467ff7c..10fe8d82ef4 100644 --- a/modules/id5AnalyticsAdapter.js +++ b/modules/id5AnalyticsAdapter.js @@ -4,7 +4,6 @@ import adapterManager from '../src/adapterManager.js'; import { ajax } from '../src/ajax.js'; import { logInfo, logError } from '../src/utils.js'; import * as events from '../src/events.js'; -import {getGlobal} from '../src/prebidGlobal.js'; const { AUCTION_END, @@ -33,7 +32,7 @@ const FLUSH_EVENTS = [ const CONFIG_URL_PREFIX = 'https://api.id5-sync.com/analytics' const TZ = new Date().getTimezoneOffset(); -const PBJS_VERSION = getGlobal().version; +const PBJS_VERSION = 'v' + '$prebid.version$'; const ID5_REDACTED = '__ID5_REDACTED__'; const isArray = Array.isArray; diff --git a/modules/id5IdSystem.js b/modules/id5IdSystem.js index e7a7ec7f037..1f369f5a7a1 100644 --- a/modules/id5IdSystem.js +++ b/modules/id5IdSystem.js @@ -41,6 +41,7 @@ const LOCAL_STORAGE = 'html5'; const LOG_PREFIX = 'User ID - ID5 submodule: '; const ID5_API_CONFIG_URL = 'https://id5-sync.com/api/config/prebid'; const ID5_DOMAIN = 'id5-sync.com'; +const TRUE_LINK_SOURCE = 'true-link-id5-sync.com'; // order the legacy cookie names in reverse priority order so the last // cookie in the array is the most preferred to use @@ -134,12 +135,13 @@ export const id5IdSubmodule = { * @returns {(Object|undefined)} */ decode(value, config) { - let universalUid; + let universalUid, publisherTrueLinkId; let ext = {}; if (value && typeof value.universal_uid === 'string') { universalUid = value.universal_uid; ext = value.ext || ext; + publisherTrueLinkId = value.publisherTrueLinkId; } else { return undefined; } @@ -159,6 +161,12 @@ export const id5IdSubmodule = { }; } + if (publisherTrueLinkId) { + responseObj.trueLinkId = { + uid: publisherTrueLinkId, + }; + } + const abTestingResult = deepAccess(value, 'ab_testing.result'); switch (abTestingResult) { case 'control': @@ -263,7 +271,22 @@ export const id5IdSubmodule = { return data.ext; } } + }, + 'trueLinkId': { + getValue: function (data) { + return data.uid; + }, + getSource: function (data) { + return TRUE_LINK_SOURCE; + }, + atype: 1, + getUidExt: function (data) { + if (data.ext) { + return data.ext; + } + } } + } }; @@ -380,6 +403,8 @@ export class IdFetchFlow { const referer = getRefererInfo(); const signature = (this.cacheIdObj && this.cacheIdObj.signature) ? this.cacheIdObj.signature : getLegacyCookieSignature(); const nbPage = incrementAndResetNb(params.partner); + const trueLinkInfo = window.id5Bootstrap ? window.id5Bootstrap.getTrueLinkInfo() : {booted: false}; + const data = { 'partner': params.partner, 'gdpr': hasGdpr, @@ -392,7 +417,8 @@ export class IdFetchFlow { 'u': referer.stack[0] || window.location.href, 'v': '$prebid.version$', 'storage': this.submoduleConfig.storage, - 'localStorage': storage.localStorageIsEnabled() ? 1 : 0 + 'localStorage': storage.localStorageIsEnabled() ? 1 : 0, + 'true_link': trueLinkInfo }; // pass in optional data, but only if populated @@ -431,6 +457,9 @@ export class IdFetchFlow { try { if (fetchCallResponse.privacy) { storeInLocalStorage(ID5_PRIVACY_STORAGE_NAME, JSON.stringify(fetchCallResponse.privacy), NB_EXP_DAYS); + if (window.id5Bootstrap && window.id5Bootstrap.setPrivacy) { + window.id5Bootstrap.setPrivacy(fetchCallResponse.privacy); + } } } catch (error) { logError(LOG_PREFIX + 'Error while writing privacy info into local storage.', error); diff --git a/modules/id5IdSystem.md b/modules/id5IdSystem.md index 592c69056fa..a2782b70559 100644 --- a/modules/id5IdSystem.md +++ b/modules/id5IdSystem.md @@ -37,7 +37,7 @@ pbjs.setConfig({ type: 'html5', // "html5" is the required storage type name: 'id5id', // "id5id" is the required storage name expires: 90, // storage lasts for 90 days - refreshInSeconds: 8*3600 // refresh ID every 8 hours to ensure it's fresh + refreshInSeconds: 7200 // refresh ID every 2 hours to ensure it's fresh } }], auctionDelay: 50 // 50ms maximum auction delay, applies to all userId modules @@ -61,7 +61,7 @@ pbjs.setConfig({ | storage.type | Required | String | This is where the results of the user ID will be stored. ID5 **requires** `"html5"`. | `"html5"` | | storage.name | Required | String | The name of the local storage where the user ID will be stored. ID5 **requires** `"id5id"`. | `"id5id"` | | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. ID5 recommends `90`. | `90` | -| storage.refreshInSeconds | Optional | Integer | How many seconds until the ID5 ID will be refreshed. ID5 strongly recommends 8 hours between refreshes | `8*3600` | +| storage.refreshInSeconds | Optional | Integer | How many seconds until the ID5 ID will be refreshed. ID5 strongly recommends 2 hours between refreshes | `7200` | **ATTENTION:** As of Prebid.js v4.14.0, ID5 requires `storage.type` to be `"html5"` and `storage.name` to be `"id5id"`. Using other values will display a warning today, but in an upcoming release, it will prevent the ID5 module from loading. This change is to ensure the ID5 module in Prebid.js interoperates properly with the [ID5 API](https://github.com/id5io/id5-api.js) and to reduce the size of publishers' first-party cookies that are sent to their web servers. If you have any questions, please reach out to us at [prebid@id5.io](mailto:prebid@id5.io). @@ -73,3 +73,68 @@ To turn on A/B Testing, simply edit the configuration (see above table) to enabl ### A Note on Using Multiple Wrappers If you or your monetization partners are deploying multiple Prebid wrappers on your websites, you should make sure you add the ID5 ID User ID module to *every* wrapper. Only the bidders configured in the Prebid wrapper where the ID5 ID User ID module is installed and configured will be able to pick up the ID5 ID. Bidders from other Prebid instances will not be able to pick up the ID5 ID. + +### Provided eids +The module provides following eids: + +``` +[ + { + source: 'id5-sync.com', + uids: [ + { + id: 'some-random-id-value', + atype: 1, + ext: { + linkType: 2, + abTestingControlGroup: false + } + } + ] + }, + { + source: 'true-link-id5-sync.com', + uids: [ + { + id: 'some-publisher-true-link-id', + atype: 1 + } + ] + }, + { + source: 'uidapi.com', + uids: [ + { + id: 'some-uid2', + atype: 3, + ext: { + provider: 'id5-sync.com' + } + } + ] + } +] +``` + +The id from `id5-sync.com` should be always present (though the id provided will be '0' in case of no consent or optout) + +The id from `true-link-id5-sync.com` will be available if the page is integrated with TrueLink (if you are an ID5 partner you can learn more at https://wiki.id5.io/en/identitycloud/retrieve-id5-ids/true-link-integration) + +The id from `uidapi.com` will be available if the partner that is used in ID5 user module has the EUID2 integration enabled (it has to be enabled on the ID5 side) + + +### Providing TrueLinkId as a Google PPID + +TrueLinkId can be provided as a PPID - to use, it the `true-link-id5-sync.com` needs to be provided as a ppid source in prebid userSync configuration: + +```javascript +pbjs.setConfig({ + userSync: { + ppid: 'true-link-id5-sync.com', + userIds: [], //userIds modules should be configured here + } +}); +``` + + + diff --git a/modules/idImportLibrary.js b/modules/idImportLibrary.js index e1847edfce4..f6819a485e0 100644 --- a/modules/idImportLibrary.js +++ b/modules/idImportLibrary.js @@ -155,7 +155,7 @@ function handleTargetElement() { const targetElement = document.getElementById(conf.target); if (targetElement) { - email = targetElement.innerText; + email = targetElement.textContent; if (!email) { _logInfo('Finding the email with observer'); diff --git a/modules/idWardRtdProvider.js b/modules/idWardRtdProvider.js deleted file mode 100644 index 8e6e3c20a64..00000000000 --- a/modules/idWardRtdProvider.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * This module adds the ID Ward RTD provider to the real time data module - * The {@link module:modules/realTimeData} module is required - * The module will populate real-time data from ID Ward - * @module modules/idWardRtdProvider - * @requires module:modules/realTimeData - */ -import { createRtdProvider } from './anonymisedRtdProvider.js';/* eslint prebid/validate-imports: "off" */ - -export const { getRealTimeData, rtdSubmodule: idWardRtdSubmodule, storage } = createRtdProvider('idWard'); diff --git a/modules/idWardRtdProvider.md b/modules/idWardRtdProvider.md deleted file mode 100644 index 1c9f0654de6..00000000000 --- a/modules/idWardRtdProvider.md +++ /dev/null @@ -1,51 +0,0 @@ -> **Warning!** -> -> The **idWardRtdProvider** module has been renamed to [anonymisedRtdProvider](anonymisedRtdProvider.md) in light of the company's rebranding. -> **idWardRtdProvider** module is maintained for backward compatibility until the next major Prebid release. -> -> Please use anonymisedRtdProvider instead of idWardRtdProvider in your Prebid integration. - -### Overview - -ID Ward is a data anonymization technology for privacy-preserving advertising. Publishers and advertisers are able to target and retarget custom audience segments covering 100% of consented audiences. -ID Ward’s Real-time Data Provider automatically obtains segment IDs from the ID Ward on-domain script (via localStorage) and passes them to the bid-stream. - -### Integration - - 1) Build the idWardRtd module into the Prebid.js package with: - - ``` - gulp build --modules=idWardRtdProvider,... - ``` - - 2) Use `setConfig` to instruct Prebid.js to initilaize the idWardRtdProvider module, as specified below. - -### Configuration - -``` - pbjs.setConfig({ - realTimeData: { - dataProviders: [ - { - name: "idWard", - waitForIt: true, - params: { - cohortStorageKey: "cohort_ids", - segtax: , - } - } - ] - } - }); - ``` - -Please note that idWardRtdProvider should be integrated into the publisher website along with the [ID Ward Pixel](https://publishers-web.id-ward.com/pixel-integration). -Please reach out to Id Ward representative(support@id-ward.com) if you have any questions or need further help to integrate Prebid, idWardRtdProvider, and Id Ward Pixel - -### Testing -To view an example of available segments returned by Id Ward: -``` -‘gulp serve --modules=rtdModule,idWardRtdProvider,pubmaticBidAdapter -``` -and then point your browser at: -"http://localhost:9999/integrationExamples/gpt/idward_segments_example.html" \ No newline at end of file diff --git a/modules/illuminBidAdapter.js b/modules/illuminBidAdapter.js index 45b74bec5c9..0e76e471f4b 100644 --- a/modules/illuminBidAdapter.js +++ b/modules/illuminBidAdapter.js @@ -1,328 +1,27 @@ -import {_each, deepAccess, parseSizesInput, parseUrl, uniques, isFn} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {getStorageManager} from '../src/storageManager.js'; -import {config} from '../src/config.js'; +import { + isBidRequestValid, createUserSyncGetter, createInterpretResponseFn, createBuildRequestsFn +} from '../libraries/vidazooUtils/bidderUtils.js'; const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'illumin'; const BIDDER_VERSION = '1.0.0'; const GVLID = 149; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getTopWindowQueryParams() { - try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.illumin.com`; } -export function extractCID(params) { - return params.cId; -} - -export function extractPID(params) { - return params.pId; -} - -export function extractSubDomain(params) { - return params.subDomain; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const { - params, - bidId, - userId, - adUnitCode, - schain, - mediaTypes, - ortb2Imp, - bidderRequestId, - bidRequestsCount, - bidderRequestsCount, - bidderWinsCount - } = bid; - let {bidFloor, ext} = params; - const hashUrl = hashCode(topWindowUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const cId = extractCID(params); - const pId = extractPID(params); - const subDomain = extractSubDomain(params); - - const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid', deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', '')); - - if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - bidFloor = floorInfo.floor; - } - } +const buildRequests = createBuildRequestsFn(createDomain, null, storage, BIDDER_CODE, BIDDER_VERSION, false); - let data = { - url: encodeURIComponent(topWindowUrl), - uqs: getTopWindowQueryParams(), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - referrer: bidderRequest.refererInfo.ref, - adUnitCode: adUnitCode, - publisherId: pId, - sizes: sizes, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}`, - schain: schain, - mediaTypes: mediaTypes, - gpid: gpid, - transactionId: ortb2Imp?.ext?.tid, - bidderRequestId: bidderRequestId, - bidRequestsCount: bidRequestsCount, - bidderRequestsCount: bidderRequestsCount, - bidderWinsCount: bidderWinsCount, - bidderTimeout: bidderTimeout - }; - - appendUserIdsToRequestPayload(data, userId); - - const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); - - if (sua) { - data.sua = sua; - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest.gppConsent) { - data.gppString = bidderRequest.gppConsent.gppString; - data.gppSid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - data.gppString = bidderRequest.ortb2.regs.gpp; - data.gppSid = bidderRequest.ortb2.regs.gpp_sid; - } - - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data - }; - - _each(ext, (value, key) => { - dto.data['ext.' + key] = value; - }); - - return dto; -} - -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - _each(userIds, (userId, idSystemProviderName) => { - key = `uid.${idSystemProviderName}`; - - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - }); -} +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, false); -function buildRequests(validBidRequests, bidderRequest) { - const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const bidderTimeout = config.getConfig('bidderTimeout'); - const requests = []; - validBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - const {bidId} = request.data; - const {results} = serverResponse.body; - - let output = []; - - try { - results.forEach(result => { - const { - creativeId, - ad, - price, - exp, - width, - height, - currency, - metaData, - advertiserDomains, - mediaType = BANNER - } = result; - if (!ad || !price) { - return; - } - - const response = { - requestId: bidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - }; - - if (metaData) { - Object.assign(response, { - meta: metaData - }) - } else { - Object.assign(response, { - meta: { - advertiserDomains: advertiserDomains || [] - } - }) - } - - if (mediaType === BANNER) { - Object.assign(response, { - ad: ad, - }); - } else { - Object.assign(response, { - vastXml: ad, - mediaType: VIDEO - }); - } - output.push(response); - }); - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '') { - let syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - - const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); - const params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}` - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.illumin.com/api/sync/iframe/${params}` - }); - } - if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.illumin.com/api/sync/image/${params}` - }); - } - return syncs; -} - -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { - h = (h << 5) - h + s.charCodeAt(i++) | 0; - } - } - return prefix + h; -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { - } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); - storage.setDataInLocalStorage(key, data); - } catch (e) { - } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.illumin.com/api/sync/iframe', imageSyncUrl: 'https://sync.illumin.com/api/sync/image' +}); export const spec = { code: BIDDER_CODE, diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index c1108d779cb..ddf13caa833 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -3,8 +3,14 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {config} from '../src/config.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {Renderer} from '../src/Renderer.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +/** + * See https://github.com/prebid/Prebid.js/pull/8827 for details on linting exception + * ImproveDigital only imports after winning a bid and only if the creative cannot reach top + * Also see https://github.com/prebid/Prebid.js/issues/11656 + */ +// eslint-disable-next-line no-restricted-imports import {loadExternalScript} from '../src/adloader.js'; /** @@ -42,7 +48,7 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid(bid) { - return !!(bid && bid.params && (bid.params.placementId || (bid.params.placementKey && bid.params.publisherId))); + return !!(bid && bid.params && bid.params.placementId && bid.params.publisherId); }, /** @@ -136,14 +142,11 @@ export const CONVERTER = ortbConverter({ } const bidderParamsPath = context.extendMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; const placementId = bidRequest.params.placementId; - if (placementId) { - deepSetValue(imp, `${bidderParamsPath}.placementId`, placementId); - if (context.extendMode) { - deepSetValue(imp, 'ext.prebid.storedrequest.id', '' + placementId); - } - } else { - deepSetValue(imp, `${bidderParamsPath}.publisherId`, getBidIdParameter('publisherId', bidRequest.params)); - deepSetValue(imp, `${bidderParamsPath}.placementKey`, getBidIdParameter('placementKey', bidRequest.params)); + const publisherId = bidRequest.params.publisherId; + deepSetValue(imp, `${bidderParamsPath}.placementId`, placementId); + deepSetValue(imp, `${bidderParamsPath}.publisherId`, publisherId); + if (context.extendMode) { + deepSetValue(imp, 'ext.prebid.storedrequest.id', '' + placementId); } deepSetValue(imp, `${bidderParamsPath}.keyValues`, getBidIdParameter('keyValues', bidRequest.params) || undefined); @@ -206,9 +209,9 @@ export const CONVERTER = ortbConverter({ overrides: { imp: { banner(fillImpBanner, imp, bidRequest, context) { - // override to disregard banner.sizes if usePrebidSizes is not set + // override to disregard banner.sizes if usePrebidSizes is false if (!bidRequest.mediaTypes[BANNER]) return; - if (config.getConfig('improvedigital.usePrebidSizes') !== true) { + if (config.getConfig('improvedigital.usePrebidSizes') === false) { const banner = Object.assign({}, bidRequest.mediaTypes[BANNER], {sizes: null}); bidRequest = {...bidRequest, mediaTypes: {[BANNER]: banner}} } diff --git a/modules/improvedigitalBidAdapter.md b/modules/improvedigitalBidAdapter.md index 15602d11038..7206dd8ba7b 100644 --- a/modules/improvedigitalBidAdapter.md +++ b/modules/improvedigitalBidAdapter.md @@ -17,6 +17,7 @@ Module that connects to Improve Digital's demand sources { bidder: 'improvedigital', params: { + publisherId: 123, placementId:1053688 } } @@ -27,6 +28,7 @@ Module that connects to Improve Digital's demand sources bids: [{ bidder: 'improvedigital', params: { + publisherId: 123, placementId:1053689, keyValues: { testKey: ["testValue"] @@ -39,6 +41,7 @@ Module that connects to Improve Digital's demand sources bids: [{ bidder: 'improvedigital', params: { + publisherId: 123, placementId:1053687, size: { w:300, @@ -47,4 +50,4 @@ Module that connects to Improve Digital's demand sources } }] }]; -``` \ No newline at end of file +``` diff --git a/modules/insticatorBidAdapter.js b/modules/insticatorBidAdapter.js index 636c0162a02..1ddd9334dc4 100644 --- a/modules/insticatorBidAdapter.js +++ b/modules/insticatorBidAdapter.js @@ -439,6 +439,10 @@ function buildRequest(validBidRequests, bidderRequest) { deepSetValue(req, 'user.ext.consent', bidderRequest.gdprConsent.consentString); } + if (validBidRequests[0]?.params?.publisherId) { + deepSetValue(req, 'site.publisher.id', validBidRequests[0].params.publisherId); + } + return req; } diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js new file mode 100644 index 00000000000..10ce8097bf1 --- /dev/null +++ b/modules/intentIqAnalyticsAdapter.js @@ -0,0 +1,234 @@ +import { logInfo, logError } from '../src/utils.js'; +import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { config } from '../src/config.js'; +import { EVENTS } from '../src/constants.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; + +const MODULE_NAME = 'iiqAnalytics' +const analyticsType = 'endpoint'; +const defaultUrl = 'https://reports.intentiq.com/report'; +const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME }); +const prebidVersion = '$prebid.version$'; +export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000); + +const FIRST_PARTY_KEY = '_iiq_fdata'; +const FIRST_PARTY_DATA_KEY = '_iiq_fdata'; +const JSVERSION = 0.1 + +const PARAMS_NAMES = { + abTestGroup: 'abGroup', + pbPauseUntil: 'pbPauseUntil', + pbMonitoringEnabled: 'pbMonitoringEnabled', + isInTestGroup: 'isInTestGroup', + enhanceRequests: 'enhanceRequests', + wasSubscribedForPrebid: 'wasSubscribedForPrebid', + hadEids: 'hadEids', + ABTestingConfigurationSource: 'ABTestingConfigurationSource', + lateConfiguration: 'lateConfiguration', + jsversion: 'jsversion', + eidsNames: 'eidsNames', + requestRtt: 'rtt', + clientType: 'clientType', + adserverDeviceType: 'AdserverDeviceType', + terminationCause: 'terminationCause', + callCount: 'callCount', + manualCallCount: 'mcc', + pubprovidedidsFailedToregister: 'ppcc', + noDataCount: 'noDataCount', + profile: 'profile', + isProfileDeterministic: 'pidDeterministic', + siteId: 'sid', + hadEidsInLocalStorage: 'idls', + auctionStartTime: 'ast', + eidsReadTime: 'eidt', + agentId: 'aid', + auctionEidsLength: 'aeidln', + wasServerCalled: 'wsrvcll', + referrer: 'vrref', + isInBrowserBlacklist: 'inbbl', + prebidVersion: 'pbjsver', + partnerId: 'partnerId' +}; + +let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({ defaultUrl, analyticsType }), { + initOptions: { + lsValueInitialized: false, + partner: null, + fpid: null, + currentGroup: null, + dataInLs: null, + eidl: null, + lsIdsInitialized: false, + manualReport: false + }, + track({ eventType, args }) { + switch (eventType) { + case BID_WON: + bidWon(args); + break; + default: + break; + } + } +}); + +// Events needed +const { + BID_WON +} = EVENTS; + +function readData(key) { + try { + if (storage.hasLocalStorage()) { + return storage.getDataFromLocalStorage(key); + } + if (storage.cookiesAreEnabled()) { + return storage.getCookie(key); + } + } catch (error) { + logError(error); + } +} + +function initLsValues() { + if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized) return; + iiqAnalyticsAnalyticsAdapter.initOptions.fpid = JSON.parse(readData(FIRST_PARTY_KEY)); + let iiqArr = config.getConfig('userSync.userIds').filter(m => m.name == 'intentIqId'); + if (iiqArr && iiqArr.length > 0) iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized = true; + if (!iiqArr) iiqArr = []; + if (iiqArr.length == 0) { + iiqArr.push({ + 'params': { + 'partner': -1, + 'group': 'U' + } + }) + } + if (iiqArr && iiqArr.length > 0) { + if (iiqArr[0].params && iiqArr[0].params.partner && !isNaN(iiqArr[0].params.partner)) { + iiqAnalyticsAnalyticsAdapter.initOptions.partner = iiqArr[0].params.partner; + iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup = iiqAnalyticsAnalyticsAdapter.initOptions.fpid.group; + } + } +} + +function initReadLsIds() { + if (isNaN(iiqAnalyticsAnalyticsAdapter.initOptions.partner) || iiqAnalyticsAnalyticsAdapter.initOptions.partner == -1) return; + try { + iiqAnalyticsAnalyticsAdapter.initOptions.dataInLs = null; + let iData = readData(FIRST_PARTY_DATA_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner) + if (iData) { + iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized = true; + let pData = JSON.parse(iData); + iiqAnalyticsAnalyticsAdapter.initOptions.dataInLs = pData.data; + iiqAnalyticsAnalyticsAdapter.initOptions.eidl = pData.eidl || -1; + } + } catch (e) { + logError(e) + } +} + +function bidWon(args) { + if (!iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized) { initLsValues(); } + if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { initReadLsIds(); } + if (!iiqAnalyticsAnalyticsAdapter.initOptions.manualReport) { + ajax(constructFullUrl(preparePayload(args, true)), undefined, null, { method: 'GET' }); + } + + logInfo('IIQ ANALYTICS -> BID WON') +} + +function getRandom(start, end) { + return Math.floor((Math.random() * (end - start + 1)) + start); +} + +export function preparePayload(data) { + let result = getDefaultDataObject(); + + result[PARAMS_NAMES.partnerId] = iiqAnalyticsAnalyticsAdapter.initOptions.partner; + result[PARAMS_NAMES.prebidVersion] = prebidVersion; + result[PARAMS_NAMES.referrer] = getReferrer(); + + result[PARAMS_NAMES.abTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup; + + result[PARAMS_NAMES.isInTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup == 'A'; + + result[PARAMS_NAMES.agentId] = REPORTER_ID; + + fillPrebidEventData(data, result); + + fillEidsData(result); + + return result; +} + +function fillEidsData(result) { + if (iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { + result[PARAMS_NAMES.hadEidsInLocalStorage] = iiqAnalyticsAnalyticsAdapter.initOptions.eidl && iiqAnalyticsAnalyticsAdapter.initOptions.eidl > 0; + result[PARAMS_NAMES.auctionEidsLength] = iiqAnalyticsAnalyticsAdapter.initOptions.eidl || -1; + } +} + +function fillPrebidEventData(eventData, result) { + if (eventData.bidderCode) { result.bidderCode = eventData.bidderCode; } + if (eventData.cpm) { result.cpm = eventData.cpm; } + if (eventData.currency) { result.currency = eventData.currency; } + if (eventData.originalCpm) { result.originalCpm = eventData.originalCpm; } + if (eventData.originalCurrency) { result.originalCurrency = eventData.originalCurrency; } + if (eventData.status) { result.status = eventData.status; } + if (eventData.auctionId) { result.prebidAuctionId = eventData.auctionId; } + + result.biddingPlatformId = 1; + result.partnerAuctionId = 'BW'; +} + +function getDefaultDataObject() { + return { + 'inbbl': false, + 'pbjsver': prebidVersion, + 'partnerAuctionId': 'BW', + 'reportSource': 'pbjs', + 'abGroup': 'U', + 'jsversion': JSVERSION, + 'partnerId': -1, + 'biddingPlatformId': 1, + 'idls': false, + 'ast': -1, + 'aeidln': -1 + } +} + +function constructFullUrl(data) { + let report = [] + data = btoa(JSON.stringify(data)) + report.push(data) + return defaultUrl + '?pid=' + iiqAnalyticsAnalyticsAdapter.initOptions.partner + + '&mct=1' + + ((iiqAnalyticsAnalyticsAdapter.initOptions && iiqAnalyticsAnalyticsAdapter.initOptions.fpid) + ? '&iiqid=' + encodeURIComponent(iiqAnalyticsAnalyticsAdapter.initOptions.fpid.pcid) : '') + + '&agid=' + REPORTER_ID + + '&jsver=' + JSVERSION + + '&vrref=' + getReferrer() + + '&source=pbjs' + + '&payload=' + JSON.stringify(report) +} + +export function getReferrer() { + return document.referrer; +} + +iiqAnalyticsAnalyticsAdapter.originEnableAnalytics = iiqAnalyticsAnalyticsAdapter.enableAnalytics; + +iiqAnalyticsAnalyticsAdapter.enableAnalytics = function (myConfig) { + iiqAnalyticsAnalyticsAdapter.originEnableAnalytics(myConfig); // call the base class function +}; + +adapterManager.registerAnalyticsAdapter({ + adapter: iiqAnalyticsAnalyticsAdapter, + code: MODULE_NAME +}); + +export default iiqAnalyticsAnalyticsAdapter; diff --git a/modules/intentIqAnalyticsAdapter.md b/modules/intentIqAnalyticsAdapter.md new file mode 100644 index 00000000000..905d88a9b21 --- /dev/null +++ b/modules/intentIqAnalyticsAdapter.md @@ -0,0 +1,27 @@ +# Overview + +Module Name: iiqAnalytics +Module Type: Analytics Adapter +Maintainer: julian@intentiq.com + +# Description + +By using this Intent IQ adapter, you will be able to obtain comprehensive analytics and metrics regarding the performance of the Intent IQ Unified ID module. This includes how the module impacts your revenue, CPMs, and fill rates related to bidders and domains. + +## Intent IQ Universal ID Registration + +No registration for this module is required. + +## Intent IQ Universal IDConfiguration + +IMPORTANT: only effective when Intent IQ Universal ID module is installed and configured. [(How-To)](https://docs.prebid.org/dev-docs/modules/userid-submodules/intentiq.html) + +No additional configuration for this module is required. We will use the configuration provided for Intent IQ Universal IQ module. + +#### Example Configuration + +```js +pbjs.enableAnalytics({ + provider: 'iiqAnalytics' +}); +``` diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 109ea5c39c6..434caae7ffb 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -10,6 +10,9 @@ import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js' import { getStorageManager } from '../src/storageManager.js'; import { MODULE_TYPE_UID } from '../src/activities/modules.js'; +import { gppDataHandler, uspDataHandler } from '../src/consentHandler.js'; +import AES from 'crypto-js/aes.js'; +import Utf8 from 'crypto-js/enc-utf8.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -21,11 +24,31 @@ const PCID_EXPIRY = 365; const MODULE_NAME = 'intentIqId'; export const FIRST_PARTY_KEY = '_iiq_fdata'; -export var FIRST_PARTY_DATA_KEY = '_iiq_fdata'; - -export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); +export let FIRST_PARTY_DATA_KEY = '_iiq_fdata'; +export const WITH_IIQ = 'A'; +export const WITHOUT_IIQ = 'B'; +export const NOT_YET_DEFINED = 'U'; +export const OPT_OUT = 'O'; +export const BLACK_LIST = 'L'; +export const CLIENT_HINTS_KEY = '_iiq_ch'; +export const EMPTY = 'EMPTY' +export const VERSION = 0.1 +const encoderCH = { + brands: 0, + mobile: 1, + platform: 2, + architecture: 3, + bitness: 4, + model: 5, + platformVersion: 6, + wow64: 7, + fullVersionList: 8 +}; const INVALID_ID = 'INVALID_ID'; +const SUPPORTED_TYPES = ['html5', 'cookie'] + +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** * Generate standard UUID string @@ -42,16 +65,35 @@ function generateGUID() { } /** - * Read Intent IQ data from cookie or local storage + * Encrypts plaintext. + * @param {string} plainText The plaintext to encrypt. + * @returns {string} The encrypted text as a base64 string. + */ +export function encryptData(plainText) { + return AES.encrypt(plainText, MODULE_NAME).toString(); +} + +/** + * Decrypts ciphertext. + * @param {string} encryptedText The encrypted text as a base64 string. + * @returns {string} The decrypted plaintext. + */ +export function decryptData(encryptedText) { + const bytes = AES.decrypt(encryptedText, MODULE_NAME); + return bytes.toString(Utf8); +} + +/** + * Read Intent IQ data from local storage or cookie * @param key * @return {string} */ -export function readData(key) { +export function readData(key, allowedStorage) { try { - if (storage.hasLocalStorage()) { + if (storage.hasLocalStorage() && allowedStorage.includes('html5')) { return storage.getDataFromLocalStorage(key); } - if (storage.cookiesAreEnabled()) { + if (storage.cookiesAreEnabled() && allowedStorage.includes('cookie')) { return storage.getCookie(key); } } catch (error) { @@ -60,21 +102,20 @@ export function readData(key) { } /** - * Store Intent IQ data in either cookie or local storage + * Store Intent IQ data in cookie, local storage or both of them * expiration date: 365 days * @param key * @param {string} value IntentIQ ID value to sintentIqIdSystem_spec.jstore */ -function storeData(key, value, cookieStorageEnabled = false) { +export function storeData(key, value, allowedStorage) { try { logInfo(MODULE_NAME + ': storing data: key=' + key + ' value=' + value); - if (value) { - if (storage.hasLocalStorage()) { + if (storage.hasLocalStorage() && allowedStorage.includes('html5')) { storage.setDataInLocalStorage(key, value); } - const expiresStr = (new Date(Date.now() + (PCID_EXPIRY * (60 * 60 * 24 * 1000)))).toUTCString(); - if (storage.cookiesAreEnabled() && cookieStorageEnabled) { + if (storage.cookiesAreEnabled() && allowedStorage.includes('cookie')) { + const expiresStr = (new Date(Date.now() + (PCID_EXPIRY * (60 * 60 * 24 * 1000)))).toUTCString(); storage.setCookie(key, value, expiresStr, 'LAX'); } } @@ -83,10 +124,28 @@ function storeData(key, value, cookieStorageEnabled = false) { } } +/** + * Remove Intent IQ data from cookie or local storage + * @param key + */ + +export function removeDataByKey(key, allowedStorage) { + try { + if (storage.hasLocalStorage() && allowedStorage.includes('html5')) { + storage.removeDataFromLocalStorage(key); + } + if (storage.cookiesAreEnabled() && allowedStorage.includes('cookie')) { + const expiredDate = new Date(0).toUTCString(); + storage.setCookie(key, '', expiredDate, 'LAX'); + } + } catch (error) { + logError(error); + } +} + /** * Parse json if possible, else return null * @param data - * @param {object|null} */ function tryParse(data) { try { @@ -97,6 +156,125 @@ function tryParse(data) { } } +/** + * Convert GPP data to an object + * @param {Object} data + * @return {string} The JSON string representation of the input data. + */ +export function handleGPPData(data = {}) { + if (Array.isArray(data)) { + let obj = {}; + for (const element of data) { + obj = Object.assign(obj, element); + } + return JSON.stringify(obj); + } + return JSON.stringify(data); +} + +/** + * Detects the browser using either userAgent or userAgentData + * @return {string} The name of the detected browser or 'unknown' if unable to detect + */ +function detectBrowser() { + try { + if (navigator.userAgent) { + return detectBrowserFromUserAgent(navigator.userAgent); + } else if (navigator.userAgentData) { + return detectBrowserFromUserAgentData(navigator.userAgentData); + } + } catch (error) { + logError('Error detecting browser:', error); + } + return 'unknown'; +} + +/** + * Detects the browser from the user agent string + * @param {string} userAgent - The user agent string from the browser + * @return {string} The name of the detected browser or 'unknown' if unable to detect + */ +export function detectBrowserFromUserAgent(userAgent) { + const browserRegexPatterns = { + opera: /Opera|OPR/, + edge: /Edg/, + chrome: /Chrome|CriOS/, + safari: /Safari/, + firefox: /Firefox/, + ie: /MSIE|Trident/, + }; + + // Check for Chrome first to avoid confusion with Safari + if (browserRegexPatterns.chrome.test(userAgent)) { + return 'chrome'; + } + + // Now we can safely check for Safari + if (browserRegexPatterns.safari.test(userAgent) && !browserRegexPatterns.chrome.test(userAgent)) { + return 'safari'; + } + + // Check other browsers + for (const browser in browserRegexPatterns) { + if (browserRegexPatterns[browser].test(userAgent)) { + return browser; + } + } + + return 'unknown'; +} + +/** + * Detects the browser from the NavigatorUAData object + * @param {NavigatorUAData} userAgentData - The user agent data object from the browser + * @return {string} The name of the detected browser or 'unknown' if unable to detect + */ +export function detectBrowserFromUserAgentData(userAgentData) { + const brandNames = userAgentData.brands.map(brand => brand.brand); + + if (brandNames.includes('Microsoft Edge')) { + return 'edge'; + } else if (brandNames.includes('Opera')) { + return 'opera'; + } else if (brandNames.some(brand => brand === 'Chromium' || brand === 'Google Chrome')) { + return 'chrome'; + } + + return 'unknown'; +} + +/** + * Processes raw client hints data into a structured format. + * @param {object} clientHints - Raw client hints data + * @return {string} A JSON string of processed client hints or an empty string if no hints + */ +export function handleClientHints(clientHints) { + const chParams = {}; + for (const key in clientHints) { + if (clientHints.hasOwnProperty(key) && clientHints[key] !== '') { + if (['brands', 'fullVersionList'].includes(key)) { + let handledParam = ''; + clientHints[key].forEach((element, index) => { + const isNotLast = index < clientHints[key].length - 1; + handledParam += `"${element.brand}";v="${element.version}"${isNotLast ? ', ' : ''}`; + }); + chParams[encoderCH[key]] = handledParam; + } else if (typeof clientHints[key] === 'boolean') { + chParams[encoderCH[key]] = `?${clientHints[key] ? 1 : 0}`; + } else { + chParams[encoderCH[key]] = `"${clientHints[key]}"`; + } + } + } + return Object.keys(chParams).length ? JSON.stringify(chParams) : ''; +} + +function defineStorageType(params) { + if (!params || !Array.isArray(params)) return ['html5']; // use locale storage be default + const filteredArr = params.filter(item => SUPPORTED_TYPES.includes(item)); + return filteredArr.length ? filteredArr : ['html5']; +} + /** @type {Submodule} */ export const intentIqIdSubmodule = { /** @@ -120,25 +298,136 @@ export const intentIqIdSubmodule = { * @returns {IdResponse|undefined} */ getId(config) { - const configParams = (config && config.params) || {}; - if (!configParams || typeof configParams.partner !== 'number') { + const configParams = (config?.params) || {}; + let decryptedData, callbackTimeoutID; + let callbackFired = false + let runtimeEids = {} + + const firePartnerCallback = () => { + if (configParams.callback && !callbackFired) { + callbackFired = true; + if (callbackTimeoutID) clearTimeout(callbackTimeoutID); + configParams.callback(runtimeEids, firstPartyData?.group || NOT_YET_DEFINED); + } + } + + callbackTimeoutID = setTimeout(() => { + firePartnerCallback(); + }, configParams.timeoutInMillis || 500 + ); + + if (typeof configParams.partner !== 'number') { logError('User ID - intentIqId submodule requires a valid partner to be defined'); + firePartnerCallback() return; } - const cookieStorageEnabled = typeof configParams.enableCookieStorage === 'boolean' ? configParams.enableCookieStorage : false - if (!FIRST_PARTY_DATA_KEY.includes(configParams.partner)) { FIRST_PARTY_DATA_KEY += '_' + configParams.partner; } let rrttStrtTime = 0; + let partnerData = {}; + let shouldCallServer = false + + const currentBrowserLowerCase = detectBrowser(); + const browserBlackList = typeof configParams.browserBlackList === 'string' ? configParams.browserBlackList.toLowerCase() : ''; + const allowedStorage = defineStorageType(config.enabledStorageTypes); + + // Check if current browser is in blacklist + if (browserBlackList?.includes(currentBrowserLowerCase)) { + logError('User ID - intentIqId submodule: browser is in blacklist!'); + if (configParams.callback) configParams.callback('', BLACK_LIST); + return; + } + + // Get consent information + const cmpData = {}; + const uspData = uspDataHandler.getConsentData(); + const gppData = gppDataHandler.getConsentData(); + + if (uspData) { + cmpData.us_privacy = uspData; + } + + if (gppData) { + cmpData.gpp = ''; + cmpData.gpi = 1; + + if (gppData.parsedSections && 'usnat' in gppData.parsedSections) { + cmpData.gpp = handleGPPData(gppData.parsedSections['usnat']); + cmpData.gpi = 0 + } + cmpData.gpp_sid = gppData.applicableSections; + } + + // Read client hints from storage + let clientHints = readData(CLIENT_HINTS_KEY, allowedStorage); + + // Get client hints and save to storage + if (navigator.userAgentData) { + navigator.userAgentData + .getHighEntropyValues([ + 'brands', + 'mobile', + 'bitness', + 'wow64', + 'architecture', + 'model', + 'platform', + 'platformVersion', + 'fullVersionList' + ]) + .then(ch => { + clientHints = handleClientHints(ch); + storeData(CLIENT_HINTS_KEY, clientHints, allowedStorage) + }); + } + + if (!FIRST_PARTY_DATA_KEY.includes(configParams.partner)) { + FIRST_PARTY_DATA_KEY += '_' + configParams.partner; + } // Read Intent IQ 1st party id or generate it if none exists - let firstPartyData = tryParse(readData(FIRST_PARTY_KEY)); - if (!firstPartyData || !firstPartyData.pcid || firstPartyData.pcidDate) { + let firstPartyData = tryParse(readData(FIRST_PARTY_KEY, allowedStorage)); + + if (!firstPartyData?.pcid) { const firstPartyId = generateGUID(); - firstPartyData = { 'pcid': firstPartyId, 'pcidDate': Date.now() }; - storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), cookieStorageEnabled); + firstPartyData = { pcid: firstPartyId, pcidDate: Date.now(), group: NOT_YET_DEFINED, cttl: 0, uspapi_value: EMPTY, gpp_value: EMPTY, date: Date.now() }; + storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); + } else if (!firstPartyData.pcidDate) { + firstPartyData.pcidDate = Date.now(); + storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); + } + + const savedData = tryParse(readData(FIRST_PARTY_DATA_KEY, allowedStorage)) + if (savedData) { + partnerData = savedData; + } + + if (partnerData.data) { + if (partnerData.data.length) { // encrypted data + decryptedData = tryParse(decryptData(partnerData.data)); + runtimeEids = decryptedData; + } } - let partnerData = tryParse(readData(FIRST_PARTY_DATA_KEY)); - if (!partnerData) partnerData = {}; + if (!firstPartyData.cttl || Date.now() - firstPartyData.date > firstPartyData.cttl || firstPartyData.uspapi_value !== cmpData.us_privacy || firstPartyData.gpp_value !== cmpData.gpp) { + firstPartyData.uspapi_value = cmpData.us_privacy; + firstPartyData.gpp_value = cmpData.gpp; + firstPartyData.isOptedOut = false + firstPartyData.cttl = 0 + shouldCallServer = true; + partnerData.data = {} + storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); + storeData(FIRST_PARTY_DATA_KEY, JSON.stringify(partnerData), allowedStorage); + } else if (firstPartyData.isOptedOut) { + firePartnerCallback() + } + + if (firstPartyData.group === WITHOUT_IIQ || (firstPartyData.group !== WITHOUT_IIQ && runtimeEids && Object.keys(runtimeEids).length)) { + firePartnerCallback() + } + + if (!shouldCallServer) { + firePartnerCallback(); + return { id: runtimeEids }; + } // use protocol relative urls for http or https let url = `https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=${configParams.partner}&pt=17&dpn=1`; @@ -149,42 +438,97 @@ export const intentIqIdSubmodule = { url += (partnerData.cttl) ? '&cttl=' + encodeURIComponent(partnerData.cttl) : ''; url += (partnerData.rrtt) ? '&rrtt=' + encodeURIComponent(partnerData.rrtt) : ''; url += firstPartyData.pcidDate ? '&iiqpciddate=' + encodeURIComponent(firstPartyData.pcidDate) : ''; + url += cmpData.us_privacy ? '&pa=' + encodeURIComponent(cmpData.us_privacy) : ''; + url += cmpData.gpp ? '&gpv=' + encodeURIComponent(cmpData.gpp) : ''; + url += cmpData.gpi ? '&gpi=' + cmpData.gpi : ''; + url += clientHints ? '&uh=' + encodeURIComponent(clientHints) : ''; + url += VERSION ? '&jsver=' + VERSION : ''; + url += firstPartyData?.group ? '&testGroup=' + encodeURIComponent(firstPartyData.group) : ''; + + const storeFirstPartyData = () => { + storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); + storeData(FIRST_PARTY_DATA_KEY, JSON.stringify(partnerData), allowedStorage); + } const resp = function (callback) { const callbacks = { success: response => { let respJson = tryParse(response); // If response is a valid json and should save is true - if (respJson && respJson.ls) { - // Store pid field if found in response json - let shouldUpdateLs = false; - if ('pid' in respJson) { - firstPartyData.pid = respJson.pid; - shouldUpdateLs = true; + if (respJson) { + partnerData.date = Date.now(); + firstPartyData.date = Date.now(); + const defineEmptyDataAndFireCallback = () => { + respJson.data = partnerData.data = runtimeEids = {}; + removeDataByKey(FIRST_PARTY_DATA_KEY, allowedStorage) + firePartnerCallback() + callback() } + if (callbackTimeoutID) clearTimeout(callbackTimeoutID) if ('cttl' in respJson) { - partnerData.cttl = respJson.cttl; - shouldUpdateLs = true; + firstPartyData.cttl = respJson.cttl; + } else firstPartyData.cttl = 86400000; + + if ('tc' in respJson) { + partnerData.terminationCause = respJson.tc; + if (respJson.tc == 41) { + firstPartyData.group = WITHOUT_IIQ; + storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); + defineEmptyDataAndFireCallback(); + return; + } else { + firstPartyData.group = WITH_IIQ; + } } - // If should save and data is empty, means we should save as INVALID_ID - if (respJson.data == '') { - respJson.data = INVALID_ID; - } else { + if ('isOptedOut' in respJson) { + if (respJson.isOptedOut !== firstPartyData.isOptedOut) { + firstPartyData.isOptedOut = respJson.isOptedOut; + } + if (respJson.isOptedOut === true) { + firstPartyData.group = OPT_OUT; + storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); + defineEmptyDataAndFireCallback() + return; + } + } + if ('pid' in respJson) { + firstPartyData.pid = respJson.pid; + } + if ('ls' in respJson) { + if (respJson.ls === false) { + defineEmptyDataAndFireCallback(); + return + } + // If data is empty, means we should save as INVALID_ID + if (respJson.data == '') { + respJson.data = INVALID_ID; + } else { + // If data is a single string, assume it is an id with source intentiq.com + if (respJson.data && typeof respJson.data === 'string') { + respJson.data = { eids: [respJson.data] } + } + } partnerData.data = respJson.data; - shouldUpdateLs = true; } + if (rrttStrtTime && rrttStrtTime > 0) { partnerData.rrtt = Date.now() - rrttStrtTime; - shouldUpdateLs = true; } - if (shouldUpdateLs === true) { - partnerData.date = Date.now(); - storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), cookieStorageEnabled); - storeData(FIRST_PARTY_DATA_KEY, JSON.stringify(partnerData), cookieStorageEnabled); + + if (respJson.data?.eids) { + runtimeEids = respJson.data.eids + callback(respJson.data.eids); + firePartnerCallback() + const encryptedData = encryptData(JSON.stringify(respJson.data.eids)) + partnerData.data = encryptedData; + } else { + callback(); + firePartnerCallback() } - callback(respJson.data); + storeFirstPartyData(); } else { callback(); + firePartnerCallback() } }, error: error => { @@ -192,18 +536,32 @@ export const intentIqIdSubmodule = { callback(); } }; - if (partnerData.date && partnerData.cttl && partnerData.data && - Date.now() - partnerData.date < partnerData.cttl) { callback(partnerData.data); } else { - rrttStrtTime = Date.now(); - ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); - } + + ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); }; - return { callback: resp }; + const respObj = { callback: resp }; + if (runtimeEids?.length) respObj.id = runtimeEids; + return respObj }, eids: { 'intentIqId': { source: 'intentiq.com', - atype: 1 + atype: 1, + getSource: function (data) { + return data.source; + }, + getValue: function (data) { + if (data?.uids?.length) { + return data.uids[0].id + } + return null + }, + getUidExt: function (data) { + if (data?.uids?.length) { + return data.uids[0].ext; + } + return null + } }, } }; diff --git a/modules/intentIqIdSystem.md b/modules/intentIqIdSystem.md new file mode 100644 index 00000000000..74208169eaa --- /dev/null +++ b/modules/intentIqIdSystem.md @@ -0,0 +1,92 @@ +``` +Module Name: IntentIQ Id System +Module Type: Id System +Maintainer: julian@intentiq.com, dmytro.piskun@intentiq.com +usp_supported: true +gpp_sids: usnat +``` + +# Intent IQ Universal ID module + +By leveraging the Intent IQ identity graph, our module helps publishers, SSPs, and DSPs overcome the challenges of monetizing cookie-less inventory and preparing for a future without 3rd-party cookies. Our solution implements 1st-party data clustering and provides Intent IQ person IDs with over 90% coverage and unmatched accuracy in supported countries while remaining privacy-friendly and CCPA compliant. This results in increased CPMs, higher fill rates, and, ultimately, lifting overall revenue + +# All you need is a few basic steps to start using our solution. + +## Registration + +Navigate to [our portal ](https://www.intentiq.com/) and contact our team for partner ID. +check our [documentation](https://pbmodule.documents.intentiq.com/) to get more information about our solution and how utilze it's full potential + +## Integration + +``` +gulp build –modules=intentIqIdSystem +``` + +We recommend including the Intent IQ Analytics adapter module for improved visibility + +## Configuration + +### Parameters + +Please find below list of paramters that could be used in configuring Intent IQ Universal ID module + +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| ------------------------------ | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| name | Required | String | The name of this module: "intentIqId" | `"intentIqId"` | +| params | Required | Object | Details for IntentIqId initialization. | | +| params.partner | Required | Number | This is the partner ID value obtained from registering with IntentIQ. | `1177538` | +| params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | +| params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | +| params.callback | Required | Function | This is a callback which is trigered with data and AB group | `(data, group) => console.log({ data, group })` | +| params.timeoutInMillis | Optional | Number | This is the timeout in milliseconds, which defines the maximum duration before the callback is triggered. The default value is 500. | `450` | +| params.browserBlackList | Optional |  String | This is the name of a browser that can be added to a blacklist. | `"chrome"` | + +### Configuration example + +```javascript +pbjs.setConfig({ + userSync: { + userIds: [ + { + name: "intentIqId", + params: { + partner: 123456, // valid partner id + callback: (data, group) => window.pbjs.requestBids(), + }, + storage: { + type: "html5", + name: "intentIqId", // set localstorage with this name + expires: 60, + refreshInSeconds: 4 * 3600, // refresh ID every 4 hours to ensure it's fresh + }, + }, + ], + syncDelay: 3000, + }, +}); +``` + +```javascript +pbjs.setConfig({ + userSync: { + userIds: [{ + name: "intentIqId", + params: { + partner: 123456 // valid partner id + pcid: PCID_VARIABLE, // string value, dynamically loaded into a variable before setting the configuration + pai: PAI_VARIABLE , // string value, dynamically loaded into a variable before setting the configuration + timeoutInMillis: 500, + browserBlackList: "chrome", + callback: (data, group) => window.pbjs.requestBids() + }, + storage: { + type: "html5", + name: "intentIqId", // set localstorage with this name + expires: 60 + } + }], + syncDelay: 3000 + } +}); +``` diff --git a/modules/interactiveOffersBidAdapter.js b/modules/interactiveOffersBidAdapter.js index feb576fbb02..8d2f0a7734d 100644 --- a/modules/interactiveOffersBidAdapter.js +++ b/modules/interactiveOffersBidAdapter.js @@ -1,4 +1,4 @@ -import {isNumber, logWarn} from '../src/utils.js'; +import {deepClone, isNumber, logWarn} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER} from '../src/mediaTypes.js'; @@ -80,7 +80,7 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest, bidderRequest) { let pageURL = window.location.href; let domain = window.location.hostname; let secure = (window.location.protocol == 'https:' ? 1 : 0); - let openRTBRequest = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequest'])); + let openRTBRequest = deepClone(DEFAULT['OpenRTBBidRequest']); openRTBRequest.id = bidderRequest.bidderRequestId; openRTBRequest.ext = { // TODO: please do not send internal data structures over the network @@ -89,36 +89,36 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest, bidderRequest) { auctionId: prebidRequest.auctionId }; - openRTBRequest.site = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSite'])); + openRTBRequest.site = deepClone(DEFAULT['OpenRTBBidRequestSite']); openRTBRequest.site.id = domain; openRTBRequest.site.name = domain; openRTBRequest.site.domain = domain; openRTBRequest.site.page = pageURL; openRTBRequest.site.ref = prebidRequest.refererInfo.ref; - openRTBRequest.site.publisher = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSitePublisher'])); + openRTBRequest.site.publisher = deepClone(DEFAULT['OpenRTBBidRequestSitePublisher']); openRTBRequest.site.publisher.id = 0; openRTBRequest.site.publisher.name = prebidRequest.refererInfo.domain; openRTBRequest.site.publisher.domain = domain; openRTBRequest.site.publisher.domain = domain; - openRTBRequest.site.content = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSiteContent'])); + openRTBRequest.site.content = deepClone(DEFAULT['OpenRTBBidRequestSiteContent']); - openRTBRequest.source = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSource'])); + openRTBRequest.source = deepClone(DEFAULT['OpenRTBBidRequestSource']); openRTBRequest.source.fd = 0; openRTBRequest.source.tid = prebidRequest.ortb2?.source?.tid; openRTBRequest.source.pchain = ''; - openRTBRequest.device = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestDevice'])); + openRTBRequest.device = deepClone(DEFAULT['OpenRTBBidRequestDevice']); - openRTBRequest.user = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestUser'])); + openRTBRequest.user = deepClone(DEFAULT['OpenRTBBidRequestUser']); openRTBRequest.imp = []; prebidRequest.bids.forEach(function(bid) { if (!ret.partnerId) { ret.partnerId = bid.params.partnerId; } - let imp = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestImp'])); + let imp = deepClone(DEFAULT['OpenRTBBidRequestImp']); imp.id = bid.bidId; imp.secure = secure; imp.tagid = bid.adUnitCode; @@ -131,7 +131,7 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest, bidderRequest) { Object.keys(bid.mediaTypes).forEach(function(mediaType) { if (mediaType == 'banner') { - imp.banner = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestImpBanner'])); + imp.banner = deepClone(DEFAULT['OpenRTBBidRequestImpBanner']); imp.banner.w = 0; imp.banner.h = 0; imp.banner.format = []; @@ -156,7 +156,7 @@ function parseResponseOpenRTBToPrebidjs(openRTBResponse) { response.seatbid.forEach(function(seatbid) { if (seatbid.bid && seatbid.bid.forEach) { seatbid.bid.forEach(function(bid) { - let prebid = JSON.parse(JSON.stringify(DEFAULT['PrebidBid'])); + let prebid = deepClone(DEFAULT['PrebidBid']); prebid.requestId = bid.impid; prebid.ad = bid.adm; prebid.creativeId = bid.crid; diff --git a/modules/invisiblyAnalyticsAdapter.js b/modules/invisiblyAnalyticsAdapter.js index 24c2c452402..af21b1470f6 100644 --- a/modules/invisiblyAnalyticsAdapter.js +++ b/modules/invisiblyAnalyticsAdapter.js @@ -5,7 +5,7 @@ import { ajaxBuilder } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; -import { generateUUID, logInfo } from '../src/utils.js'; +import { deepClone, hasNonSerializableProperty, generateUUID, logInfo } from '../src/utils.js'; import { EVENTS } from '../src/constants.js'; const DEFAULT_EVENT_URL = 'https://api.pymx5.com/v1/' + 'sites/events'; @@ -133,7 +133,12 @@ function flush() { } function handleEvent(eventType, eventArgs) { - eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {}; + if (eventArgs) { + eventArgs = hasNonSerializableProperty(eventArgs) ? eventArgs : deepClone(eventArgs) + } else { + eventArgs = {} + } + let invisiblyEvent = {}; switch (eventType) { diff --git a/modules/iqmBidAdapter.js b/modules/iqmBidAdapter.js deleted file mode 100644 index c94a88748a7..00000000000 --- a/modules/iqmBidAdapter.js +++ /dev/null @@ -1,277 +0,0 @@ -import {_each, deepAccess, getBidIdParameter, isArray} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {INSTREAM} from '../src/video.js'; - -/** - * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest - */ - -const BIDDER_CODE = 'iqm'; -const VERSION = 'v.1.0.0'; -const VIDEO_ORTB_PARAMS = [ - 'mimes', - 'minduration', - 'maxduration', - 'placement', - 'protocols', - 'startdelay' -]; -var ENDPOINT_URL = 'https://pbd.bids.iqm.com'; - -export const spec = { - supportedMediaTypes: [BANNER, VIDEO], - code: BIDDER_CODE, - aliases: ['iqm'], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - const banner = deepAccess(bid, 'mediaTypes.banner'); - const videoMediaType = deepAccess(bid, 'mediaTypes.video'); - const context = deepAccess(bid, 'mediaTypes.video.context'); - if ((videoMediaType && context === INSTREAM)) { - const videoBidderParams = deepAccess(bid, 'params.video', {}); - - if (!Array.isArray(videoMediaType.playerSize)) { - return false; - } - - if (!videoMediaType.context) { - return false; - } - - const videoParams = { - ...videoMediaType, - ...videoBidderParams - }; - - if (!Array.isArray(videoParams.mimes) || videoParams.mimes.length === 0) { - return false; - } - - if (!Array.isArray(videoParams.protocols) || videoParams.protocols.length === 0) { - return false; - } - - if ( - typeof videoParams.placement !== 'undefined' && - typeof videoParams.placement !== 'number' - ) { - return false; - } - if ( - videoMediaType.context === INSTREAM && - typeof videoParams.startdelay !== 'undefined' && - typeof videoParams.startdelay !== 'number' - ) { - return false; - } - - return !!(bid && bid.params && bid.params.publisherId && bid.params.placementId); - } else { - if (banner === 'undefined') { - return false; - } - return !!(bid && bid.params && bid.params.publisherId && bid.params.placementId); - } - }, - /** - * Takes an array of valid bid requests, all of which are guaranteed to have passed the isBidRequestValid() test. - *It prepares a bid request with the required information for the DSP side and sends this request to alloted endpoint - * parameter{validBidRequests, bidderRequest} bidderRequest object is useful because it carries a couple of bid parameters that are global to all the bids. - */ - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map(bid => { - var finalRequest = {}; - let bidfloor = getBidIdParameter('bidfloor', bid.params); - - const imp = { - id: bid.bidId, - secure: 1, - bidfloor: bidfloor || 0, - displaymanager: 'Prebid.js', - displaymanagerver: VERSION, - - } - if (deepAccess(bid, 'mediaTypes.banner')) { - imp.banner = getSize(bid.sizes); - imp.mediatype = 'banner'; - } else if (deepAccess(bid, 'mediaTypes.video')) { - imp.video = _buildVideoORTB(bid); - imp.mediatype = 'video'; - } - const site = getSite(bidderRequest); - let device = getDevice(bid.params); - finalRequest = { - sizes: bid.sizes, - id: bid.bidId, - publisherId: getBidIdParameter('publisherId', bid.params), - placementId: getBidIdParameter('placementId', bid.params), - device: device, - site: site, - imp: imp, - // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 - auctionId: bid.auctionId, - adUnitCode: bid.adUnitCode, - bidderRequestId: bid.bidderRequestId, - uuid: bid.bidId, - // TODO: please do not send internal data structures over the network - // I am not going to attempt to accommodate this, no way this is usable on their end, it changes way too frequently - bidderRequest - } - const request = { - method: 'POST', - url: ENDPOINT_URL, - data: finalRequest, - options: { - withCredentials: false - }, - - } - return request; - }); - }, - /** - * Takes Response from server as input and request. - *It parses the response from server side and generates bidresponses for with required rendering paramteres - * parameter{serverResponse, bidRequest} serverReponse: Response from the server side with ad creative. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - serverResponse = serverResponse.body; - if (serverResponse && isArray(serverResponse.seatbid)) { - _each(serverResponse.seatbid, function (bidList) { - _each(bidList.bid, function (bid) { - const responseCPM = parseFloat(bid.price); - if (responseCPM > 0.0 && bid.impid) { - const bidResponse = { - requestId: bidRequest.data.id, - currency: serverResponse.cur || 'USD', - cpm: responseCPM, - netRevenue: true, - creativeId: bid.crid || '', - adUnitCode: bidRequest.data.adUnitCode, - auctionId: bidRequest.data.auctionId, - mediaType: bidRequest.data.imp.mediatype, - - ttl: bid.ttl || 60 - }; - - if (bidRequest.data.imp.mediatype === VIDEO) { - bidResponse.width = bid.w || bidRequest.data.imp.video.w; - bidResponse.height = bid.h || bidRequest.data.imp.video.h; - bidResponse.adResponse = { - content: bid.adm, - height: bidRequest.data.imp.video.h, - width: bidRequest.data.imp.video.w - }; - - if (bidRequest.data.imp.video.context === INSTREAM) { - bidResponse.vastUrl = bid.adm; - } - } else if (bidRequest.data.imp.mediatype === BANNER) { - bidResponse.ad = bid.adm; - bidResponse.width = bid.w || bidRequest.data.imp.banner.w; - bidResponse.height = bid.h || bidRequest.data.imp.banner.h; - } - bidResponses.push(bidResponse); - } - }) - }); - } - return bidResponses; - }, - -}; - -let getDevice = function (bidparams) { - const language = navigator.language ? 'language' : 'userLanguage'; - return { - geo: bidparams.geo, - h: screen.height, - w: screen.width, - dnt: _getDNT() ? 1 : 0, - language: navigator[language].split('-')[0], - make: navigator.vendor ? navigator.vendor : '', - ua: navigator.userAgent, - devicetype: _isMobile() ? 1 : _isConnectedTV() ? 3 : 2 - }; -}; - -let _getDNT = function () { - return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNotTrack === '1' || navigator.doNotTrack === 'yes'; -}; - -let getSize = function (sizes) { - let sizeMap; - if (sizes.length === 2 && typeof sizes[0] === 'number' && typeof sizes[1] === 'number') { - sizeMap = {w: sizes[0], h: sizes[1]}; - } else { - sizeMap = {w: sizes[0][0], h: sizes[0][1]}; - } - return sizeMap; -}; - -function _isMobile() { - return (/(ios|ipod|ipad|iphone|android)/i).test(global.navigator.userAgent); -} - -function _isConnectedTV() { - return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(global.navigator.userAgent); -} - -function getSite(bidderRequest) { - let domain = ''; - let page = ''; - let referrer = ''; - const Id = 1; - - const {refererInfo} = bidderRequest; - - // TODO: are these the right refererInfo values? - domain = refererInfo.domain; - page = refererInfo.page; - referrer = refererInfo.ref; - - return { - domain, - page, - Id, - referrer - }; -}; - -function _buildVideoORTB(bidRequest) { - const videoAdUnit = deepAccess(bidRequest, 'mediaTypes.video'); - const videoBidderParams = deepAccess(bidRequest, 'params.video', {}); - const video = {}; - - const videoParams = { - ...videoAdUnit, - ...videoBidderParams // Bidder Specific overrides - }; - video.context = 1; - const {w, h} = getSize(videoParams.playerSize[0]); - video.w = w; - video.h = h; - - VIDEO_ORTB_PARAMS.forEach((param) => { - if (videoParams.hasOwnProperty(param)) { - video[param] = videoParams[param]; - } - }); - - video.placement = video.placement || 2; - - video.startdelay = video.startdelay || 0; - video.placement = 1; - video.context = INSTREAM; - - return video; -} -registerBidder(spec); diff --git a/modules/iqzoneBidAdapter.js b/modules/iqzoneBidAdapter.js index 3ce622dba10..c03d579d2a5 100644 --- a/modules/iqzoneBidAdapter.js +++ b/modules/iqzoneBidAdapter.js @@ -1,239 +1,19 @@ -import { logMessage, logError, deepAccess } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'iqzone'; const AD_URL = 'https://smartssp-us-east.iqzone.com/pbjs'; const SYNC_URL = 'https://cs.smartssp.iqzone.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes, transactionId, userIdAsEids } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.plcmt = mediaTypes[VIDEO].plcmt; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - if (transactionId) { - placement.ext = placement.ext || {}; - placement.ext.tid = transactionId; - } - - if (userIdAsEids && userIdAsEids.length) { - placement.eids = userIdAsEids; - } - - return placement; -} - -function getBidFloor(bid) { - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0, - tmax: bidderRequest.timeout - }; - - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - - if (bidderRequest.gdprConsent) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { - syncUrl += '&gpp=' + gppConsent.gppString; - syncUrl += '&gpp_sid=' + gppConsent.applicableSections.join(','); - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 4fcf7830685..e182634b52a 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -26,7 +26,6 @@ import { Renderer } from '../src/Renderer.js'; import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; const BIDDER_CODE = 'ix'; -const ALIAS_BIDDER_CODE = 'roundel'; const GLOBAL_VENDOR_ID = 10; const SECURE_BID_URL = 'https://htlb.casalemedia.com/openrtb/pbjs'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO, NATIVE]; @@ -74,7 +73,6 @@ const SOURCE_RTI_MAPPING = { 'google.com': '' }; const PROVIDERS = [ - 'britepoolid', 'lipbid', 'criteoId', 'merkleId', @@ -696,11 +694,6 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { addRTI(userEids, eidInfo); } - // If `roundel` alias bidder, only send requests if liveramp ids exist. - if (bidderRequest && bidderRequest.bidderCode === ALIAS_BIDDER_CODE && !eidInfo.seenSources['liveramp.com']) { - return []; - } - const requests = []; let r = createRequest(validBidRequests); @@ -708,7 +701,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { r = addRequestedFeatureToggles(r, FEATURE_TOGGLES.REQUESTED_FEATURE_TOGGLES) // getting ixdiags for adunits of the video, outstream & multi format (MF) style - const fledgeEnabled = deepAccess(bidderRequest, 'fledgeEnabled') + const fledgeEnabled = deepAccess(bidderRequest, 'paapi.enabled') let ixdiag = buildIXDiag(validBidRequests, fledgeEnabled); for (let key in ixdiag) { r.ext.ixdiag[key] = ixdiag[key]; @@ -1439,7 +1432,7 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps, bidde bannerImps[validBidRequest.adUnitCode].pos = deepAccess(validBidRequest, 'mediaTypes.banner.pos'); // Add Fledge flag if enabled - const fledgeEnabled = deepAccess(bidderRequest, 'fledgeEnabled') + const fledgeEnabled = deepAccess(bidderRequest, 'paapi.enabled') if (fledgeEnabled) { const auctionEnvironment = deepAccess(validBidRequest, 'ortb2Imp.ext.ae') const paapi = deepAccess(validBidRequest, 'ortb2Imp.ext.paapi') @@ -1452,8 +1445,6 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps, bidde } else { logWarn('error setting auction environment flag - must be an integer') } - } else if (deepAccess(bidderRequest, 'defaultForSlots') == 1) { - bannerImps[validBidRequest.adUnitCode].ae = 1 } } @@ -1609,11 +1600,6 @@ export const spec = { code: BIDDER_CODE, gvlid: GLOBAL_VENDOR_ID, - aliases: [{ - code: ALIAS_BIDDER_CODE, - gvlid: GLOBAL_VENDOR_ID, - skipPbsAliasing: false - }], supportedMediaTypes: SUPPORTED_AD_TYPES, /** @@ -1865,7 +1851,7 @@ export const spec = { try { return { bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, }; } catch (error) { logWarn('Error attaching AuctionConfigs', error); diff --git a/modules/ixBidAdapter.md b/modules/ixBidAdapter.md index 0705c5932cf..f2f6d97daf9 100644 --- a/modules/ixBidAdapter.md +++ b/modules/ixBidAdapter.md @@ -472,7 +472,7 @@ The timeout value must be a positive whole number in milliseconds. Protected Audience API (FLEDGE) =========================== -In order to enable receiving [Protected Audience API](https://developer.chrome.com/en/docs/privacy-sandbox/fledge/) traffic, follow Prebid's documentation on [fledgeForGpt](https://docs.prebid.org/dev-docs/modules/fledgeForGpt.html) module to build and enable Fledge. +In order to enable receiving [Protected Audience API](https://developer.chrome.com/en/docs/privacy-sandbox/fledge/) traffic, follow Prebid's documentation on [paapiForGpt](https://docs.prebid.org/dev-docs/modules/paapiForGpt.html) module to build and enable Fledge. Additional Information ====================== diff --git a/modules/jwplayerBidAdapter.js b/modules/jwplayerBidAdapter.js index 151d08bf3a6..c58eed8ffb8 100644 --- a/modules/jwplayerBidAdapter.js +++ b/modules/jwplayerBidAdapter.js @@ -2,7 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO } from '../src/mediaTypes.js'; import { isArray, isFn, deepAccess, deepSetValue, getDNT, logError, logWarn } from '../src/utils.js'; import { config } from '../src/config.js'; -import { hasPurpose1Consent } from '../src/utils/gpdr.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; const BIDDER_CODE = 'jwplayer'; const BASE_URL = 'https://vpb-server.jwplayer.com/'; diff --git a/modules/jwplayerRtdProvider.js b/modules/jwplayerRtdProvider.js index 29ce0da5317..78c26cbda6a 100644 --- a/modules/jwplayerRtdProvider.js +++ b/modules/jwplayerRtdProvider.js @@ -12,7 +12,7 @@ import {submodule} from '../src/hook.js'; import {config} from '../src/config.js'; import {ajaxBuilder} from '../src/ajax.js'; -import {deepAccess, logError} from '../src/utils.js'; +import { deepAccess, logError, logWarn } from '../src/utils.js' import {find} from '../src/polyfill.js'; import {getGlobal} from '../src/prebidGlobal.js'; @@ -31,9 +31,7 @@ const playlistItemCache = {}; const pendingRequests = {}; let activeRequestCount = 0; let resumeBidRequest; -// defaults to 'always' for backwards compatibility -// TODO: Prebid 9 - replace with ENRICH_WHEN_EMPTY -let overrideContentId = ENRICH_ALWAYS; +let overrideContentId = ENRICH_WHEN_EMPTY; let overrideContentUrl = ENRICH_WHEN_EMPTY; let overrideContentTitle = ENRICH_WHEN_EMPTY; let overrideContentDescription = ENRICH_WHEN_EMPTY; @@ -83,9 +81,7 @@ export function fetchTargetingInformation(jwTargeting) { } export function setOverrides(params) { - // For backwards compatibility, default to always unless overridden by Publisher. - // TODO: Prebid 9 - replace with ENRICH_WHEN_EMPTY - overrideContentId = sanitizeOverrideParam(params.overrideContentId, ENRICH_ALWAYS); + overrideContentId = sanitizeOverrideParam(params.overrideContentId, ENRICH_WHEN_EMPTY); overrideContentUrl = sanitizeOverrideParam(params.overrideContentUrl, ENRICH_WHEN_EMPTY); overrideContentTitle = sanitizeOverrideParam(params.overrideContentTitle, ENRICH_WHEN_EMPTY); overrideContentDescription = sanitizeOverrideParam(params.overrideContentDescription, ENRICH_WHEN_EMPTY); @@ -433,17 +429,37 @@ export function addTargetingToBid(bid, targeting) { bid.rtd = Object.assign({}, rtd, jwRtd); } -function getPlayer(playerDivId) { +export function getPlayer(playerDivId) { const jwplayer = window.jwplayer; if (!jwplayer) { logError(SUBMODULE_NAME + '.js was not found on page'); return; } - const player = jwplayer(playerDivId); - if (!player || !player.getPlaylist) { - logError('player ID did not match any players'); + let player = jwplayer(playerDivId); + if (player && player.getPlaylist) { + return player; + } + + const playerOnPageCount = document.getElementsByClassName('jwplayer').length; + if (playerOnPageCount === 0) { + logError('No JWPlayer instances have been detected on the page'); return; } - return player; + + let errorMessage = `player Div ID ${playerDivId} did not match any players.`; + + // If there are multiple instances on the page, we cannot guess which one should be targeted. + if (playerOnPageCount > 1) { + logError(errorMessage); + return; + } + + player = jwplayer(); + if (player && player.getPlaylist) { + logWarn(`${errorMessage} Targeting player Div ID ${player.id} instead`); + return player; + } + + logError(errorMessage); } diff --git a/modules/jwplayerRtdProvider.md b/modules/jwplayerRtdProvider.md index 936cd1d10a2..44d696eea6d 100644 --- a/modules/jwplayerRtdProvider.md +++ b/modules/jwplayerRtdProvider.md @@ -12,16 +12,20 @@ Publishers must register JW Player as a real time data provider by setting up a following structure: ```javascript -const jwplayerDataProvider = { - name: "jwplayer" -}; - pbjs.setConfig({ ..., realTimeData: { - dataProviders: [ - jwplayerDataProvider - ] + dataProviders: [{ + name: 'jwplayer', + waitForIt: true, + params: { + mediaIDs: ['abc', 'def', 'ghi', 'jkl'], + overrideContentId: 'always', + overrideContentUrl: 'always', + overrideContentTitle: 'always', + overrideContentDescription: 'always' + } + }] } }); ``` @@ -86,7 +90,7 @@ realTimeData = { | waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false | | params | Object | | | | params.mediaIDs | Array of Strings | Media Ids for prefetching | Optional | -| params.overrideContentId | String enum: 'always', 'whenEmpty' or 'never' | Determines when the module should update the oRTB site.content.id | Defaults to 'always' | +| params.overrideContentId | String enum: 'always', 'whenEmpty' or 'never' | Determines when the module should update the oRTB site.content.id | Defaults to 'whenEmpty' | | params.overrideContentUrl | String enum: 'always', 'whenEmpty' or 'never' | Determines when the module should update the oRTB site.content.url | Defaults to 'whenEmpty' | | params.overrideContentTitle | String enum: 'always', 'whenEmpty' or 'never' | Determines when the module should update the oRTB site.content.title | Defaults to 'whenEmpty' | | params.overrideContentDescription | String enum: 'always', 'whenEmpty' or 'never' | Determines when the module should update the oRTB site.content.ext.description | Defaults to 'whenEmpty' | @@ -155,7 +159,7 @@ To view an example: - in your browser, navigate to: -`http://localhost:9999/integrationExamples/gpt/jwplayerRtdProvider_example.html` +`http://localhost:9999/integrationExamples/realTimeData/jwplayerRtdProvider_example.html` **Note:** the mediaIds in the example are placeholder values; replace them with your existing IDs. diff --git a/modules/jwplayerVideoProvider.js b/modules/jwplayerVideoProvider.js index ed6b69d756a..54de1949e6f 100644 --- a/modules/jwplayerVideoProvider.js +++ b/modules/jwplayerVideoProvider.js @@ -12,6 +12,12 @@ import stateFactory from '../libraries/video/shared/state.js'; import { JWPLAYER_VENDOR } from '../libraries/video/constants/vendorCodes.js'; import { getEventHandler } from '../libraries/video/shared/eventHandler.js'; import { submodule } from '../src/hook.js'; +/** + * @typedef {import('../libraries/video/constants/ortb.js').OrtbVideoParams} OrtbVideoParams + * @typedef {import('../libraries/video/shared/state.js').State} State + * @typedef {import('../modules/videoModule/coreVideo.js').VideoProvider} VideoProvider + * @typedef {import('../modules/videoModule/coreVideo.js').videoProviderConfig} videoProviderConfig + */ /** * @constructor diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js index cafbbd982fa..8429228d7af 100644 --- a/modules/kargoBidAdapter.js +++ b/modules/kargoBidAdapter.js @@ -48,7 +48,7 @@ const SUA_ATTRIBUTES = [ const CERBERUS = Object.freeze({ KEY: 'krg_crb', - SYNC_URL: 'https://crb.kargo.com/api/v1/initsyncrnd/{UUID}?seed={SEED}&idx={INDEX}&gdpr={GDPR}&gdpr_consent={GDPR_CONSENT}&us_privacy={US_PRIVACY}&gpp={GPP_STRING}&gpp_sid={GPP_SID}', + SYNC_URL: 'https://crb.kargo.com/api/v1/initsyncrnd/{UUID}?seed={SEED}&gdpr={GDPR}&gdpr_consent={GDPR_CONSENT}&us_privacy={US_PRIVACY}&gpp={GPP_STRING}&gpp_sid={GPP_SID}', SYNC_COUNT: 5, PAGE_VIEW_ID: 'pageViewId', PAGE_VIEW_TIMESTAMP: 'pageViewTimestamp', @@ -95,16 +95,13 @@ function buildRequests(validBidRequests, bidderRequest) { ] }, imp: impressions, - user: getUserIds(tdidAdapter, bidderRequest.uspConsent, bidderRequest.gdprConsent, firstBidRequest.userIdAsEids, bidderRequest.gppConsent) + user: getUserIds(tdidAdapter, bidderRequest.uspConsent, bidderRequest.gdprConsent, firstBidRequest.userIdAsEids, bidderRequest.gppConsent), + ext: getExtensions(firstBidRequest.ortb2, bidderRequest?.refererInfo) }); - // Add full ortb2 object as backup - if (firstBidRequest.ortb2) { - const siteCat = firstBidRequest.ortb2.site?.cat; - if (siteCat != null) { - krakenParams.site = { cat: siteCat }; - } - krakenParams.ext = { ortb2: firstBidRequest.ortb2 }; + // Add site.cat if it exists + if (firstBidRequest.ortb2?.site?.cat != null) { + krakenParams.site = { cat: firstBidRequest.ortb2.site.cat }; } // Add schain @@ -186,6 +183,10 @@ function buildRequests(validBidRequests, bidderRequest) { krakenParams.page = page; } + if (krakenParams.ext && Object.keys(krakenParams.ext).length === 0) { + delete krakenParams.ext; + } + return Object.assign({}, bidderRequest, { method: BIDDER.REQUEST_METHOD, url: `https://${BIDDER.HOST}${BIDDER.REQUEST_ENDPOINT}`, @@ -250,7 +251,7 @@ function interpretResponse(response, bidRequest) { if (fledgeAuctionConfigs.length > 0) { return { bids: bidResponses, - fledgeAuctionConfigs + paapi: fledgeAuctionConfigs } } else { return bidResponses; @@ -273,19 +274,16 @@ function getUserSyncs(syncOptions, _, gdprConsent, usPrivacy, gppConsent) { return syncs; } if (syncOptions.iframeEnabled && seed && clientId) { - for (let i = 0; i < CERBERUS.SYNC_COUNT; i++) { - syncs.push({ - type: 'iframe', - url: CERBERUS.SYNC_URL.replace('{UUID}', clientId) - .replace('{SEED}', seed) - .replace('{INDEX}', i) - .replace('{GDPR}', gdpr) - .replace('{GDPR_CONSENT}', gdprConsentString) - .replace('{US_PRIVACY}', usPrivacy || '') - .replace('{GPP_STRING}', gppString) - .replace('{GPP_SID}', gppApplicableSections) - }); - } + syncs.push({ + type: 'iframe', + url: CERBERUS.SYNC_URL.replace('{UUID}', clientId) + .replace('{SEED}', seed) + .replace('{GDPR}', gdpr) + .replace('{GDPR_CONSENT}', gdprConsentString) + .replace('{US_PRIVACY}', usPrivacy || '') + .replace('{GPP_STRING}', gppString) + .replace('{GPP_SID}', gppApplicableSections) + }) } return syncs; } @@ -300,6 +298,13 @@ function onTimeout(timeoutData) { }); } +function getExtensions(ortb2, refererInfo) { + const ext = {}; + if (ortb2) ext.ortb2 = ortb2; + if (refererInfo) ext.refererInfo = refererInfo; + return ext; +} + function _generateRandomUUID() { try { // crypto.getRandomValues is supported everywhere but Opera Mini for years diff --git a/modules/kiviadsBidAdapter.js b/modules/kiviadsBidAdapter.js index 13739d57cb2..161ddad470f 100644 --- a/modules/kiviadsBidAdapter.js +++ b/modules/kiviadsBidAdapter.js @@ -1,212 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'kiviads'; const AD_URL = 'https://lb.kiviads.com/pbjs'; const SYNC_URL = 'https://sync.kiviads.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: bidderRequest.coppa === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - gpp: bidderRequest.gppConsent || undefined, - tmax: bidderRequest.bidderTimeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/krushmediaBidAdapter.js b/modules/krushmediaBidAdapter.js index c4507201064..255e3670254 100644 --- a/modules/krushmediaBidAdapter.js +++ b/modules/krushmediaBidAdapter.js @@ -1,165 +1,40 @@ -import { isFn, deepAccess, logMessage } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { + isBidRequestValid, + buildRequestsBase, + interpretResponse, + getUserSyncs, + buildPlacementProcessingFunction, +} from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'krushmedia'; const AD_URL = 'https://ads4.krushmedia.com/?c=rtb&m=hb'; -const SYNC_URL = 'https://cs.krushmedia.com/html?src=pbjs' - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers); - default: - return false; +const SYNC_URL = 'https://cs.krushmedia.com'; + +const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => { + placement.key = bid.params.key; + placement.traffic = placement.adFormat; + if (placement.adFormat === VIDEO) { + placement.wPlayer = placement.playerSize?.[0]?.[0]; + placement.hPlayer = placement.playerSize?.[0]?.[1]; } -} +}; -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } +const placementProcessingFunction = buildPlacementProcessingFunction({ addCustomFieldsToPlacement }); - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + return buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction }); +}; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.key))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let winTop = window; - let location; - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page); - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; - - const placements = []; - const request = { - deviceWidth: winTop.screen.width, - deviceHeight: winTop.screen.height, - language: (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - secure: 1, - host: location.host, - page: location.pathname, - placements: placements - }; - - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent; - } - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - const placement = { - key: bid.params.key, - bidId: bid.bidId, - schain: bid.schain || {}, - bidFloor: getBidFloor(bid) - }; - - if (bid.mediaTypes && bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) { - placement.traffic = BANNER; - placement.sizes = bid.mediaTypes[BANNER].sizes; - } else if (bid.mediaTypes && bid.mediaTypes[VIDEO] && bid.mediaTypes[VIDEO].playerSize) { - placement.traffic = VIDEO; - placement.wPlayer = bid.mediaTypes[VIDEO].playerSize[0]; - placement.hPlayer = bid.mediaTypes[VIDEO].playerSize[1]; - placement.minduration = bid.mediaTypes[VIDEO].minduration; - placement.maxduration = bid.mediaTypes[VIDEO].maxduration; - placement.mimes = bid.mediaTypes[VIDEO].mimes; - placement.protocols = bid.mediaTypes[VIDEO].protocols; - placement.startdelay = bid.mediaTypes[VIDEO].startdelay; - placement.placement = bid.mediaTypes[VIDEO].placement; - placement.skip = bid.mediaTypes[VIDEO].skip; - placement.skipafter = bid.mediaTypes[VIDEO].skipafter; - placement.minbitrate = bid.mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = bid.mediaTypes[VIDEO].maxbitrate; - placement.delivery = bid.mediaTypes[VIDEO].delivery; - placement.playbackmethod = bid.mediaTypes[VIDEO].playbackmethod; - placement.api = bid.mediaTypes[VIDEO].api; - placement.linearity = bid.mediaTypes[VIDEO].linearity; - } else if (bid.mediaTypes && bid.mediaTypes[NATIVE]) { - placement.traffic = NATIVE; - placement.native = bid.mediaTypes[NATIVE]; - } - placements.push(placement); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncUrl = SYNC_URL - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - return [{ - type: 'iframe', - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(['key']), + buildRequests, + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/kueezBidAdapter.js b/modules/kueezBidAdapter.js index 5a5536e0c1a..63a01bfea02 100644 --- a/modules/kueezBidAdapter.js +++ b/modules/kueezBidAdapter.js @@ -417,6 +417,7 @@ function populateVideoParams(params, bid) { const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`); const minDuration = deepAccess(bid, `mediaTypes.video.minduration`); const placement = deepAccess(bid, `mediaTypes.video.placement`); + const plcmt = deepAccess(bid, `mediaTypes.video.plcmt`); const playbackMethod = getPlaybackMethod(bid); const skip = deepAccess(bid, `mediaTypes.video.skip`); @@ -435,7 +436,9 @@ function populateVideoParams(params, bid) { if (placement) { params.placement = placement; } - + if (plcmt) { + params.plcmt = plcmt; + } if (playbackMethod) { params.playbackMethod = playbackMethod; } diff --git a/modules/kueezRtbBidAdapter.js b/modules/kueezRtbBidAdapter.js index ba33f3ade9a..c0fb17672af 100644 --- a/modules/kueezRtbBidAdapter.js +++ b/modules/kueezRtbBidAdapter.js @@ -1,338 +1,43 @@ -import {_each, deepAccess, parseSizesInput, parseUrl, uniques, isFn} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {getStorageManager} from '../src/storageManager.js'; -import {config} from '../src/config.js'; +import { + createBuildRequestsFn, + createInterpretResponseFn, + createUserSyncGetter, + isBidRequestValid +} from '../libraries/vidazooUtils/bidderUtils.js'; const GVLID = 1165; const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'kueezrtb'; const BIDDER_VERSION = '1.0.0'; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getTopWindowQueryParams() { - try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.kueezrtb.com`; } -export function extractCID(params) { - return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; -} - -export function extractPID(params) { - return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; -} - -export function extractSubDomain(params) { - return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { +function createUniqueRequestData(hashUrl, bid) { const { - params, - bidId, - userId, - adUnitCode, - schain, - mediaTypes, auctionId, transactionId, - bidderRequestId, - bidRequestsCount, - bidderRequestsCount, - bidderWinsCount } = bid; - let {bidFloor, ext} = params; - const hashUrl = hashCode(topWindowUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const cId = extractCID(params); - const pId = extractPID(params); - const subDomain = extractSubDomain(params); - - const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', ''); - - if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - bidFloor = floorInfo.floor; - } - } - let data = { - url: encodeURIComponent(topWindowUrl), - uqs: getTopWindowQueryParams(), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - referrer: bidderRequest.refererInfo.ref, - adUnitCode: adUnitCode, - publisherId: pId, - sizes: sizes, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}`, - schain: schain, - mediaTypes: mediaTypes, - gpid: gpid, - // TODO: fix auctionId/transactionId leak: https://github.com/prebid/Prebid.js/issues/9781 - auctionId: auctionId, - transactionId: transactionId, - bidderRequestId: bidderRequestId, - bidRequestsCount: bidRequestsCount, - bidderRequestsCount: bidderRequestsCount, - bidderWinsCount: bidderWinsCount, - bidderTimeout: bidderTimeout - }; - - appendUserIdsToRequestPayload(data, userId); - - const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); - - if (sua) { - data.sua = sua; - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest.gppConsent) { - data.gppString = bidderRequest.gppConsent.gppString; - data.gppSid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - data.gppString = bidderRequest.ortb2.regs.gpp; - data.gppSid = bidderRequest.ortb2.regs.gpp_sid; - } - - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data + return { + auctionId, + transactionId, }; - - _each(ext, (value, key) => { - dto.data['ext.' + key] = value; - }); - - return dto; } -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - _each(userIds, (userId, idSystemProviderName) => { - key = `uid.${idSystemProviderName}`; +const buildRequests = createBuildRequestsFn(createDomain, createUniqueRequestData, storage, BIDDER_CODE, BIDDER_VERSION, false); - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - }); -} +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, false); -function buildRequests(validBidRequests, bidderRequest) { - const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const bidderTimeout = bidderRequest.timeout ?? config.getConfig('bidderTimeout'); - const requests = []; - validBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - const {bidId} = request.data; - const {results} = serverResponse.body; - - let output = []; - - try { - results.forEach(result => { - const { - creativeId, - ad, - price, - exp, - width, - height, - currency, - metaData, - advertiserDomains, - mediaType = BANNER - } = result; - if (!ad || !price) { - return; - } - - const response = { - requestId: bidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - }; - - if (metaData) { - Object.assign(response, { - meta: metaData - }) - } else { - Object.assign(response, { - meta: { - advertiserDomains: advertiserDomains || [] - } - }) - } - - if (mediaType === BANNER) { - Object.assign(response, { - ad: ad, - }); - } else { - Object.assign(response, { - vastXml: ad, - mediaType: VIDEO - }); - } - output.push(response); - }); - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '', gppConsent = {}) { - let syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - const {gppString, applicableSections} = gppConsent; - - const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); - let params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}` - - if (gppString && applicableSections?.length) { - params += '&gpp=' + encodeURIComponent(gppString); - params += '&gpp_sid=' + encodeURIComponent(applicableSections.join(',')); - } - - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.kueezrtb.com/api/sync/iframe/${params}` - }); - } - if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.kueezrtb.com/api/sync/image/${params}` - }); - } - return syncs; -} - -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { - h = (h << 5) - h + s.charCodeAt(i++) | 0; - } - } - return prefix + h; -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { - } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); - storage.setDataInLocalStorage(key, data); - } catch (e) { - } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.kueezrtb.com/api/sync/iframe', + imageSyncUrl: 'https://sync.kueezrtb.com/api/sync/image' +}); export const spec = { code: BIDDER_CODE, diff --git a/modules/liveIntentIdSystem.js b/modules/liveIntentIdSystem.js index 6925f5fd4a0..a9708910ca7 100644 --- a/modules/liveIntentIdSystem.js +++ b/modules/liveIntentIdSystem.js @@ -20,7 +20,7 @@ import { getRefererInfo } from '../src/refererDetection.js'; * @typedef {import('../modules/userId/index.js').SubmoduleConfig} SubmoduleConfig * @typedef {import('../modules/userId/index.js').IdResponse} IdResponse */ - +const GVLID = 148; const DEFAULT_AJAX_TIMEOUT = 5000; const EVENTS_TOPIC = 'pre_lips'; const MODULE_NAME = 'liveIntentId'; @@ -185,7 +185,7 @@ export const liveIntentIdSubmodule = { * @type {string} */ name: MODULE_NAME, - + gvlid: GVLID, setModuleMode(mode) { this.moduleMode = mode; }, diff --git a/modules/lkqdBidAdapter.js b/modules/lkqdBidAdapter.js index d4b1cdea0d1..6c97f64e6a8 100644 --- a/modules/lkqdBidAdapter.js +++ b/modules/lkqdBidAdapter.js @@ -47,7 +47,7 @@ export const spec = { const GDPR = BIDDER_GDPR || bid.params.gdpr || null; const GDPRS = BIDDER_GDPRS || bid.params.gdprs || null; const DNT = bid.params.dnt || null; - const BID_FLOOR = bid.params.flrd > bid.params.flrmp ? bid.params.flrd : bid.params.flrmp; + const BID_FLOOR = 0; const VIDEO_BID = bid.video ? bid.video : {}; const requestData = { @@ -157,7 +157,6 @@ export const spec = { h: sizes[1], skip: VIDEO_BID.skip || 0, playbackmethod: VIDEO_BID.playbackmethod || [1], - placement: (bid.params.execution === 'outstream' || VIDEO_BID.context === 'outstream') ? 5 : 1, ext: { lkqdcustomparameters: {} }, diff --git a/modules/loganBidAdapter.js b/modules/loganBidAdapter.js index 7aa82e3046c..bec23cddc2d 100644 --- a/modules/loganBidAdapter.js +++ b/modules/loganBidAdapter.js @@ -99,6 +99,7 @@ export const spec = { placement.protocols = mediaType[VIDEO].protocols; placement.startdelay = mediaType[VIDEO].startdelay; placement.placement = mediaType[VIDEO].placement; + placement.plcmt = mediaType[VIDEO].plcmt; placement.skip = mediaType[VIDEO].skip; placement.skipafter = mediaType[VIDEO].skipafter; placement.minbitrate = mediaType[VIDEO].minbitrate; diff --git a/modules/logicadBidAdapter.js b/modules/logicadBidAdapter.js index fe4dd83c9e2..e7c5300d072 100644 --- a/modules/logicadBidAdapter.js +++ b/modules/logicadBidAdapter.js @@ -46,7 +46,7 @@ export const spec = { if (fledgeAuctionConfigs.length) { return { bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, }; } @@ -74,7 +74,7 @@ function newBidRequest(bidRequest, bidderRequest) { mediaTypes: bidRequest.mediaTypes, } - const fledgeEnabled = deepAccess(bidderRequest, 'fledgeEnabled') + const fledgeEnabled = deepAccess(bidderRequest, 'paapi.enabled') if (fledgeEnabled) { const ae = deepAccess(bidRequest, 'ortb2Imp.ext.ae'); if (ae) { diff --git a/modules/loyalBidAdapter.js b/modules/loyalBidAdapter.js index 30fdeb44233..e34ec89cf35 100644 --- a/modules/loyalBidAdapter.js +++ b/modules/loyalBidAdapter.js @@ -1,190 +1,17 @@ -import { logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'loyal'; const AD_URL = 'https://us-east-1.loyal.app/pbjs'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor, - eids: [] - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - tmax: bidderRequest.timeout - }; - - if (bidderRequest.gdprConsent?.consentString) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse }; registerBidder(spec); diff --git a/modules/luceadBidAdapter.js b/modules/luceadBidAdapter.js index b95dfc08732..ffc2307bcb8 100755 --- a/modules/luceadBidAdapter.js +++ b/modules/luceadBidAdapter.js @@ -134,7 +134,7 @@ function interpretResponse(serverResponse, bidRequest) { } })); - return {bids, fledgeAuctionConfigs}; + return {bids, paapi: fledgeAuctionConfigs}; } function report(type, data) { diff --git a/modules/lunamediahbBidAdapter.js b/modules/lunamediahbBidAdapter.js index 66838014e18..6ad42a4f3ca 100644 --- a/modules/lunamediahbBidAdapter.js +++ b/modules/lunamediahbBidAdapter.js @@ -1,140 +1,19 @@ -import { logMessage } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'lunamediahb'; const AD_URL = 'https://balancer.lmgssp.com/?c=o&m=multi'; const SYNC_URL = 'https://cookie.lmgssp.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl) || Boolean(bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers); - default: - return false; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let winTop = window; - let location; - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page) - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; - - const placements = []; - const request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - const placement = { - placementId: bid.params.placementId, - bidId: bid.bidId, - schain: bid.schain || {}, - }; - const mediaType = bid.mediaTypes - - if (mediaType && mediaType[BANNER] && mediaType[BANNER].sizes) { - placement.sizes = mediaType[BANNER].sizes; - placement.traffic = BANNER; - } else if (mediaType && mediaType[VIDEO]) { - if (mediaType[VIDEO].playerSize) { - placement.wPlayer = mediaType[VIDEO].playerSize[0]; - placement.hPlayer = mediaType[VIDEO].playerSize[1]; - } - placement.traffic = VIDEO; - placement.videoContext = mediaType[VIDEO].context || 'instream' - } else if (mediaType && mediaType[NATIVE]) { - placement.native = mediaType[NATIVE]; - placement.traffic = NATIVE; - } - placements.push(placement); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/luponmediaBidAdapter.js b/modules/luponmediaBidAdapter.js index 2c08ca3a435..447257f97da 100755 --- a/modules/luponmediaBidAdapter.js +++ b/modules/luponmediaBidAdapter.js @@ -9,7 +9,9 @@ import { logError, logMessage, logWarn, - parseSizesInput + parseSizesInput, + sizeTupleToRtbSize, + sizesToSizeTuples } from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {config} from '../src/config.js'; @@ -271,16 +273,8 @@ function newOrtbBidRequest(bidRequest, bidderRequest, currentImps) { let bannerSizes = []; if (bannerParams && bannerParams.sizes) { - const sizes = parseSizesInput(bannerParams.sizes); - // get banner sizes in form [{ w: , h: }, ...] - const format = sizes.map(size => { - const [ width, height ] = size.split('x'); - const w = parseInt(width, 10); - const h = parseInt(height, 10); - return { w, h }; - }); - + const format = sizesToSizeTuples(bannerParams.sizes).map(sizeTupleToRtbSize); bannerSizes = format; } diff --git a/modules/mabidderBidAdapter.js b/modules/mabidderBidAdapter.js index 8d97f48f604..6df68bda269 100644 --- a/modules/mabidderBidAdapter.js +++ b/modules/mabidderBidAdapter.js @@ -1,6 +1,5 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import { getGlobal } from '../src/prebidGlobal.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const BIDDER_CODE = 'mabidder'; @@ -39,7 +38,7 @@ export const spec = { url: baseUrl, method: 'POST', data: { - v: getGlobal().version, + v: 'v' + '$prebid.version$', bids: bids, url: bidderRequest.refererInfo.page || '', referer: bidderRequest.refererInfo.ref || '', diff --git a/modules/madvertiseBidAdapter.js b/modules/madvertiseBidAdapter.js index 3b031623aef..9fc7ceb68aa 100644 --- a/modules/madvertiseBidAdapter.js +++ b/modules/madvertiseBidAdapter.js @@ -1,5 +1,4 @@ import { parseSizesInput, _each } from '../src/utils.js'; -import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; /** @@ -27,9 +26,6 @@ export const spec = { if (sizes.length > 0 && sizes[0] === undefined) { return false; } - if (typeof bid.params.floor == 'undefined' || parseFloat(bid.params.floor) < 0.01) { - bid.params.floor = 0.01; - } return typeof bid.params.s != 'undefined'; }, @@ -58,7 +54,7 @@ export const spec = { } if (bidderRequest && bidderRequest.gdprConsent) { - src = src + '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? '1' : '0') + '&consent[0][format]=' + config.getConfig('consentManagement.cmpApi') + '&consent[0][value]=' + bidderRequest.gdprConsent.consentString; + src = src + '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? '1' : '0') + '&consent[0][format]=iab&consent[0][value]=' + bidderRequest.gdprConsent.consentString; } return { diff --git a/modules/magniteAnalyticsAdapter.js b/modules/magniteAnalyticsAdapter.js index 225607ad6d3..dd16baed66e 100644 --- a/modules/magniteAnalyticsAdapter.js +++ b/modules/magniteAnalyticsAdapter.js @@ -47,13 +47,13 @@ const pbsErrorMap = { 4: 'request-error', 999: 'generic-error' } -let cookieless; let browser; let pageReferer; let auctionIndex = 0; // count of auctions on page let accountId; let endpoint; +let cookieless; let prebidGlobal = getGlobal(); const { @@ -334,9 +334,9 @@ const getTopLevelDetails = () => { // Add DM wrapper details if (rubiConf.wrapperName) { - let rule; + let rule = rubiConf.rule_name; if (cookieless) { - rule = rubiConf.rule_name ? rubiConf.rule_name.concat('_cookieless') : 'cookieless'; + rule = rule ? rule.concat('_cookieless') : 'cookieless'; } payload.wrapper = { name: rubiConf.wrapperName, @@ -703,6 +703,7 @@ magniteAdapter.disableAnalytics = function () { magniteAdapter._oldEnable = enableMgniAnalytics; endpoint = undefined; accountId = undefined; + cookieless = undefined; auctionIndex = 0; resetConfs(); getHook('callPrebidCache').getHooks({ hook: callPrebidCacheHook }).remove(); diff --git a/modules/marsmediaAnalyticsAdapter.js b/modules/marsmediaAnalyticsAdapter.js deleted file mode 100644 index f1e53a3c20c..00000000000 --- a/modules/marsmediaAnalyticsAdapter.js +++ /dev/null @@ -1,53 +0,0 @@ -import {ajax} from '../src/ajax.js'; -import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import {getGlobal} from '../src/prebidGlobal.js'; - -/**** - * Mars Media Analytics - * Contact: prebid@m-m-g.com‏ - * Developer: Chen Saadia - */ - -const MARS_BIDDER_CODE = 'marsmedia'; -const analyticsType = 'endpoint'; -const MARS_VERSION = '1.0.1'; -const MARS_ANALYTICS_URL = 'https://prebid_stats.mars.media/prebidjs/api/analytics.php'; -var events = {}; - -var marsmediaAnalyticsAdapter = Object.assign(adapter( - { - MARS_ANALYTICS_URL, - analyticsType - }), -{ - track({eventType, args}) { - if (typeof args !== 'undefined' && args.bidderCode === MARS_BIDDER_CODE) { - events[eventType] = args; - } - - if (eventType === 'auctionEnd') { - setTimeout(function() { - ajax( - MARS_ANALYTICS_URL, - { - success: function() {}, - error: function() {} - }, - JSON.stringify({act: 'prebid_analytics', params: events, 'pbjs': getGlobal().getBidResponses(), ver: MARS_VERSION}), - { - method: 'POST' - } - ); - }, 3000); - } - } -} -); - -adapterManager.registerAnalyticsAdapter({ - adapter: marsmediaAnalyticsAdapter, - code: 'marsmedia' -}); - -export default marsmediaAnalyticsAdapter; diff --git a/modules/mathildeadsBidAdapter.js b/modules/mathildeadsBidAdapter.js index 929cee8f3c0..0ecfe63765b 100644 --- a/modules/mathildeadsBidAdapter.js +++ b/modules/mathildeadsBidAdapter.js @@ -1,212 +1,19 @@ -import { isFn, deepAccess, logMessage } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'mathildeads'; const AD_URL = 'https://endpoint2.mathilde-ads.com/pbjs'; const SYNC_URL = 'https://cs2.mathilde-ads.com'; -function isBidResponseValid (bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency || !bid.meta) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData (bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - placementId, - bidId, - schain, - bidfloor - }; - - if (mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } - - if (mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } - - if (mediaTypes[NATIVE]) { - placement.adFormat = NATIVE; - placement.native = mediaTypes[NATIVE]; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && params.placementId); - - if (mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } - - if (mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } - - if (mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } - - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest?.refererInfo?.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/mediafuseBidAdapter.js b/modules/mediafuseBidAdapter.js index d969314f406..b70d2bf30a5 100644 --- a/modules/mediafuseBidAdapter.js +++ b/modules/mediafuseBidAdapter.js @@ -24,7 +24,7 @@ import {find, includes} from '../src/polyfill.js'; import {INSTREAM, OUTSTREAM} from '../src/video.js'; import {getStorageManager} from '../src/storageManager.js'; import {bidderSettings} from '../src/bidderSettings.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; import {APPNEXUS_CATEGORY_MAPPING} from '../libraries/categoryTranslationMapping/index.js'; import { @@ -729,7 +729,7 @@ function bidToTag(bid) { if (!isEmpty(bid.params.keywords)) { tag.keywords = getANKewyordParamFromMaps(bid.params.keywords); } - let gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); + let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); if (gpid) { tag.gpid = gpid; } @@ -1036,7 +1036,7 @@ function hideSASIframe(elementId) { function outstreamRender(bid) { hidedfpContainer(bid.adUnitCode); hideSASIframe(bid.adUnitCode); - // push to render queue because ANOutstreamVideo may not be loaded yet + // push to render queue because ANOutstreamVideo may not be loaded bid.renderer.push(() => { window.ANOutstreamVideo.renderAd({ tagId: bid.adResponse.tag_id, diff --git a/modules/mediagoBidAdapter.js b/modules/mediagoBidAdapter.js index 8f687d30ff3..5c6c62b95fe 100644 --- a/modules/mediagoBidAdapter.js +++ b/modules/mediagoBidAdapter.js @@ -5,6 +5,11 @@ import * as utils from '../src/utils.js'; import { getStorageManager } from '../src/storageManager.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getPageTitle, getPageDescription, getPageKeywords, getConnectionDownLink, getReferrer } from '../libraries/fpdUtils/pageInfo.js'; +import { getDevice } from '../libraries/fpdUtils/deviceInfo.js'; +import { getBidFloor } from '../libraries/currencyUtils/floor.js'; +import { transformSizes, normalAdSize } from '../libraries/sizeUtils/tranformSize.js'; + // import { config } from '../src/config.js'; // import { isPubcidEnabled } from './pubCommonId.js'; @@ -34,64 +39,6 @@ export const COOKIE_KEY_MGUID = '__mguid_'; const COOKIE_KEY_PMGUID = '__pmguid_'; const COOKIE_RETENTION_TIME = 365 * 24 * 60 * 60 * 1000; // 1 year let reqTimes = 0; -/** - * get page title - * @returns {string} - */ - -export function getPageTitle(win = window) { - try { - const ogTitle = win.top.document.querySelector('meta[property="og:title"]') - return win.top.document.title || (ogTitle && ogTitle.content) || ''; - } catch (e) { - const ogTitle = document.querySelector('meta[property="og:title"]') - return document.title || (ogTitle && ogTitle.content) || ''; - } -} - -/** - * get page description - * - * @returns {string} - */ -export function getPageDescription(win = window) { - let element; - - try { - element = win.top.document.querySelector('meta[name="description"]') || - win.top.document.querySelector('meta[property="og:description"]') - } catch (e) { - element = document.querySelector('meta[name="description"]') || - document.querySelector('meta[property="og:description"]') - } - - return (element && element.content) || ''; -} - -/** - * get page keywords - * @returns {string} - */ -export function getPageKeywords(win = window) { - let element; - - try { - element = win.top.document.querySelector('meta[name="keywords"]'); - } catch (e) { - element = document.querySelector('meta[name="keywords"]'); - } - - return (element && element.content) || ''; -} - -/** - * get connection downlink - * @returns {number} - */ -export function getConnectionDownLink(win = window) { - const nav = win.navigator || {}; - return nav && nav.connection && nav.connection.downlink >= 0 ? nav.connection.downlink.toString() : undefined; -} /** * get pmg uid @@ -135,54 +82,6 @@ function getProperty(obj, ...keys) { return o; } -/** - * 是不是移动设备或者平板 - * @return {boolean} - */ -function isMobileAndTablet() { - let check = false; - (function (a) { - let reg1 = new RegExp( - [ - '(android|bbd+|meego)', - '.+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)', - '|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone', - '|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up.(browser|link)|vodafone|wap', - '|windows ce|xda|xiino|android|ipad|playbook|silk' - ].join(''), - 'i' - ); - let reg2 = new RegExp( - [ - '1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)', - '|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )', - '|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell', - '|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)', - '|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene', - '|gf-5|g-mo|go(.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c', - '|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom', - '|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)', - '|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)', - '|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]', - '|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)', - '|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio', - '|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms', - '|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al', - '|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)', - '|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(.b|g1|si)|utst|', - 'v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)', - '|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-', - '|your|zeto|zte-' - ].join(''), - 'i' - ); - if (reg1.test(a) || reg2.test(a.substr(0, 4))) { - check = true; - } - })(navigator.userAgent || navigator.vendor || window.opera); - return check; -} - /** * 获取底价 * @param {*} bid @@ -205,62 +104,9 @@ function isMobileAndTablet() { // } // return floor; // } -function getBidFloor(bid) { - if (!utils.isFn(bid.getFloor)) { - return utils.deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - return bidFloor.floor; - } catch (_) { - return 0; - } -} - -/** - * 将尺寸转为RTB识别的尺寸 - * - * @param {Array|Object} requestSizes 配置尺寸 - * @return {Object} - */ -function transformSizes(requestSizes) { - let sizes = []; - let sizeObj = {}; - - if (utils.isArray(requestSizes) && requestSizes.length === 2 && !utils.isArray(requestSizes[0])) { - sizeObj.width = parseInt(requestSizes[0], 10); - sizeObj.height = parseInt(requestSizes[1], 10); - sizes.push(sizeObj); - } else if (typeof requestSizes === 'object') { - for (let i = 0; i < requestSizes.length; i++) { - let size = requestSizes[i]; - sizeObj = {}; - sizeObj.width = parseInt(size[0], 10); - sizeObj.height = parseInt(size[1], 10); - sizes.push(sizeObj); - } - } - - return sizes; -} // 支持的广告尺寸 -const mediagoAdSize = [ - { w: 300, h: 250 }, - { w: 300, h: 600 }, - { w: 728, h: 90 }, - { w: 970, h: 250 }, - { w: 320, h: 50 }, - { w: 160, h: 600 }, - { w: 320, h: 180 }, - { w: 320, h: 100 }, - { w: 336, h: 280 } -]; +const mediagoAdSize = normalAdSize; /** * 获取广告位配置 @@ -340,21 +186,6 @@ function getItems(validBidRequests, bidderRequest) { return items; } -/** - * @param {BidRequest} bidRequest - * @param bidderRequest - * @returns {string} - */ -function getReferrer(bidRequest = {}, bidderRequest = {}) { - let pageUrl; - if (bidRequest.params && bidRequest.params.referrer) { - pageUrl = bidRequest.params.referrer; - } else { - pageUrl = utils.deepAccess(bidderRequest, 'refererInfo.page'); - } - return pageUrl; -} - /** * get current time to UTC string * @returns utc string @@ -386,7 +217,7 @@ function getParam(validBidRequests, bidderRequest) { const cat = utils.deepAccess(bidderRequest, 'ortb2.site.cat'); reqTimes += 1; - let isMobile = isMobileAndTablet() ? 1 : 0; + let isMobile = getDevice() ? 1 : 0; // input test status by Publisher. more frequently for test true req let isTest = validBidRequests[0].params.test || 0; let auctionId = getProperty(bidderRequest, 'auctionId'); diff --git a/modules/mediakeysBidAdapter.js b/modules/mediakeysBidAdapter.js index f4967fed170..987b2689f6b 100644 --- a/modules/mediakeysBidAdapter.js +++ b/modules/mediakeysBidAdapter.js @@ -66,6 +66,7 @@ const ORTB_VIDEO_PARAMS = { h: value => isInteger(value), startdelay: value => isInteger(value), placement: value => [1, 2, 3, 4, 5].indexOf(value) !== -1, + plcmt: value => [1, 2, 3, 4].indexOf(value) !== -1, linearity: value => [1, 2].indexOf(value) !== -1, skip: value => [0, 1].indexOf(value) !== -1, skipmin: value => isInteger(value), diff --git a/modules/medianetAnalyticsAdapter.js b/modules/medianetAnalyticsAdapter.js index 68927cc6b13..e8d73e77d5f 100644 --- a/modules/medianetAnalyticsAdapter.js +++ b/modules/medianetAnalyticsAdapter.js @@ -36,8 +36,7 @@ const PRICE_GRANULARITY = { }; const MEDIANET_BIDDER_CODE = 'medianet'; -// eslint-disable-next-line no-undef -const PREBID_VERSION = getGlobal().version; +const PREBID_VERSION = '$prebid.version$' const ERROR_CONFIG_JSON_PARSE = 'analytics_config_parse_fail'; const ERROR_CONFIG_FETCH = 'analytics_config_ajax_fail'; const ERROR_WINNING_BID_ABSENT = 'winning_bid_absent'; diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index 4d4cf0d80ed..c90292a74ac 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -1,6 +1,6 @@ import { - buildUrl, deepAccess, + formatQS, getWindowTop, isArray, isEmpty, @@ -8,7 +8,9 @@ import { isStr, logError, logInfo, - triggerPixel + safeJSONEncode, + deepClone, + deepSetValue } from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {config} from '../src/config.js'; @@ -18,6 +20,7 @@ import {Renderer} from '../src/Renderer.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import {getGlobal} from '../src/prebidGlobal.js'; import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import {ajax} from '../src/ajax.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -35,27 +38,20 @@ const SLOT_VISIBILITY = { ABOVE_THE_FOLD: 1, BELOW_THE_FOLD: 2 }; -const EVENTS = { +export const EVENTS = { TIMEOUT_EVENT_NAME: 'client_timeout', - BID_WON_EVENT_NAME: 'client_bid_won' + BID_WON_EVENT_NAME: 'client_bid_won', + SET_TARGETING: 'client_set_targeting', + BIDDER_ERROR: 'client_bidder_error' }; -const EVENT_PIXEL_URL = 'qsearch-a.akamaihd.net/log'; +export const EVENT_PIXEL_URL = 'https://navvy.media.net/log'; const OUTSTREAM = 'outstream'; -// TODO: this should be picked from bidderRequest -let refererInfo = getRefererInfo(); - -let mnData = {}; +let pageMeta; window.mnet = window.mnet || {}; window.mnet.queue = window.mnet.queue || []; -mnData.urlData = { - domain: refererInfo.domain, - page: refererInfo.page, - isTop: refererInfo.reachedTop -}; - const aliases = [ { code: TRUSTEDSTACK_CODE, gvlid: 1288 }, ]; @@ -85,20 +81,20 @@ function siteDetails(site, bidderRequest) { } function getPageMeta() { - if (mnData.pageMeta) { - return mnData.pageMeta; + if (pageMeta) { + return pageMeta; } let canonicalUrl = getUrlFromSelector('link[rel="canonical"]', 'href'); let ogUrl = getUrlFromSelector('meta[property="og:url"]', 'content'); let twitterUrl = getUrlFromSelector('meta[name="twitter:url"]', 'content'); - mnData.pageMeta = Object.assign({}, + pageMeta = Object.assign({}, canonicalUrl && { 'canonical_url': canonicalUrl }, ogUrl && { 'og_url': ogUrl }, twitterUrl && { 'twitter_url': twitterUrl } ); - return mnData.pageMeta; + return pageMeta; } function getUrlFromSelector(selector, attribute) { @@ -186,7 +182,7 @@ function extParams(bidRequest, bidderRequests) { const coppaApplies = !!(config.getConfig('coppa')); return Object.assign({}, { customer_id: params.cid }, - { prebid_version: getGlobal().version }, + { prebid_version: 'v' + '$prebid.version$' }, { gdpr_applies: gdprApplies }, (gdprApplies) && { gdpr_consent_string: gdpr.consentString || '' }, { usp_applies: uspApplies }, @@ -261,7 +257,7 @@ function slotParams(bidRequest, bidderRequests) { if (floorInfo && floorInfo.length > 0) { params.bidfloors = floorInfo; } - if (bidderRequests.fledgeEnabled) { + if (bidderRequests.paapi?.enabled) { params.ext.ae = bidRequest?.ortb2Imp?.ext?.ae; } return params; @@ -338,6 +334,15 @@ function getBidderURL(bidderCode, cid) { return url + '?cid=' + encodeURIComponent(cid); } +function ortb2Data(ortb2, bidRequests) { + const ortb2Object = deepClone(ortb2); + const eids = deepAccess(bidRequests, '0.userIdAsEids'); + if (eids) { + deepSetValue(ortb2Object, 'user.ext.eids', eids) + } + return ortb2Object; +} + function generatePayload(bidRequests, bidderRequests) { return { site: siteDetails(bidRequests[0].params.site, bidderRequests), @@ -345,7 +350,7 @@ function generatePayload(bidRequests, bidderRequests) { // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 id: bidRequests[0].auctionId, imp: bidRequests.map(request => slotParams(request, bidderRequests)), - ortb2: bidderRequests.ortb2, + ortb2: ortb2Data(bidderRequests.ortb2, bidRequests), tmax: bidderRequests.timeout } } @@ -363,38 +368,71 @@ function fetchCookieSyncUrls(response) { return []; } -function getLoggingData(event, data) { - data = (isArray(data) && data) || []; - - let params = {}; +function getEventData(event) { + const params = {}; + const referrerInfo = getRefererInfo(); params.logid = 'kfk'; params.evtid = 'projectevents'; params.project = 'prebid'; - params.acid = deepAccess(data, '0.auctionId') || ''; + params.pbver = '$prebid.version$'; params.cid = getGlobal().medianetGlobals.cid || ''; - params.crid = data.map((adunit) => deepAccess(adunit, 'params.0.crid') || adunit.adUnitCode).join('|'); - params.adunit_count = data.length || 0; - params.dn = mnData.urlData.domain || ''; - params.requrl = mnData.urlData.page || ''; - params.istop = mnData.urlData.isTop || ''; + params.dn = encodeURIComponent(referrerInfo.domain || ''); + params.requrl = encodeURIComponent(referrerInfo.page || ''); params.event = event.name || ''; params.value = event.value || ''; params.rd = event.related_data || ''; + return params; +} +function getBidData(bid) { + const params = {}; + params.acid = bid.auctionId || ''; + params.crid = deepAccess(bid, 'params.crid') || deepAccess(bid, 'params.0.crid') || bid.adUnitCode || ''; + params.ext = safeJSONEncode(bid.ext) || ''; + + const rawobj = deepClone(bid); + delete rawobj.ad; + delete rawobj.vastXml; + params.rawobj = safeJSONEncode(rawobj); return params; } -function logEvent (event, data) { - let getParams = { - protocol: 'https', - hostname: EVENT_PIXEL_URL, - search: getLoggingData(event, data) - }; - triggerPixel(buildUrl(getParams)); +function getLoggingData(event, bids) { + const logData = {}; + if (!isArray(bids)) { + bids = []; + } + bids.forEach((bid) => { + let bidData = getBidData(bid); + Object.keys(bidData).forEach((key) => { + logData[key] = logData[key] || []; + logData[key].push(encodeURIComponent(bidData[key])); + }); + }); + return Object.assign({}, getEventData(event), logData) +} + +function fireAjaxLog(url, payload) { + ajax(url, + { + success: () => undefined, + error: () => undefined + }, + payload, + { + method: 'POST', + keepalive: true + } + ); } -function clearMnData() { - mnData = {}; +function logEvent(event, data) { + const logData = getLoggingData(event, data); + fireAjaxLog(EVENT_PIXEL_URL, formatQS(logData)); +} + +function clearPageMeta() { + pageMeta = undefined; } function addRenderer(bid) { @@ -508,7 +546,7 @@ export const spec = { } return { bids: validBids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, } }, getUserSyncs: function(syncOptions, serverResponses) { @@ -550,7 +588,30 @@ export const spec = { } catch (e) {} }, - clearMnData, + onSetTargeting: (bid) => { + try { + let eventData = { + name: EVENTS.SET_TARGETING, + value: bid.cpm + }; + const enableSendAllBids = config.getConfig('enableSendAllBids'); + if (!enableSendAllBids) { + logEvent(eventData, [bid]); + } + } catch (e) {} + }, + + onBidderError: ({error, bidderRequest}) => { + try { + let eventData = { + name: EVENTS.BIDDER_ERROR, + related_data: `timedOut:${error.timedOut}|status:${error.status}|message:${error.reason.message}` + }; + logEvent(eventData, bidderRequest.bids); + } catch (e) {} + }, + + clearPageMeta, getWindowSize, }; diff --git a/modules/medianetBidAdapter.md b/modules/medianetBidAdapter.md index d401a72f1f6..500c9f3f12b 100644 --- a/modules/medianetBidAdapter.md +++ b/modules/medianetBidAdapter.md @@ -186,12 +186,12 @@ var adUnits = [{ In order to enable PAAPI auctions follow the instructions below: -1. Add the fledgeForGpt and paapi modules to your prebid bundle. +1. Add the paapiForGpt and paapi modules to your prebid bundle. 2. Add the following configuration for the module ``` pbjs.que.push(function() { pbjs.setConfig({ - fledgeForGpt: { + paapi: { enabled: true, bidders: ['medianet'], defaultForSlots: 1 @@ -200,4 +200,4 @@ pbjs.que.push(function() { }); ``` -For a detailed guide to enabling PAAPI auctions follow Prebid's documentation on [fledgeForGpt](https://docs.prebid.org/dev-docs/modules/fledgeForGpt.html) +For a detailed guide to enabling PAAPI auctions follow Prebid's documentation on [paapiForGpt](https://docs.prebid.org/dev-docs/modules/paapiForGpt.html) diff --git a/modules/mgidBidAdapter.js b/modules/mgidBidAdapter.js index fb3990e97f1..5cfef325d2f 100644 --- a/modules/mgidBidAdapter.js +++ b/modules/mgidBidAdapter.js @@ -12,7 +12,7 @@ import { isFn, isNumber, isBoolean, - isInteger, deepSetValue, getBidIdParameter, + isInteger, deepSetValue, getBidIdParameter, setOnAny } from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE} from '../src/mediaTypes.js'; @@ -86,7 +86,7 @@ _each(NATIVE_ASSETS, anAsset => { _NATIVE_ASSET_ID_TO_KEY_MAP[anAsset.ID] = anAs _each(NATIVE_ASSETS, anAsset => { _NATIVE_ASSET_KEY_TO_ASSET_MAP[anAsset.KEY] = anAsset }); export const spec = { - VERSION: '1.6', + VERSION: '1.7', code: BIDDER_CODE, gvlid: GVLID, supportedMediaTypes: [BANNER, NATIVE], @@ -167,6 +167,8 @@ export const spec = { tagid, secure, }; + const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid'); + gpid && isStr(gpid) && deepSetValue(impObj, `ext.gpid`, gpid); const floorData = getBidFloor(bid, cur); if (floorData.floor) { impObj.bidfloor = floorData.floor; @@ -431,15 +433,6 @@ export const spec = { registerBidder(spec); -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - /** * Unpack the Server's Bid into a Prebid-compatible one. * @param serverBid diff --git a/modules/mgidXBidAdapter.js b/modules/mgidXBidAdapter.js index f073fb4c576..471e8fb2754 100644 --- a/modules/mgidXBidAdapter.js +++ b/modules/mgidXBidAdapter.js @@ -1,19 +1,9 @@ -import { - isFn, - deepAccess, - logMessage, - logError, - isPlainObject, - isNumber, - isArray, - isStr -} from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - +import { isPlainObject, isNumber, isArray, isStr } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; import { USERSYNC_DEFAULT_CONFIG } from '../src/userSync.js'; +import { isBidRequestValid, buildRequestsBase, interpretResponse } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'mgidX'; const GVLID = 358; @@ -21,195 +11,27 @@ const AD_URL = 'https://#{REGION}#.mgid.com/pbjs'; const PIXEL_SYNC_URL = 'https://cm.mgid.com/i.gif'; const IFRAME_SYNC_URL = 'https://cm.mgid.com/i.html'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + const request = buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest }); + const region = validBidRequests[0].params?.region; - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; + if (region === 'eu') { + request.url = AD_URL.replace('#{REGION}#', 'eu'); + } else { + request.url = AD_URL.replace('#{REGION}#', 'us-east-x'); } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} + return request; +}; export const spec = { code: BIDDER_CODE, gvlid: GVLID, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - tmax: bidderRequest.timeout - }; - - if (bidderRequest.gdprConsent) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - const region = validBidRequests[0].params?.region; - - let url; - if (region === 'eu') { - url = AD_URL.replace('#{REGION}#', 'eu'); - } else { - url = AD_URL.replace('#{REGION}#', 'us-east-x'); - } - - return { - method: 'POST', - url: url, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, + isBidRequestValid: isBidRequestValid(), + buildRequests, + interpretResponse, getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => { const spb = isPlainObject(config.getConfig('userSync')) && diff --git a/modules/microadBidAdapter.js b/modules/microadBidAdapter.js index 61aa9b795de..82b9025766b 100644 --- a/modules/microadBidAdapter.js +++ b/modules/microadBidAdapter.js @@ -28,7 +28,6 @@ const AUDIENCE_IDS = [ {type: 8, bidKey: 'userId.id5id.uid', source: 'id5-sync.com'}, {type: 9, bidKey: 'userId.tdid', source: 'adserver.org'}, {type: 10, bidKey: 'userId.novatiq.snowflake', source: 'novatiq.com'}, - {type: 11, bidKey: 'userId.parrableId.eid', source: 'parrable.com'}, {type: 12, bidKey: 'userId.dacId.id', source: 'dac.co.jp'}, {type: 13, bidKey: 'userId.idl_env', source: 'liveramp.com'}, {type: 14, bidKey: 'userId.criteoId', source: 'criteo.com'}, diff --git a/modules/minutemediaBidAdapter.js b/modules/minutemediaBidAdapter.js index a724a0446a4..4e83c5c6db4 100644 --- a/modules/minutemediaBidAdapter.js +++ b/modules/minutemediaBidAdapter.js @@ -2,33 +2,28 @@ import { logWarn, logInfo, isArray, - isFn, deepAccess, - isEmpty, - contains, - timestamp, triggerPixel, - isInteger, - getBidIdParameter } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { + getEndpoint, + generateBidsParams, + generateGeneralParams, + buildBidResponse, +} from '../libraries/riseUtils/index.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'minutemedia'; const ADAPTER_VERSION = '6.0.0'; const TTL = 360; const DEFAULT_CURRENCY = 'USD'; -const SELLER_ENDPOINT = 'https://hb.minutemedia-prebid.com/'; +const BASE_URL = 'https://hb.minutemedia-prebid.com/'; const MODES = { PRODUCTION: 'hb-mm-multi', TEST: 'hb-multi-mm-test' -} -const SUPPORTED_SYNC_METHODS = { - IFRAME: 'iframe', - PIXEL: 'pixel' -} +}; export const spec = { code: BIDDER_CODE, @@ -51,50 +46,24 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { const combinedRequestsObject = {}; - // use data from the first bid, to create the general params for all bids const generalObject = validBidRequests[0]; const testMode = generalObject.params.testMode; - combinedRequestsObject.params = generateGeneralParams(generalObject, bidderRequest); + combinedRequestsObject.params = generateGeneralParams(generalObject, bidderRequest, ADAPTER_VERSION); combinedRequestsObject.bids = generateBidsParams(validBidRequests, bidderRequest); return { method: 'POST', - url: getEndpoint(testMode), + url: getEndpoint(testMode, BASE_URL, MODES), data: combinedRequestsObject - } + }; }, - interpretResponse: function ({body}) { + interpretResponse: function ({ body }) { const bidResponses = []; if (body.bids) { body.bids.forEach(adUnit => { - const bidResponse = { - requestId: adUnit.requestId, - cpm: adUnit.cpm, - currency: adUnit.currency || DEFAULT_CURRENCY, - width: adUnit.width, - height: adUnit.height, - ttl: adUnit.ttl || TTL, - creativeId: adUnit.creativeId, - netRevenue: adUnit.netRevenue || true, - nurl: adUnit.nurl, - mediaType: adUnit.mediaType, - meta: { - mediaType: adUnit.mediaType - } - }; - - if (adUnit.mediaType === VIDEO) { - bidResponse.vastXml = adUnit.vastXml; - } else if (adUnit.mediaType === BANNER) { - bidResponse.ad = adUnit.ad; - } - - if (adUnit.adomain && adUnit.adomain.length) { - bidResponse.meta.advertiserDomains = adUnit.adomain; - } - + const bidResponse = buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER); bidResponses.push(bidResponse); }); } @@ -104,20 +73,20 @@ export const spec = { getUserSyncs: function (syncOptions, serverResponses) { const syncs = []; for (const response of serverResponses) { - if (syncOptions.iframeEnabled && response.body.params.userSyncURL) { + if (syncOptions.iframeEnabled && deepAccess(response, 'body.params.userSyncURL')) { syncs.push({ type: 'iframe', - url: response.body.params.userSyncURL + url: deepAccess(response, 'body.params.userSyncURL') }); } - if (syncOptions.pixelEnabled && isArray(response.body.params.userSyncPixels)) { + if (syncOptions.pixelEnabled && isArray(deepAccess(response, 'body.params.userSyncPixels'))) { const pixels = response.body.params.userSyncPixels.map(pixel => { return { type: 'image', url: pixel - } - }) - syncs.push(...pixels) + }; + }); + syncs.push(...pixels); } } return syncs; @@ -135,349 +104,3 @@ export const spec = { }; registerBidder(spec); - -/** - * Get floor price - * @param bid {bid} - * @returns {Number} - */ -function getFloor(bid, mediaType) { - if (!isFn(bid.getFloor)) { - return 0; - } - let floorResult = bid.getFloor({ - currency: DEFAULT_CURRENCY, - mediaType: mediaType, - size: '*' - }); - return floorResult.currency === DEFAULT_CURRENCY && floorResult.floor ? floorResult.floor : 0; -} - -/** - * Get the the ad sizes array from the bid - * @param bid {bid} - * @returns {Array} - */ -function getSizesArray(bid, mediaType) { - let sizesArray = [] - - if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) { - sizesArray = bid.mediaTypes[mediaType].sizes; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizesArray = bid.sizes; - } - - return sizesArray; -} - -/** - * Get schain string value - * @param schainObject {Object} - * @returns {string} - */ -function getSupplyChain(schainObject) { - if (isEmpty(schainObject)) { - return ''; - } - let scStr = `${schainObject.ver},${schainObject.complete}`; - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - return scStr; -} - -/** - * Get encoded node value - * @param val {string} - * @returns {string} - */ -function getEncodedValIfNotEmpty(val) { - return !isEmpty(val) ? encodeURIComponent(val) : ''; -} - -/** - * Get preferred user-sync method based on publisher configuration - * @param bidderCode {string} - * @returns {string} - */ -function getAllowedSyncMethod(filterSettings, bidderCode) { - const iframeConfigsToCheck = ['all', 'iframe']; - const pixelConfigToCheck = 'image'; - if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { - return SUPPORTED_SYNC_METHODS.IFRAME; - } - if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { - return SUPPORTED_SYNC_METHODS.PIXEL; - } -} - -/** - * Check if sync rule is supported - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - const isInclude = syncRule.filter === 'include'; - const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - return isInclude && contains(bidders, bidderCode); -} - -/** - * Get the seller endpoint - * @param testMode {boolean} - * @returns {string} - */ -function getEndpoint(testMode) { - return testMode - ? SELLER_ENDPOINT + MODES.TEST - : SELLER_ENDPOINT + MODES.PRODUCTION; -} - -/** - * get device type - * @param uad {ua} - * @returns {string} - */ -function getDeviceType(ua) { - if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i - .test(ua.toLowerCase())) { - return '5'; - } - if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i - .test(ua.toLowerCase())) { - return '4'; - } - if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i - .test(ua.toLowerCase())) { - return '3'; - } - return '1'; -} - -function generateBidsParams(validBidRequests, bidderRequest) { - const bidsArray = []; - - if (validBidRequests.length) { - validBidRequests.forEach(bid => { - bidsArray.push(generateBidParameters(bid, bidderRequest)); - }); - } - - return bidsArray; -} - -/** - * Generate bid specific parameters - * @param {bid} bid - * @param {bidderRequest} bidderRequest - * @returns {Object} bid specific params object - */ -function generateBidParameters(bid, bidderRequest) { - const {params} = bid; - const mediaType = isBanner(bid) ? BANNER : VIDEO; - const sizesArray = getSizesArray(bid, mediaType); - - // fix floor price in case of NAN - if (isNaN(params.floorPrice)) { - params.floorPrice = 0; - } - - const bidObject = { - mediaType, - adUnitCode: getBidIdParameter('adUnitCode', bid), - sizes: sizesArray, - floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice), - bidId: getBidIdParameter('bidId', bid), - loop: getBidIdParameter('bidderRequestsCount', bid), - bidderRequestId: getBidIdParameter('bidderRequestId', bid), - transactionId: bid.ortb2Imp?.ext?.tid || '', - coppa: 0, - }; - - const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`); - if (pos) { - bidObject.pos = pos; - } - - const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`); - if (gpid) { - bidObject.gpid = gpid; - } - - const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`); - if (placementId) { - bidObject.placementId = placementId; - } - - const mimes = deepAccess(bid, `mediaTypes.${mediaType}.mimes`); - if (mimes) { - bidObject.mimes = mimes; - } - const api = deepAccess(bid, `mediaTypes.${mediaType}.api`); - if (api) { - bidObject.api = api; - } - - const sua = deepAccess(bid, `ortb2.device.sua`); - if (sua) { - bidObject.sua = sua; - } - - const coppa = deepAccess(bid, `ortb2.regs.coppa`) - if (coppa) { - bidObject.coppa = 1; - } - - if (mediaType === VIDEO) { - const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`); - let playbackMethodValue; - - // verify playbackMethod is of type integer array, or integer only. - if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) { - // only the first playbackMethod in the array will be used, according to OpenRTB 2.5 recommendation - playbackMethodValue = playbackMethod[0]; - } else if (isInteger(playbackMethod)) { - playbackMethodValue = playbackMethod; - } - - if (playbackMethodValue) { - bidObject.playbackMethod = playbackMethodValue; - } - - const placement = deepAccess(bid, `mediaTypes.video.placement`); - if (placement) { - bidObject.placement = placement; - } - - const minDuration = deepAccess(bid, `mediaTypes.video.minduration`); - if (minDuration) { - bidObject.minDuration = minDuration; - } - - const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`); - if (maxDuration) { - bidObject.maxDuration = maxDuration; - } - - const skip = deepAccess(bid, `mediaTypes.video.skip`); - if (skip) { - bidObject.skip = skip; - } - - const linearity = deepAccess(bid, `mediaTypes.video.linearity`); - if (linearity) { - bidObject.linearity = linearity; - } - - const protocols = deepAccess(bid, `mediaTypes.video.protocols`); - if (protocols) { - bidObject.protocols = protocols; - } - - const plcmt = deepAccess(bid, `mediaTypes.video.plcmt`); - if (plcmt) { - bidObject.plcmt = plcmt; - } - } - - return bidObject; -} - -function isBanner(bid) { - return bid.mediaTypes && bid.mediaTypes.banner; -} - -/** - * Generate params that are common between all bids - * @param {single bid object} generalObject - * @param {bidderRequest} bidderRequest - * @returns {object} the common params object - */ -function generateGeneralParams(generalObject, bidderRequest) { - const domain = window.location.hostname; - const {syncEnabled, filterSettings} = config.getConfig('userSync') || {}; - const {bidderCode} = bidderRequest; - const generalBidParams = generalObject.params; - const timeout = bidderRequest.timeout; - - // these params are snake_case instead of camelCase to allow backwards compatability on the server. - // in the future, these will be converted to camelCase to match our convention. - const generalParams = { - wrapper_type: 'prebidjs', - wrapper_vendor: '$$PREBID_GLOBAL$$', - wrapper_version: '$prebid.version$', - adapter_version: ADAPTER_VERSION, - auction_start: timestamp(), - publisher_id: generalBidParams.org, - publisher_name: domain, - site_domain: domain, - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, - device_type: getDeviceType(navigator.userAgent), - ua: navigator.userAgent, - is_wrapper: !!generalBidParams.isWrapper, - session_id: generalBidParams.sessionId || getBidIdParameter('bidderRequestId', generalObject), - tmax: timeout - } - - const userIdsParam = getBidIdParameter('userId', generalObject); - if (userIdsParam) { - generalParams.userIds = JSON.stringify(userIdsParam); - } - - const ortb2Metadata = bidderRequest.ortb2 || {}; - if (ortb2Metadata.site) { - generalParams.site_metadata = JSON.stringify(ortb2Metadata.site); - } - if (ortb2Metadata.user) { - generalParams.user_metadata = JSON.stringify(ortb2Metadata.user); - } - - if (syncEnabled) { - const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); - if (allowedSyncMethod) { - generalParams.cs_method = allowedSyncMethod; - } - } - - if (bidderRequest.uspConsent) { - generalParams.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies; - generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - - if (bidderRequest.gppConsent) { - generalParams.gpp = bidderRequest.gppConsent.gppString; - generalParams.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - generalParams.gpp = bidderRequest.ortb2.regs.gpp; - generalParams.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - if (generalBidParams.ifa) { - generalParams.ifa = generalBidParams.ifa; - } - - if (generalObject.schain) { - generalParams.schain = getSupplyChain(generalObject.schain); - } - - if (bidderRequest && bidderRequest.refererInfo) { - generalParams.referrer = deepAccess(bidderRequest, 'refererInfo.ref'); - generalParams.page_url = deepAccess(bidderRequest, 'refererInfo.page') || deepAccess(window, 'location.href'); - } - - return generalParams -} diff --git a/modules/minutemediaplusBidAdapter.js b/modules/minutemediaplusBidAdapter.js deleted file mode 100644 index 146d437b1fa..00000000000 --- a/modules/minutemediaplusBidAdapter.js +++ /dev/null @@ -1,349 +0,0 @@ -import {_each, deepAccess, parseSizesInput, parseUrl, uniques, isFn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {config} from '../src/config.js'; - -const GVLID = 918; -const DEFAULT_SUB_DOMAIN = 'exchange'; -const BIDDER_CODE = 'mmplus'; -const BIDDER_VERSION = '1.0.0'; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15; - -const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getTopWindowQueryParams() { - try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} - -export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { - return `https://${subDomain}.minutemedia-prebid.com`; -} - -export function extractCID(params) { - return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; -} - -export function extractPID(params) { - return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; -} - -export function extractSubDomain(params) { - return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const { - params, - bidId, - userId, - adUnitCode, - schain, - mediaTypes, - auctionId, - ortb2Imp, - bidderRequestId, - bidRequestsCount, - bidderRequestsCount, - bidderWinsCount - } = bid; - let {bidFloor, ext} = params; - const hashUrl = hashCode(topWindowUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const cId = extractCID(params); - const pId = extractPID(params); - const subDomain = extractSubDomain(params); - - const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid', deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', '')); - - if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - bidFloor = floorInfo.floor; - } - } - - let data = { - url: encodeURIComponent(topWindowUrl), - uqs: getTopWindowQueryParams(), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - referrer: bidderRequest.refererInfo.ref, - adUnitCode: adUnitCode, - publisherId: pId, - sizes: sizes, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}`, - schain: schain, - mediaTypes: mediaTypes, - gpid: gpid, - // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 - auctionId: auctionId, - transactionId: ortb2Imp?.ext?.tid, - bidderRequestId: bidderRequestId, - bidRequestsCount: bidRequestsCount, - bidderRequestsCount: bidderRequestsCount, - bidderWinsCount: bidderWinsCount, - bidderTimeout: bidderTimeout - }; - - appendUserIdsToRequestPayload(data, userId); - - const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); - - if (sua) { - data.sua = sua; - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest.gppConsent) { - data.gppString = bidderRequest.gppConsent.gppString; - data.gppSid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - data.gppString = bidderRequest.ortb2.regs.gpp; - data.gppSid = bidderRequest.ortb2.regs.gpp_sid; - } - - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data - }; - - _each(ext, (value, key) => { - dto.data['ext.' + key] = value; - }); - - return dto; -} - -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - _each(userIds, (userId, idSystemProviderName) => { - key = `uid.${idSystemProviderName}`; - - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - }); -} - -function buildRequests(validBidRequests, bidderRequest) { - const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const bidderTimeout = config.getConfig('bidderTimeout'); - const requests = []; - validBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - const {bidId} = request.data; - const {results} = serverResponse.body; - - let output = []; - - try { - results.forEach(result => { - const { - creativeId, - ad, - price, - exp, - width, - height, - currency, - metaData, - advertiserDomains, - mediaType = BANNER - } = result; - if (!ad || !price) { - return; - } - - const response = { - requestId: bidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - }; - - if (metaData) { - Object.assign(response, { - meta: metaData - }) - } else { - Object.assign(response, { - meta: { - advertiserDomains: advertiserDomains || [] - } - }) - } - - if (mediaType === BANNER) { - Object.assign(response, { - ad: ad, - }); - } else { - Object.assign(response, { - vastXml: ad, - mediaType: VIDEO - }); - } - output.push(response); - }); - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '', gppConsent = {}) { - let syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - const {gppString, applicableSections} = gppConsent; - - const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); - let params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}` - - if (gppString && applicableSections?.length) { - params += '&gpp=' + encodeURIComponent(gppString); - params += '&gpp_sid=' + encodeURIComponent(applicableSections.join(',')); - } - - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.minutemedia-prebid.com/api/sync/iframe/${params}` - }); - } - if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.minutemedia-prebid.com/api/sync/image/${params}` - }); - } - return syncs; -} - -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { - h = (h << 5) - h + s.charCodeAt(i++) | 0; - } - } - return prefix + h; -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { - } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); - storage.setDataInLocalStorage(key, data); - } catch (e) { - } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} - -export const spec = { - code: BIDDER_CODE, - version: BIDDER_VERSION, - gvlid: GVLID, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs -}; - -registerBidder(spec); diff --git a/modules/minutemediaplusBidAdapter.md b/modules/minutemediaplusBidAdapter.md deleted file mode 100644 index 410c00e7017..00000000000 --- a/modules/minutemediaplusBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -**Module Name:** MinuteMediaPlus Bidder Adapter - -**Module Type:** Bidder Adapter - -**Maintainer:** hb@minutemedia.com - -# Description - -Module that connects to MinuteMediaPlus's demand sources. - -# Test Parameters -```js -var adUnits = [ - { - code: 'test-ad', - sizes: [[300, 250]], - bids: [ - { - bidder: 'mmplus', - params: { - cId: '562524b21b1c1f08117fc7f9', - pId: '59ac17c192832d0011283fe3', - bidFloor: 0.0001, - ext: { - param1: 'loremipsum', - param2: 'dolorsitamet' - } - } - } - ] - } -]; -``` diff --git a/modules/mobfoxpbBidAdapter.js b/modules/mobfoxpbBidAdapter.js index 35e9b03c031..dcc6e9594c4 100644 --- a/modules/mobfoxpbBidAdapter.js +++ b/modules/mobfoxpbBidAdapter.js @@ -1,147 +1,17 @@ -import { isFn, deepAccess, getWindowTop } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { isBidRequestValid, buildRequests, interpretResponse } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'mobfoxpb'; const AD_URL = 'https://bes.mobfox.com/pbjs'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers); - default: - return false; - } -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && bid.params.placementId); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - const winTop = getWindowTop(); - const location = winTop.location; - const placements = []; - const request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent; - } - - // Add GPP consent - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - const placement = { - placementId: bid.params.placementId, - bidId: bid.bidId, - schain: bid.schain || {}, - bidfloor: getBidFloor(bid) - }; - const mediaType = bid.mediaTypes; - - if (mediaType && mediaType[BANNER] && mediaType[BANNER].sizes) { - placement.traffic = BANNER; - placement.sizes = mediaType[BANNER].sizes; - } else if (mediaType && mediaType[VIDEO] && mediaType[VIDEO].playerSize) { - placement.traffic = VIDEO; - placement.wPlayer = mediaType[VIDEO].playerSize[0]; - placement.hPlayer = mediaType[VIDEO].playerSize[1]; - placement.playerSize = mediaType[VIDEO].playerSize; - placement.minduration = mediaType[VIDEO].minduration; - placement.maxduration = mediaType[VIDEO].maxduration; - placement.mimes = mediaType[VIDEO].mimes; - placement.protocols = mediaType[VIDEO].protocols; - placement.startdelay = mediaType[VIDEO].startdelay; - placement.placement = mediaType[VIDEO].placement; - placement.skip = mediaType[VIDEO].skip; - placement.skipafter = mediaType[VIDEO].skipafter; - placement.minbitrate = mediaType[VIDEO].minbitrate; - placement.maxbitrate = mediaType[VIDEO].maxbitrate; - placement.delivery = mediaType[VIDEO].delivery; - placement.playbackmethod = mediaType[VIDEO].playbackmethod; - placement.api = mediaType[VIDEO].api; - placement.linearity = mediaType[VIDEO].linearity; - } else if (mediaType && mediaType[NATIVE]) { - placement.traffic = NATIVE; - placement.native = mediaType[NATIVE]; - } - placements.push(placement); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - resItem.meta = resItem.meta || {}; - resItem.meta.advertiserDomains = resItem.adomain || []; - - response.push(resItem); - } - } - return response; - }, + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse }; registerBidder(spec); diff --git a/modules/mobianRtdProvider.js b/modules/mobianRtdProvider.js new file mode 100644 index 00000000000..818a35f9302 --- /dev/null +++ b/modules/mobianRtdProvider.js @@ -0,0 +1,66 @@ +/** + * This module adds the Mobian RTD provider to the real time data module + * The {@link module:modules/realTimeData} module is required + * @module modules/anonymisedRtdProvider + * @requires module:modules/realTimeData + */ +import { submodule } from '../src/hook.js'; +import { ajaxBuilder } from '../src/ajax.js'; +import { deepSetValue } from '../src/utils.js'; + +/** + * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule + */ + +export const MOBIAN_URL = 'https://impact-api-prod.themobian.com/brand_safety'; + +/** @type {RtdSubmodule} */ +export const mobianBrandSafetySubmodule = { + name: 'mobianBrandSafety', + init: init, + getBidRequestData: getBidRequestData +}; + +function init() { + return true; +} +function getBidRequestData(bidReqConfig, callback, config) { + const { site: ortb2Site } = bidReqConfig.ortb2Fragments.global; + const pageUrl = encodeURIComponent(getPageUrl()); + const requestUrl = `${MOBIAN_URL}/by_url?url=${pageUrl}`; + + const ajax = ajaxBuilder(); + + return new Promise((resolve) => { + ajax(requestUrl, { + success: function(response) { + const risks = ['garm_high_risk', 'garm_medium_risk', 'garm_low_risk', 'garm_no_risk']; + const riskLevels = ['high_risk', 'medium_risk', 'low_risk', 'no_risk']; + + let mobianGarmRisk = 'unknown'; + for (let i = 0; i < risks.length; i++) { + if (response[risks[i]]) { + mobianGarmRisk = riskLevels[i]; + break; + } + } + const risk = { + 'mobianGarmRisk': mobianGarmRisk + }; + resolve(risk); + deepSetValue(ortb2Site.ext, 'data.mobian', risk); + callback() + }, + error: function () { + resolve({}); + callback() + } + }); + }); +} + +function getPageUrl() { + return window.location.href; +} + +submodule('realTimeData', mobianBrandSafetySubmodule); diff --git a/modules/mobianRtdProvider.md b/modules/mobianRtdProvider.md new file mode 100644 index 00000000000..e7475eb40fb --- /dev/null +++ b/modules/mobianRtdProvider.md @@ -0,0 +1,11 @@ +# Overview + +Module Name: Mobian Rtd Provider +Module Type: Rtd Provider +Maintainer: rich.rodriguez@themobian.com + +# Description + +RTD provider for themobian Brand Safety determinations. Publishers +should use this to get Mobian's GARM Risk evaluations for +a URL. diff --git a/modules/mytargetBidAdapter.md b/modules/mytargetBidAdapter.md deleted file mode 100644 index 3292ff561fa..00000000000 --- a/modules/mytargetBidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -``` -Module Name: myTarget Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support_target@corp.my.com -``` - -# Description - -Module that connects to myTarget demand sources. - -# Test Parameters - -``` - var adUnits = [{ - code: 'placementCode', - mediaTypes: { - banner: { - sizes: [[240, 400]], - } - }, - bids: [{ - bidder: 'mytarget', - params: { - placementId: '379783', - - // OPTIONAL: custom bid floor - bidfloor: 10000, - - // OPTIONAL: if you know the ad position on the page, specify it here - // (this corresponds to "Ad Position" in OpenRTB 2.3, section 5.4) - position: 0, - - // OPTIONAL: bid response type: 0 - ad url (default), 1 - ad markup - response: 0 - } - }] - }]; -``` diff --git a/modules/nativoBidAdapter.js b/modules/nativoBidAdapter.js index 69a270247cd..c9da876b292 100644 --- a/modules/nativoBidAdapter.js +++ b/modules/nativoBidAdapter.js @@ -34,7 +34,7 @@ const localPbjsRef = getGlobal() * Keep track of bid data by keys * @returns {Object} - Map of bid data that can be referenced by multiple keys */ -export const BidDataMap = () => { +export function BidDataMap() { const referenceMap = {} const bids = [] diff --git a/modules/newspassidBidAdapter.js b/modules/newspassidBidAdapter.js index 2a4b2da186b..d33b4e64297 100644 --- a/modules/newspassidBidAdapter.js +++ b/modules/newspassidBidAdapter.js @@ -1,4 +1,5 @@ import { + deepClone, logInfo, logError, deepAccess, @@ -33,12 +34,12 @@ export const spec = { }, loadConfiguredData(bid) { if (this.propertyBag.config) { return; } - this.propertyBag.config = JSON.parse(JSON.stringify(this.config_defaults)); + this.propertyBag.config = deepClone(this.config_defaults); let bidder = bid.bidder || 'newspassid'; this.propertyBag.config.logId = bidder.toUpperCase(); this.propertyBag.config.bidder = bidder; let bidderConfig = config.getConfig(bidder) || {}; - logInfo('got bidderConfig: ', JSON.parse(JSON.stringify(bidderConfig))); + logInfo('got bidderConfig: ', deepClone(bidderConfig)); let arrGetParams = this.getGetParametersAsObject(); if (bidderConfig.endpointOverride) { if (bidderConfig.endpointOverride.origin) { @@ -131,7 +132,7 @@ export const spec = { buildRequests(validBidRequests, bidderRequest) { this.loadConfiguredData(validBidRequests[0]); this.propertyBag.buildRequestsStart = new Date().getTime(); - logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${NEWSPASSVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest))); + logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${NEWSPASSVERSION} validBidRequests`, deepClone(validBidRequests), 'bidderRequest', deepClone(bidderRequest)); if (this.blockTheRequest()) { return []; } @@ -281,7 +282,7 @@ export const spec = { data: JSON.stringify(npRequest), bidderRequest: bidderRequest }; - logInfo('buildRequests request data for single = ', JSON.parse(JSON.stringify(npRequest))); + logInfo('buildRequests request data for single = ', deepClone(npRequest)); this.propertyBag.buildRequestsEnd = new Date().getTime(); logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret); return ret; @@ -309,7 +310,7 @@ export const spec = { if (request && request.bidderRequest && request.bidderRequest.bids) { this.loadConfiguredData(request.bidderRequest.bids[0]); } let startTime = new Date().getTime(); logInfo(`interpretResponse time: ${startTime}. buildRequests done -> interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`); - logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request))); + logInfo(`serverResponse, request`, deepClone(serverResponse), deepClone(request)); serverResponse = serverResponse.body || {}; let aucId = serverResponse.id; // this will be correct for single requests and non-single if (!serverResponse.hasOwnProperty('seatbid')) { @@ -464,10 +465,6 @@ export const spec = { if (id5id) { ret['id5id'] = id5id; } - let parrableId = deepAccess(bidRequest.userId, 'parrableId.eid'); - if (parrableId) { - ret['parrableId'] = parrableId; - } let sharedid = deepAccess(bidRequest.userId, 'sharedid.id'); if (sharedid) { ret['sharedid'] = sharedid; diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 65f530d9e58..5e9be67c6bb 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -1,6 +1,5 @@ import { _each, - createTrackPixelHtml, deepAccess, deepSetValue, getBidIdParameter, @@ -12,6 +11,7 @@ import { parseUrl, triggerPixel, } from '../src/utils.js'; +import {getAd} from '../libraries/targetVideoUtils/bidderUtils.js'; import {getGlobal} from '../src/prebidGlobal.js'; import { EVENTS } from '../src/constants.js'; @@ -455,32 +455,6 @@ function getTopWindow(curWindow, nesting = 0) { }; } -function getAd(bid) { - let ad, adUrl, vastXml, vastUrl; - - switch (deepAccess(bid, 'ext.prebid.type')) { - case VIDEO: - if (bid.adm.substr(0, 4) === 'http') { - vastUrl = bid.adm; - } else { - vastXml = bid.adm; - }; - - break; - default: - if (bid.adm && bid.nurl) { - ad = bid.adm; - ad += createTrackPixelHtml(decodeURIComponent(bid.nurl)); - } else if (bid.adm) { - ad = bid.adm; - } else if (bid.nurl) { - adUrl = bid.nurl; - }; - }; - - return {ad, adUrl, vastXml, vastUrl}; -} - function getSiteObj() { const refInfo = (getRefererInfo && getRefererInfo()) || {}; diff --git a/modules/nexx360BidAdapter.js b/modules/nexx360BidAdapter.js index b4f7cf50ffe..29700c14a6c 100644 --- a/modules/nexx360BidAdapter.js +++ b/modules/nexx360BidAdapter.js @@ -125,7 +125,7 @@ const converter = ortbConverter({ deepSetValue(request, 'ext.localStorage.nexx360Id', nexx360LocalStorage.nexx360Id); } const amxId = getAmxId(); - if (amxId) deepSetValue(request, 'ext.localStorage.amxId', amxId()); + if (amxId) deepSetValue(request, 'ext.localStorage.amxId', amxId); deepSetValue(request, 'ext.version', '$prebid.version$'); deepSetValue(request, 'ext.source', 'prebid.js'); deepSetValue(request, 'ext.pageViewId', PAGE_VIEW_ID); diff --git a/modules/nobidAnalyticsAdapter.js b/modules/nobidAnalyticsAdapter.js index a0aa5ee4989..afa980b05c9 100644 --- a/modules/nobidAnalyticsAdapter.js +++ b/modules/nobidAnalyticsAdapter.js @@ -1,4 +1,4 @@ -import {deepClone, logError, getParameterByName} from '../src/utils.js'; +import {deepClone, logError, getParameterByName, logMessage} from '../src/utils.js'; import {ajax} from '../src/ajax.js'; import {getStorageManager} from '../src/storageManager.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; @@ -26,8 +26,7 @@ const { AD_RENDER_SUCCEEDED } = EVENTS; function log (msg) { - // eslint-disable-next-line no-console - console.log(`%cNoBid Analytics ${VERSION}`, 'padding: 2px 8px 2px 8px; background-color:#f50057; color: white', msg); + logMessage(`%cNoBid Analytics ${VERSION}: ${msg}`); } function isJson (str) { return str && str.startsWith('{') && str.endsWith('}'); @@ -241,7 +240,7 @@ window.nobidCarbonizer = { adunit.bids = allowedBidders; } for (const adunit of adunits) { - if (!nobidAnalytics.originalAdUnits[adunit.code]) nobidAnalytics.originalAdUnits[adunit.code] = JSON.parse(JSON.stringify(adunit)); + if (!nobidAnalytics.originalAdUnits[adunit.code]) nobidAnalytics.originalAdUnits[adunit.code] = deepClone(adunit); }; if (this.isActive()) { // 5% of the time do not block; diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index 77e5a1c6fed..4865ea3bc9c 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -3,7 +3,7 @@ import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { getStorageManager } from '../src/storageManager.js'; -import { hasPurpose1Consent } from '../src/utils/gpdr.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/novatiqIdSystem.md b/modules/novatiqIdSystem.md index f33fc700311..a78363e8fe3 100644 --- a/modules/novatiqIdSystem.md +++ b/modules/novatiqIdSystem.md @@ -19,12 +19,11 @@ pbjs.setConfig({ name: 'novatiq', params: { // change to the Partner Number you received from Novatiq - sourceid '1a3' - } + sourceid: '1a3' } }], // 50ms maximum auction delay, applies to all userId modules - auctionDelay: 50 + auctionDelay: 50 } }); ``` diff --git a/modules/onetagBidAdapter.js b/modules/onetagBidAdapter.js index 62bee5c2aeb..8ddcb2c3980 100644 --- a/modules/onetagBidAdapter.js +++ b/modules/onetagBidAdapter.js @@ -93,7 +93,7 @@ function buildRequests(validBidRequests, bidderRequest) { const connection = navigator.connection || navigator.webkitConnection; payload.networkConnectionType = (connection && connection.type) ? connection.type : null; payload.networkEffectiveConnectionType = (connection && connection.effectiveType) ? connection.effectiveType : null; - payload.fledgeEnabled = Boolean(bidderRequest && bidderRequest.fledgeEnabled) + payload.fledgeEnabled = Boolean(bidderRequest?.paapi?.enabled) return { method: 'POST', url: ENDPOINT, @@ -156,7 +156,7 @@ function interpretResponse(serverResponse, bidderRequest) { const fledgeAuctionConfigs = body.fledgeAuctionConfigs return { bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, } } else { return bids; diff --git a/modules/ooloAnalyticsAdapter.js b/modules/ooloAnalyticsAdapter.js index 8a6ef88a7fb..573fee3b0b3 100644 --- a/modules/ooloAnalyticsAdapter.js +++ b/modules/ooloAnalyticsAdapter.js @@ -433,6 +433,11 @@ function sendPage() { function sendHbConfigData() { const conf = {} const pbjsConfig = config.getConfig() + // Check if pbjsConfig.userSync exists and has userIds property + if (pbjsConfig.userSync && pbjsConfig.userSync.userIds) { + // Delete the userIds property + delete pbjsConfig.userSync.userIds; + } Object.keys(pbjsConfig).forEach(key => { if (key[0] !== '_') { diff --git a/modules/openwebBidAdapter.js b/modules/openwebBidAdapter.js index 5bc74ac6465..60364f41d3c 100644 --- a/modules/openwebBidAdapter.js +++ b/modules/openwebBidAdapter.js @@ -2,33 +2,28 @@ import { logWarn, logInfo, isArray, - isFn, deepAccess, - isEmpty, - contains, - triggerPixel, - isInteger, - getBidIdParameter, - getDNT + triggerPixel } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { + getEndpoint, + generateBidsParams, + generateGeneralParams, + buildBidResponse, +} from '../libraries/riseUtils/index.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'openweb'; const ADAPTER_VERSION = '6.0.0'; const TTL = 360; const DEFAULT_CURRENCY = 'USD'; -const SELLER_ENDPOINT = 'https://hb.openwebmp.com/'; +const BASE_URL = 'https://hb.openwebmp.com/'; const MODES = { PRODUCTION: 'hb-multi', TEST: 'hb-multi-test' -} -const SUPPORTED_SYNC_METHODS = { - IFRAME: 'iframe', - PIXEL: 'pixel' -} +}; export const spec = { code: BIDDER_CODE, @@ -46,6 +41,11 @@ export const spec = { return false; } + if (!bidRequest.params.placementId) { + logWarn('placementId is a mandatory param for OpenWeb adapter'); + return false; + } + return true; }, buildRequests: function (validBidRequests, bidderRequest) { @@ -60,7 +60,7 @@ export const spec = { return { method: 'POST', - url: getEndpoint(testMode), + url: getEndpoint(testMode, BASE_URL, MODES), data: combinedRequestsObject } }, @@ -69,32 +69,7 @@ export const spec = { if (body && body.bids && body.bids.length) { body.bids.forEach(adUnit => { - const bidResponse = { - requestId: adUnit.requestId, - cpm: adUnit.cpm, - currency: adUnit.currency || DEFAULT_CURRENCY, - width: adUnit.width, - height: adUnit.height, - ttl: adUnit.ttl || TTL, - creativeId: adUnit.creativeId, - netRevenue: adUnit.netRevenue || true, - nurl: adUnit.nurl, - mediaType: adUnit.mediaType, - meta: { - mediaType: adUnit.mediaType - } - }; - - if (adUnit.mediaType === VIDEO) { - bidResponse.vastXml = adUnit.vastXml; - } else if (adUnit.mediaType === BANNER) { - bidResponse.ad = adUnit.ad; - } - - if (adUnit.adomain && adUnit.adomain.length) { - bidResponse.meta.advertiserDomains = adUnit.adomain; - } - + const bidResponse = buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER); bidResponses.push(bidResponse); }); } @@ -104,20 +79,20 @@ export const spec = { getUserSyncs: function (syncOptions, serverResponses) { const syncs = []; for (const response of serverResponses) { - if (syncOptions.iframeEnabled && response.body.params.userSyncURL) { + if (syncOptions.iframeEnabled && deepAccess(response, 'body.params.userSyncURL')) { syncs.push({ type: 'iframe', - url: response.body.params.userSyncURL + url: deepAccess(response, 'body.params.userSyncURL') }); } - if (syncOptions.pixelEnabled && isArray(response.body.params.userSyncPixels)) { + if (syncOptions.pixelEnabled && isArray(deepAccess(response, 'body.params.userSyncPixels'))) { const pixels = response.body.params.userSyncPixels.map(pixel => { return { type: 'image', url: pixel } - }) - syncs.push(...pixels) + }); + syncs.push(...pixels); } } return syncs; @@ -135,351 +110,3 @@ export const spec = { }; registerBidder(spec); - -/** - * Get floor price - * @param bid {bid} - * @returns {Number} - */ -function getFloor(bid, mediaType) { - if (!isFn(bid.getFloor)) { - return 0; - } - let floorResult = bid.getFloor({ - currency: DEFAULT_CURRENCY, - mediaType: mediaType, - size: '*' - }); - return floorResult.currency === DEFAULT_CURRENCY && floorResult.floor ? floorResult.floor : 0; -} - -/** - * Get the the ad sizes array from the bid - * @param bid {bid} - * @returns {Array} - */ -function getSizesArray(bid, mediaType) { - let sizesArray = [] - - if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) { - sizesArray = bid.mediaTypes[mediaType].sizes; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizesArray = bid.sizes; - } - - return sizesArray; -} - -/** - * Get schain string value - * @param schainObject {Object} - * @returns {string} - */ -function getSupplyChain(schainObject) { - if (isEmpty(schainObject)) { - return ''; - } - let scStr = `${schainObject.ver},${schainObject.complete}`; - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - return scStr; -} - -/** - * Get encoded node value - * @param val {string} - * @returns {string} - */ -function getEncodedValIfNotEmpty(val) { - return !isEmpty(val) ? encodeURIComponent(val) : ''; -} - -/** - * Get preferred user-sync method based on publisher configuration - * @param bidderCode {string} - * @returns {string} - */ -function getAllowedSyncMethod(filterSettings, bidderCode) { - const iframeConfigsToCheck = ['all', 'iframe']; - const pixelConfigToCheck = 'image'; - if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { - return SUPPORTED_SYNC_METHODS.IFRAME; - } - if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { - return SUPPORTED_SYNC_METHODS.PIXEL; - } -} - -/** - * Check if sync rule is supported - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - const isInclude = syncRule.filter === 'include'; - const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - return isInclude && contains(bidders, bidderCode); -} - -/** - * Get the seller endpoint - * @param testMode {boolean} - * @returns {string} - */ -function getEndpoint(testMode) { - return testMode - ? SELLER_ENDPOINT + MODES.TEST - : SELLER_ENDPOINT + MODES.PRODUCTION; -} - -/** - * get device type - * @param uad {ua} - * @returns {string} - */ -function getDeviceType(ua) { - if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i - .test(ua.toLowerCase())) { - return '5'; - } - if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i - .test(ua.toLowerCase())) { - return '4'; - } - if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i - .test(ua.toLowerCase())) { - return '3'; - } - return '1'; -} - -function generateBidsParams(validBidRequests, bidderRequest) { - const bidsArray = []; - - if (validBidRequests.length) { - validBidRequests.forEach(bid => { - bidsArray.push(generateBidParameters(bid, bidderRequest)); - }); - } - - return bidsArray; -} - -/** - * Generate bid specific parameters - * @param {bid} bid - * @param {bidderRequest} bidderRequest - * @returns {Object} bid specific params object - */ -function generateBidParameters(bid, bidderRequest) { - const {params} = bid; - const mediaType = isBanner(bid) ? BANNER : VIDEO; - const sizesArray = getSizesArray(bid, mediaType); - - // fix floor price in case of NAN - if (isNaN(params.floorPrice)) { - params.floorPrice = 0; - } - - const bidObject = { - mediaType, - adUnitCode: getBidIdParameter('adUnitCode', bid), - sizes: sizesArray, - floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice), - bidId: getBidIdParameter('bidId', bid), - loop: getBidIdParameter('bidderRequestsCount', bid), - bidderRequestId: getBidIdParameter('bidderRequestId', bid), - transactionId: bid.ortb2Imp?.ext?.tid || '', - coppa: 0, - }; - - const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`); - if (pos) { - bidObject.pos = pos; - } - - const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`); - if (gpid) { - bidObject.gpid = gpid; - } - - const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`); - if (placementId) { - bidObject.placementId = placementId; - } - - const mimes = deepAccess(bid, `mediaTypes.${mediaType}.mimes`); - if (mimes) { - bidObject.mimes = mimes; - } - const api = deepAccess(bid, `mediaTypes.${mediaType}.api`); - if (api) { - bidObject.api = api; - } - - const sua = deepAccess(bid, `ortb2.device.sua`); - if (sua) { - bidObject.sua = sua; - } - - const coppa = deepAccess(bid, `ortb2.regs.coppa`); - if (coppa) { - bidObject.coppa = 1; - } - - if (mediaType === VIDEO) { - const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`); - let playbackMethodValue; - - // verify playbackMethod is of type integer array, or integer only. - if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) { - // only the first playbackMethod in the array will be used, according to OpenRTB 2.5 recommendation - playbackMethodValue = playbackMethod[0]; - } else if (isInteger(playbackMethod)) { - playbackMethodValue = playbackMethod; - } - - if (playbackMethodValue) { - bidObject.playbackMethod = playbackMethodValue; - } - - const placement = deepAccess(bid, `mediaTypes.video.placement`); - if (placement) { - bidObject.placement = placement; - } - - const minDuration = deepAccess(bid, `mediaTypes.video.minduration`); - if (minDuration) { - bidObject.minDuration = minDuration; - } - - const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`); - if (maxDuration) { - bidObject.maxDuration = maxDuration; - } - - const skip = deepAccess(bid, `mediaTypes.video.skip`); - if (skip) { - bidObject.skip = skip; - } - - const linearity = deepAccess(bid, `mediaTypes.video.linearity`); - if (linearity) { - bidObject.linearity = linearity; - } - - const protocols = deepAccess(bid, `mediaTypes.video.protocols`); - if (protocols) { - bidObject.protocols = protocols; - } - - const plcmt = deepAccess(bid, `mediaTypes.video.plcmt`); - if (plcmt) { - bidObject.plcmt = plcmt; - } - } - - return bidObject; -} - -function isBanner(bid) { - return bid.mediaTypes && bid.mediaTypes.banner; -} - -/** - * Generate params that are common between all bids - * @param {single bid object} generalObject - * @param {bidderRequest} bidderRequest - * @returns {object} the common params object - */ -function generateGeneralParams(generalObject, bidderRequest) { - const domain = deepAccess(bidderRequest, 'refererInfo.domain') || window.location.hostname; - const {syncEnabled, filterSettings} = config.getConfig('userSync') || {}; - const {bidderCode, timeout} = bidderRequest; - const generalBidParams = generalObject.params; - - // these params are snake_case instead of camelCase to allow backwards compatability on the server. - // in the future, these will be converted to camelCase to match our convention. - const generalParams = { - wrapper_type: 'prebidjs', - wrapper_vendor: '$$PREBID_GLOBAL$$', - wrapper_version: '$prebid.version$', - adapter_version: ADAPTER_VERSION, - publisher_id: generalBidParams.org, - publisher_name: domain, - site_domain: domain, - dnt: getDNT() ? 1 : 0, - device_type: getDeviceType(navigator.userAgent), - ua: navigator.userAgent, - is_wrapper: !!generalBidParams.isWrapper, - session_id: generalBidParams.sessionId || getBidIdParameter('bidderRequestId', generalObject), - tmax: timeout - } - - const userIdsParam = getBidIdParameter('userId', generalObject); - if (userIdsParam) { - generalParams.userIds = JSON.stringify(userIdsParam); - } - - const ortb2Metadata = bidderRequest.ortb2 || {}; - if (ortb2Metadata.site) { - generalParams.site_metadata = JSON.stringify(ortb2Metadata.site); - } - if (ortb2Metadata.user) { - generalParams.user_metadata = JSON.stringify(ortb2Metadata.user); - } - - if (syncEnabled) { - const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); - if (allowedSyncMethod) { - generalParams.cs_method = allowedSyncMethod; - } - } - - if (bidderRequest.auctionStart) { - generalParams.auction_start = bidderRequest.auctionStart; - } - - if (bidderRequest.uspConsent) { - generalParams.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies; - generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - - if (bidderRequest.gppConsent) { - generalParams.gpp = bidderRequest.gppConsent.gppString; - generalParams.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - generalParams.gpp = bidderRequest.ortb2.regs.gpp; - generalParams.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - if (generalBidParams.ifa) { - generalParams.ifa = generalBidParams.ifa; - } - - if (generalObject.schain) { - generalParams.schain = getSupplyChain(generalObject.schain); - } - - if (bidderRequest && bidderRequest.refererInfo) { - generalParams.referrer = deepAccess(bidderRequest, 'refererInfo.ref'); - generalParams.page_url = deepAccess(bidderRequest, 'refererInfo.page') || deepAccess(window, 'location.href'); - } - - return generalParams; -} diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js index 81b710d09a1..8b16aa1a84e 100644 --- a/modules/openxBidAdapter.js +++ b/modules/openxBidAdapter.js @@ -4,7 +4,6 @@ import * as utils from '../src/utils.js'; import {mergeDeep} from '../src/utils.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; const bidderConfig = 'hb_pb_ortb'; const bidderVersion = '2.0'; @@ -18,8 +17,7 @@ export const spec = { isBidRequestValid, buildRequests, interpretResponse, - getUserSyncs, - transformBidParams + getUserSyncs }; registerBidder(spec); @@ -116,7 +114,7 @@ const converter = ortbConverter({ }); return { bids: response.bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, } } else { return response.bids @@ -150,13 +148,6 @@ const converter = ortbConverter({ } }); -function transformBidParams(params, isOpenRtb) { - return convertTypes({ - 'unit': 'string', - 'customFloor': 'number' - }, params); -} - function isBidRequestValid(bidRequest) { const hasDelDomainOrPlatform = bidRequest.params.delDomain || bidRequest.params.platform; diff --git a/modules/operaadsBidAdapter.js b/modules/operaadsBidAdapter.js index 957192d1bec..486d5ac726b 100644 --- a/modules/operaadsBidAdapter.js +++ b/modules/operaadsBidAdapter.js @@ -525,7 +525,6 @@ function createImp(bidRequest) { playbackmethod: videoReq.playbackmethod || VIDEO_DEFAULTS.PLAYBACK_METHODS, delivery: videoReq.delivery || VIDEO_DEFAULTS.DELIVERY, api: videoReq.api || VIDEO_DEFAULTS.API, - placement: videoReq.context === OUTSTREAM ? 3 : 1, }; mediaType = VIDEO; diff --git a/modules/optableBidAdapter.js b/modules/optableBidAdapter.js index f6c7cf00a35..4e639fb88ee 100644 --- a/modules/optableBidAdapter.js +++ b/modules/optableBidAdapter.js @@ -35,7 +35,7 @@ export const spec = { return { bidId: impid, config } }) - return { bids, fledgeAuctionConfigs: auctionConfigs } + return { bids, paapi: auctionConfigs } }, supportedMediaTypes: [BANNER] } diff --git a/modules/optoutBidAdapter.js b/modules/optoutBidAdapter.js index f7b5934665c..f0010d54833 100644 --- a/modules/optoutBidAdapter.js +++ b/modules/optoutBidAdapter.js @@ -1,7 +1,7 @@ import { deepAccess } from '../src/utils.js'; import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; const BIDDER_CODE = 'optout'; diff --git a/modules/orakiBidAdapter.js b/modules/orakiBidAdapter.js new file mode 100644 index 00000000000..d3ef143249b --- /dev/null +++ b/modules/orakiBidAdapter.js @@ -0,0 +1,19 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; + +const BIDDER_CODE = 'oraki'; +const AD_URL = 'https://eu1.oraki.io/pbjs'; +const SYNC_URL = 'https://sync.oraki.io'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) +}; + +registerBidder(spec); diff --git a/modules/orakiBidAdapter.md b/modules/orakiBidAdapter.md new file mode 100644 index 00000000000..ce35021a937 --- /dev/null +++ b/modules/orakiBidAdapter.md @@ -0,0 +1,79 @@ +# Overview + +``` +Module Name: Oraki Bidder Adapter +Module Type: Oraki Bidder Adapter +Maintainer: ben@oraki.io +``` + +# Description + +Connects to Oraki exchange for bids. +Oraki bid adapter supports Banner, Video (instream and outstream) and Native. + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'adunit1', + mediaTypes: { + banner: { + sizes: [ [300, 250], [320, 50] ], + } + }, + bids: [ + { + bidder: 'oraki', + params: { + placementId: 'testBanner', + } + } + ] + }, + { + code: 'addunit2', + mediaTypes: { + video: { + playerSize: [ [640, 480] ], + context: 'instream', + minduration: 5, + maxduration: 60, + } + }, + bids: [ + { + bidder: 'oraki', + params: { + placementId: 'testVideo', + } + } + ] + }, + { + code: 'addunit3', + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + }, + bids: [ + { + bidder: 'oraki', + params: { + placementId: 'testNative', + } + } + ] + } + ]; +``` diff --git a/modules/orbidderBidAdapter.js b/modules/orbidderBidAdapter.js index 0f912384db7..dc8293e74f2 100644 --- a/modules/orbidderBidAdapter.js +++ b/modules/orbidderBidAdapter.js @@ -3,7 +3,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import { getGlobal } from '../src/prebidGlobal.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -93,6 +92,9 @@ export const spec = { if (bidderRequest && bidderRequest.refererInfo) { referer = bidderRequest.refererInfo.page || ''; } + if (bidRequest?.mediaTypes?.video) { + delete bidRequest.mediaTypes.video; + } bidRequest.params.bidfloor = getBidFloor(bidRequest); @@ -101,7 +103,7 @@ export const spec = { method: 'POST', options: { withCredentials: true }, data: { - v: getGlobal().version, + v: 'v' + '$prebid.version$', pageUrl: referer, ...bidRequest // get all data provided by bid request } diff --git a/modules/outbrainBidAdapter.js b/modules/outbrainBidAdapter.js index 9690b79fea5..5ce514a46d7 100644 --- a/modules/outbrainBidAdapter.js +++ b/modules/outbrainBidAdapter.js @@ -5,7 +5,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import { getStorageManager } from '../src/storageManager.js'; import {OUTSTREAM} from '../src/video.js'; -import {_map, deepAccess, deepSetValue, isArray, logWarn, replaceAuctionPrice} from '../src/utils.js'; +import {_map, deepAccess, deepSetValue, logWarn, replaceAuctionPrice, setOnAny, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js'; import {ajax} from '../src/ajax.js'; import {config} from '../src/config.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; @@ -94,7 +94,7 @@ export const spec = { imp.video = getVideoAsset(bid); } else { imp.banner = { - format: transformSizes(bid.sizes) + format: bid.sizes?.map((size) => parseGPTSingleSizeArrayToRtbSize(size)) } } @@ -111,7 +111,7 @@ export const spec = { const request = { id: bidderRequest.bidderRequestId, site: { page, publisher }, - device: { ua }, + device: ortb2?.device || { ua }, source: { fd: 1 }, cur: [cur], tmax: timeout, @@ -174,7 +174,7 @@ export const spec = { } const { seatbid, cur } = serverResponse.body; - const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => { + const bidResponses = seatbid.map(seat => seat.bid).flat().reduce((result, bid) => { result[bid.impid - 1] = bid; return result; }, []); @@ -288,19 +288,6 @@ function parseNative(bid) { return result; } -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - -function flatten(arr) { - return [].concat(...arr); -} - function getNativeAssets(bid) { return _map(bid.nativeParams, (bidParams, key) => { const props = NATIVE_PARAMS[key]; @@ -319,7 +306,7 @@ function getNativeAssets(bid) { } if (bidParams.sizes) { - const sizes = flatten(bidParams.sizes); + const sizes = bidParams.sizes.flat(); w = parseInt(sizes[0], 10); h = parseInt(sizes[1], 10); } @@ -339,7 +326,7 @@ function getNativeAssets(bid) { } function getVideoAsset(bid) { - const sizes = flatten(bid.mediaTypes.video.playerSize); + const sizes = bid.mediaTypes.video.playerSize.flat(); return { w: parseInt(sizes[0], 10), h: parseInt(sizes[1], 10), @@ -354,34 +341,12 @@ function getVideoAsset(bid) { minduration: bid.mediaTypes.video.minduration, maxduration: bid.mediaTypes.video.maxduration, startdelay: bid.mediaTypes.video.startdelay, - placement: bid.mediaTypes.video.plcmt ?? bid.mediaTypes.video.placement, + placement: bid.mediaTypes.video.placement, + plcmt: bid.mediaTypes.video.plcmt, linearity: bid.mediaTypes.video.linearity }; } -/* Turn bid request sizes into ut-compatible format */ -function transformSizes(requestSizes) { - if (!isArray(requestSizes)) { - return []; - } - - if (requestSizes.length === 2 && !isArray(requestSizes[0])) { - return [{ - w: parseInt(requestSizes[0], 10), - h: parseInt(requestSizes[1], 10) - }]; - } else if (isArray(requestSizes[0])) { - return requestSizes.map(item => - ({ - w: parseInt(item[0], 10), - h: parseInt(item[1], 10) - }) - ); - } - - return []; -} - function _getFloor(bid, type) { const floorInfo = bid.getFloor({ currency: CURRENCY, diff --git a/modules/oxxionAnalyticsAdapter.js b/modules/oxxionAnalyticsAdapter.js index b3bc2d3479f..9e18c92d25b 100644 --- a/modules/oxxionAnalyticsAdapter.js +++ b/modules/oxxionAnalyticsAdapter.js @@ -3,6 +3,7 @@ import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; import { ajax } from '../src/ajax.js'; import { getRefererInfo } from '../src/refererDetection.js'; +import { deepClone } from '../src/utils.js'; const analyticsType = 'endpoint'; const url = 'URL_TO_SERVER_ENDPOINT'; @@ -125,7 +126,7 @@ function addTimeout(args) { let stringArgs = JSON.parse(dereferenceWithoutRenderer(args)); argsDereferenced = stringArgs; argsDereferenced.forEach((attr) => { - argsCleaned.push(filterAttributes(JSON.parse(JSON.stringify(attr)), false)); + argsCleaned.push(filterAttributes(deepClone(attr), false)); }); if (auctionEnd[eventType] == undefined) { auctionEnd[eventType] = [] } auctionEnd[eventType].push(argsCleaned); diff --git a/modules/ozoneBidAdapter.js b/modules/ozoneBidAdapter.js index 0d921f57cda..7a4a5a9717c 100644 --- a/modules/ozoneBidAdapter.js +++ b/modules/ozoneBidAdapter.js @@ -8,7 +8,7 @@ import { contains, mergeDeep, parseUrl, - generateUUID + generateUUID, isInteger, deepClone } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; @@ -22,7 +22,7 @@ const AUCTIONURI = '/openrtb2/auction'; const OZONECOOKIESYNC = '/static/load-cookie.html'; const OZONE_RENDERER_URL = 'https://prebid.the-ozone-project.com/ozone-renderer.js'; const ORIGIN_DEV = 'https://test.ozpr.net'; -const OZONEVERSION = '2.9.1'; +const OZONEVERSION = '2.9.3'; export const spec = { gvlid: 524, aliases: [{code: 'lmc', gvlid: 524}, {code: 'venatus', gvlid: 524}], @@ -38,7 +38,7 @@ export const spec = { 'auctionUrl': ORIGIN + AUCTIONURI, 'cookieSyncUrl': ORIGIN + OZONECOOKIESYNC, 'rendererUrl': OZONE_RENDERER_URL, - 'batchRequests': false /* you can change this to true OR override it in the config: config.ozone.batchRequests */ + 'batchRequests': false /* you can change this to true OR numeric OR override it in the config: config.ozone.batchRequests = true/false/number */ }, loadWhitelabelData(bid) { if (this.propertyBag.whitelabel) { return; } @@ -47,7 +47,7 @@ export const spec = { this.propertyBag.whitelabel.logId = bidder.toUpperCase(); this.propertyBag.whitelabel.bidder = bidder; let bidderConfig = config.getConfig(bidder) || {}; - logInfo('got bidderConfig: ', JSON.parse(JSON.stringify(bidderConfig))); + logInfo('got bidderConfig: ', deepClone(bidderConfig)); if (bidderConfig.kvpPrefix) { this.propertyBag.whitelabel.keyPrefix = bidderConfig.kvpPrefix; } @@ -76,10 +76,22 @@ export const spec = { } } if (bidderConfig.hasOwnProperty('batchRequests')) { - this.propertyBag.whitelabel.batchRequests = bidderConfig.batchRequests; + if (this.batchValueIsValid(bidderConfig.batchRequests)) { + this.propertyBag.whitelabel.batchRequests = bidderConfig.batchRequests; + } else { + logError('bidderConfig.batchRequests must be boolean or a number. Found & ignored data type: ' + typeof bidderConfig.batchRequests); + } + } + if (bidderConfig.hasOwnProperty('videoParams')) { + this.propertyBag.whitelabel.videoParams = bidderConfig.videoParams; } if (arr.hasOwnProperty('batchRequests')) { - this.propertyBag.whitelabel.batchRequests = true; + let getBatch = parseInt(arr.batchRequests); + if (this.batchValueIsValid(getBatch)) { + this.propertyBag.whitelabel.batchRequests = getBatch; + } else { + logError('Ignoring query param: batchRequests - this must be a positive number'); + } } try { if (arr.hasOwnProperty('auction') && arr.auction === 'dev') { @@ -93,6 +105,9 @@ export const spec = { } catch (e) {} logInfo('set propertyBag.whitelabel to', this.propertyBag.whitelabel); }, + batchValueIsValid(batch) { + return typeof batch === 'boolean' || (typeof batch === 'number' && batch > 0); + }, getAuctionUrl() { return this.propertyBag.whitelabel.auctionUrl; }, @@ -102,9 +117,17 @@ export const spec = { getRendererUrl() { return this.propertyBag.whitelabel.rendererUrl; }, - isBatchRequests() { - logInfo('isBatchRequests going to return ', this.propertyBag.whitelabel.batchRequests); - return this.propertyBag.whitelabel.batchRequests; + getVideoPlacementValue: function(context) { + if (['instream', 'outstream'].indexOf(context) < 0) return null; + return deepAccess(this.propertyBag, `whitelabel.videoParams.${context}`, null); + }, + getBatchRequests() { + logInfo('getBatchRequests going to return ', this.propertyBag.whitelabel.batchRequests); + if (this.propertyBag.whitelabel.batchRequests === true) { return 10; } + if (typeof this.propertyBag.whitelabel.batchRequests === 'number' && this.propertyBag.whitelabel.batchRequests > 0) { + return this.propertyBag.whitelabel.batchRequests; + } + return false; }, isBidRequestValid(bid) { this.loadWhitelabelData(bid); @@ -177,13 +200,14 @@ export const spec = { this.propertyBag.buildRequestsStart = new Date().getTime(); let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix; - logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest))); + logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, deepClone(validBidRequests), 'bidderRequest', deepClone(bidderRequest)); if (this.blockTheRequest()) { return []; } + let fledgeEnabled = !!bidderRequest.fledgeEnabled; // IF true then this is added as each bid[].ext.ae=1 let htmlParams = {'publisherId': '', 'siteId': ''}; if (validBidRequests.length > 0) { - this.cookieSyncBag.userIdObject = Object.assign(this.cookieSyncBag.userIdObject, this.findAllUserIds(validBidRequests[0])); + this.cookieSyncBag.userIdObject = Object.assign(this.cookieSyncBag.userIdObject, this.findAllUserIdsFromEids(validBidRequests[0])); this.cookieSyncBag.siteId = deepAccess(validBidRequests[0], 'params.siteId'); this.cookieSyncBag.publisherId = deepAccess(validBidRequests[0], 'params.publisherId'); htmlParams = validBidRequests[0].params; @@ -305,6 +329,14 @@ export const spec = { if (gpid) { deepSetValue(obj, 'ext.gpid', gpid); } + if (fledgeEnabled) { // fledge is enabled at some config level - pbjs.setBidderConfig or pbjs.setConfig + const auctionEnvironment = deepAccess(ozoneBidRequest, 'ortb2Imp.ext.ae'); // this will be set for one of 3 reasons; adunit, setBidderConfig, setConfig + if (isInteger(auctionEnvironment)) { + deepSetValue(obj, 'ext.ae', auctionEnvironment); + } else { + logError('ortb2Imp.ext.ae is not an integer - ignoring it for obj.id=' + obj.id); + } + } return obj; }); let extObj = {}; @@ -313,8 +345,8 @@ export const spec = { extObj[whitelabelBidder][whitelabelPrefix + '_rw'] = placementIdOverrideFromGetParam ? 1 : 0; if (validBidRequests.length > 0) { let userIds = this.cookieSyncBag.userIdObject; // 2021-01-06 - slight optimisation - we've already found this info - if (userIds.hasOwnProperty('pubcid')) { - extObj[whitelabelBidder].pubcid = userIds.pubcid; + if (userIds.hasOwnProperty('pubcid.org')) { + extObj[whitelabelBidder].pubcid = userIds['pubcid.org']; } } extObj[whitelabelBidder].pv = this.getPageId(); // attach the page ID that will be common to all auction calls for this page if refresh() is called @@ -362,6 +394,10 @@ export const spec = { } else { logInfo('WILL NOT ADD USP consent info; no bidderRequest.uspConsent.'); } + if (bidderRequest?.ortb2?.regs?.gpp) { + deepSetValue(ozoneRequest, 'regs.gpp', bidderRequest.ortb2.regs.gpp); + deepSetValue(ozoneRequest, 'regs.gpp_sid', bidderRequest.ortb2.regs.gpp_sid); + } if (schain) { // we set this while iterating over the bids logInfo('schain found'); deepSetValue(ozoneRequest, 'source.ext.schain', schain); @@ -369,15 +405,26 @@ export const spec = { if (config.getConfig('coppa') === true) { deepSetValue(ozoneRequest, 'regs.coppa', 1); } + extObj[whitelabelBidder].cookieDeprecationLabel = deepAccess(bidderRequest, 'ortb2.device.ext.cdep', 'none'); + logInfo('cookieDeprecationLabel from bidderRequest object = ' + extObj[whitelabelBidder].cookieDeprecationLabel); let ozUuid = generateUUID(); - if (this.isBatchRequests()) { + let batchRequestsVal = this.getBatchRequests(); // false|numeric + if (typeof batchRequestsVal === 'number') { logInfo('going to batch the requests'); let arrRet = []; // return an array of objects containing data describing max 10 bids - for (let i = 0; i < tosendtags.length; i += 10) { - ozoneRequest.id = ozUuid; // Unique ID of the bid request, provided by the exchange. (REQUIRED) - ozoneRequest.imp = tosendtags.slice(i, i + 10); - ozoneRequest.ext = extObj; + for (let i = 0; i < tosendtags.length; i += batchRequestsVal) { + if (bidderRequest.auctionId) { + logInfo('Found bidderRequest.auctionId - will pass these values through & not generate our own id'); + ozoneRequest.id = bidderRequest.auctionId; + ozoneRequest.auctionId = bidderRequest.auctionId; + deepSetValue(ozoneRequest, 'source.tid', deepAccess(bidderRequest, 'ortb2.source.tid')); + } else { + logInfo('Did not find bidderRequest.auctionId - will generate our own id'); + ozoneRequest.id = ozUuid; // Unique ID of the bid request, provided by the exchange. (REQUIRED) + } deepSetValue(ozoneRequest, 'user.ext.eids', userExtEids); + ozoneRequest.imp = tosendtags.slice(i, i + batchRequestsVal); + ozoneRequest.ext = extObj; if (ozoneRequest.imp.length > 0) { arrRet.push({ method: 'POST', @@ -393,7 +440,15 @@ export const spec = { logInfo('requests will not be batched.'); if (singleRequest) { logInfo('buildRequests starting to generate response for a single request'); - ozoneRequest.id = ozUuid; // Unique ID of the bid request, provided by the exchange. (REQUIRED) + if (bidderRequest.auctionId) { + logInfo('Found bidderRequest.auctionId - will pass these values through & not generate our own id'); + ozoneRequest.id = bidderRequest.auctionId; + ozoneRequest.auctionId = bidderRequest.auctionId; + deepSetValue(ozoneRequest, 'source.tid', deepAccess(bidderRequest, 'ortb2.source.tid')); + } else { + logInfo('Did not find bidderRequest.auctionId - will generate our own id'); + ozoneRequest.id = ozUuid; // Unique ID of the bid request, provided by the exchange. (REQUIRED) + } ozoneRequest.imp = tosendtags; ozoneRequest.ext = extObj; deepSetValue(ozoneRequest, 'user.ext.eids', userExtEids); @@ -403,7 +458,7 @@ export const spec = { data: JSON.stringify(ozoneRequest), bidderRequest: bidderRequest }; - logInfo('buildRequests request data for single = ', JSON.parse(JSON.stringify(ozoneRequest))); + logInfo('buildRequests request data for single = ', deepClone(ozoneRequest)); this.propertyBag.buildRequestsEnd = new Date().getTime(); logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret); return ret; @@ -444,7 +499,7 @@ export const spec = { if (mediaTypesSizes.native) { ret.native = bidRequestRef.getFloor({mediaType: 'native', currency: 'USD', size: mediaTypesSizes.native}); } - logInfo('getFloorObjectForAuction returning : ', JSON.parse(JSON.stringify(ret))); + logInfo('getFloorObjectForAuction returning : ', deepClone(ret)); return ret; }, interpretResponse(serverResponse, request) { @@ -453,7 +508,7 @@ export const spec = { let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix; logInfo(`interpretResponse time: ${startTime} . Time between buildRequests done and interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`); - logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request))); + logInfo(`serverResponse, request`, deepClone(serverResponse), deepClone(request)); serverResponse = serverResponse.body || {}; let aucId = serverResponse.id; // this will be correct for single requests and non-single if (!serverResponse.hasOwnProperty('seatbid')) { @@ -480,7 +535,7 @@ export const spec = { for (let j = 0; j < sb.bid.length; j++) { let thisRequestBid = this.getBidRequestForBidId(sb.bid[j].impid, request.bidderRequest.bids); logInfo(`seatbid:${i}, bid:${j} Going to set default w h for seatbid/bidRequest`, sb.bid[j], thisRequestBid); - const {defaultWidth, defaultHeight} = defaultSize(thisRequestBid); + let {defaultWidth, defaultHeight} = defaultSize(thisRequestBid); let thisBid = ozoneAddStandardProperties(sb.bid[j], defaultWidth, defaultHeight); thisBid.meta = {advertiserDomains: thisBid.adomain || []}; let videoContext = null; @@ -512,8 +567,8 @@ export const spec = { this.setBidMediaTypeIfNotExist(thisBid, BANNER); } if (enhancedAdserverTargeting) { - let allBidsForThisBidid = ozoneGetAllBidsForBidId(thisBid.bidId, serverResponse.seatbid); - logInfo('Going to iterate allBidsForThisBidId', allBidsForThisBidid); + let allBidsForThisBidid = ozoneGetAllBidsForBidId(thisBid.bidId, serverResponse.seatbid, defaultWidth, defaultHeight); + logInfo('Going to iterate allBidsForThisBidId', deepClone(allBidsForThisBidid)); Object.keys(allBidsForThisBidid).forEach((bidderName, index, ar2) => { logInfo(`adding adserverTargeting for ${bidderName} for bidId ${thisBid.bidId}`); adserverTargeting[whitelabelPrefix + '_' + bidderName] = bidderName; @@ -521,6 +576,7 @@ export const spec = { adserverTargeting[whitelabelPrefix + '_' + bidderName + '_adv'] = String(allBidsForThisBidid[bidderName].adomain); adserverTargeting[whitelabelPrefix + '_' + bidderName + '_adId'] = String(allBidsForThisBidid[bidderName].adId); adserverTargeting[whitelabelPrefix + '_' + bidderName + '_pb_r'] = getRoundedBid(allBidsForThisBidid[bidderName].price, allBidsForThisBidid[bidderName].ext.prebid.type); + adserverTargeting[whitelabelPrefix + '_' + bidderName + '_size'] = String(allBidsForThisBidid[bidderName].width) + 'x' + String(allBidsForThisBidid[bidderName].height); if (allBidsForThisBidid[bidderName].hasOwnProperty('dealid')) { adserverTargeting[whitelabelPrefix + '_' + bidderName + '_dealid'] = String(allBidsForThisBidid[bidderName].dealid); } @@ -550,6 +606,7 @@ export const spec = { } } let {seat: winningSeat, bid: winningBid} = ozoneGetWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid); + winningBid = ozoneAddStandardProperties(winningBid, defaultWidth, defaultHeight); adserverTargeting[whitelabelPrefix + '_auc_id'] = String(aucId); // was request.bidderRequest.auctionId adserverTargeting[whitelabelPrefix + '_winner'] = String(winningSeat); adserverTargeting[whitelabelPrefix + '_bid'] = 'true'; @@ -571,10 +628,28 @@ export const spec = { arrAllBids.push(thisBid); } } + let ret = arrAllBids; + let fledgeAuctionConfigs = deepAccess(serverResponse, 'ext.igi') || []; // 20240606 standardising + if (Array.isArray(fledgeAuctionConfigs) && fledgeAuctionConfigs.length > 0) { + fledgeAuctionConfigs = fledgeAuctionConfigs.filter(config => { + if (!this.isValidAuctionConfig(config)) { + logWarn('Malformed auction config detected:', config); + return false; + } + return true; + }); + ret = { + bids: arrAllBids, + fledgeAuctionConfigs, + }; + } let endTime = new Date().getTime(); logInfo(`interpretResponse going to return at time ${endTime} (took ${endTime - startTime}ms) Time from buildRequests Start -> interpretRequests End = ${endTime - this.propertyBag.buildRequestsStart}ms`); - logInfo('interpretResponse arrAllBids (serialised): ', JSON.parse(JSON.stringify(arrAllBids))); // this is ok to log because the renderer has not been attached yet - return arrAllBids; + logInfo('interpretResponse arrAllBids (serialised): ', deepClone(ret)); // this is ok to log because the renderer has not been attached yet + return ret; + }, + isValidAuctionConfig(config) { + return typeof config === 'object' && config !== null; }, setBidMediaTypeIfNotExist(thisBid, mediaType) { if (!thisBid.hasOwnProperty('mediaType')) { @@ -613,11 +688,12 @@ export const spec = { } return ret; }, - getUserSyncs(optionsType, serverResponse, gdprConsent, usPrivacy) { + getUserSyncs(optionsType, serverResponse, gdprConsent, usPrivacy, gppConsent = {}) { logInfo('getUserSyncs optionsType', optionsType, 'serverResponse', serverResponse, 'gdprConsent', gdprConsent, 'usPrivacy', usPrivacy, 'cookieSyncBag', this.cookieSyncBag); if (!serverResponse || serverResponse.length === 0) { return []; } + let { gppString = '', applicableSections = [] } = gppConsent; if (optionsType.iframeEnabled) { var arrQueryString = []; if (config.getConfig('debug')) { @@ -626,6 +702,10 @@ export const spec = { arrQueryString.push('gdpr=' + (deepAccess(gdprConsent, 'gdprApplies', false) ? '1' : '0')); arrQueryString.push('gdpr_consent=' + deepAccess(gdprConsent, 'consentString', '')); arrQueryString.push('usp_consent=' + (usPrivacy || '')); + arrQueryString.push('gpp=' + gppString); + if (Array.isArray(applicableSections)) { + arrQueryString.push(`gpp_sid=${applicableSections.join()}`); + } for (let keyname in this.cookieSyncBag.userIdObject) { arrQueryString.push(keyname + '=' + this.cookieSyncBag.userIdObject[keyname]); } @@ -659,47 +739,26 @@ export const spec = { } return null; }, - findAllUserIds(bidRequest) { - var ret = {}; - let searchKeysSingle = ['pubcid', 'tdid', 'idl_env', 'criteoId', 'lotamePanoramaId', 'fabrickId']; - if (bidRequest.hasOwnProperty('userId')) { - for (let arrayId in searchKeysSingle) { - let key = searchKeysSingle[arrayId]; - if (bidRequest.userId.hasOwnProperty(key)) { - if (typeof (bidRequest.userId[key]) == 'string') { - ret[key] = bidRequest.userId[key]; - } else if (typeof (bidRequest.userId[key]) == 'object') { - logError(`WARNING: findAllUserIds had to use first key in user object to get value for bid.userId key: ${key}. Prebid adapter should be updated.`); - ret[key] = bidRequest.userId[key][Object.keys(bidRequest.userId[key])[0]]; // cannot use Object.values - } else { - logError(`failed to get string key value for userId : ${key}`); - } - } - } - let lipbid = deepAccess(bidRequest.userId, 'lipb.lipbid'); - if (lipbid) { - ret['lipb'] = {'lipbid': lipbid}; - } - let id5id = deepAccess(bidRequest.userId, 'id5id.uid'); - if (id5id) { - ret['id5id'] = id5id; - } - let parrableId = deepAccess(bidRequest.userId, 'parrableId.eid'); - if (parrableId) { - ret['parrableId'] = parrableId; - } - let sharedid = deepAccess(bidRequest.userId, 'sharedid.id'); - if (sharedid) { - ret['sharedid'] = sharedid; - } + findAllUserIdsFromEids(bidRequest) { + let ret = {}; + if (!bidRequest.hasOwnProperty('userIdAsEids')) { + logInfo('findAllUserIdsFromEids - no bidRequest.userIdAsEids object - will quit'); + this.tryGetPubCidFromOldLocation(ret, bidRequest); // legacy + return ret; + } + for (let obj of bidRequest.userIdAsEids) { + ret[obj.source] = deepAccess(obj, 'uids.0.id'); } + this.tryGetPubCidFromOldLocation(ret, bidRequest); // legacy + return ret; + }, + tryGetPubCidFromOldLocation(ret, bidRequest) { if (!ret.hasOwnProperty('pubcid')) { let pubcid = deepAccess(bidRequest, 'crumbs.pubcid'); if (pubcid) { - ret['pubcid'] = pubcid; // if built with old pubCommonId module + ret['pubcid.org'] = pubcid; // if built with old pubCommonId module (use the new eid key) } } - return ret; }, getPlacementId(bidRequest) { return (bidRequest.params.placementId).toString(); @@ -767,7 +826,7 @@ export const spec = { return ret; }, _unpackVideoConfigIntoIABformat(ret, objConfig) { - let arrVideoKeysAllowed = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype']; + let arrVideoKeysAllowed = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'plcmt', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype']; for (const key in objConfig) { var found = false; arrVideoKeysAllowed.forEach(function(arg) { @@ -795,11 +854,9 @@ export const spec = { return objRet; }, _addVideoDefaults(objRet, objConfig, addIfMissing) { - let context = deepAccess(objConfig, 'context'); - if (context === 'outstream') { - objRet.placement = 3; - } else if (context === 'instream') { - objRet.placement = 1; + let placementValue = this.getVideoPlacementValue(deepAccess(objConfig, 'context')); + if (placementValue) { + objRet.placement = placementValue; } let skippable = deepAccess(objConfig, 'skippable', null); if (skippable == null) { @@ -843,7 +900,7 @@ export const spec = { } }; export function injectAdIdsIntoAllBidResponses(seatbid) { - logInfo('injectAdIdsIntoAllBidResponses', seatbid); + logInfo('injectAdIdsIntoAllBidResponses', deepClone(seatbid)); for (let i = 0; i < seatbid.length; i++) { let sb = seatbid[i]; for (let j = 0; j < sb.bid.length; j++) { @@ -895,7 +952,7 @@ export function ozoneGetWinnerForRequestBid(requestBidId, serverResponseSeatBid) } return {'seat': winningSeat, 'bid': thisBidWinner}; } -export function ozoneGetAllBidsForBidId(matchBidId, serverResponseSeatBid) { +export function ozoneGetAllBidsForBidId(matchBidId, serverResponseSeatBid, defaultWidth, defaultHeight) { let objBids = {}; for (let j = 0; j < serverResponseSeatBid.length; j++) { let theseBids = serverResponseSeatBid[j].bid; @@ -904,10 +961,11 @@ export function ozoneGetAllBidsForBidId(matchBidId, serverResponseSeatBid) { if (theseBids[k].impid === matchBidId) { if (objBids.hasOwnProperty(thisSeat)) { // > 1 bid for an adunit from a bidder - only use the one with the highest bid if (objBids[thisSeat]['price'] < theseBids[k].price) { - objBids[thisSeat] = theseBids[k]; + objBids[thisSeat] = ozoneAddStandardProperties(theseBids[k], defaultWidth, defaultHeight); } } else { objBids[thisSeat] = theseBids[k]; + objBids[thisSeat] = ozoneAddStandardProperties(theseBids[k], defaultWidth, defaultHeight); } } } @@ -1039,7 +1097,7 @@ function newRenderer(adUnitCode, rendererOptions = {}) { } function outstreamRender(bid) { logInfo('outstreamRender called. Going to push the call to window.ozoneVideo.outstreamRender(bid) bid = (first static, then reference)'); - logInfo(JSON.parse(JSON.stringify(spec.getLoggableBidObject(bid)))); + logInfo(deepClone(spec.getLoggableBidObject(bid))); bid.renderer.push(() => { logInfo('Going to execute window.ozoneVideo.outstreamRender'); window.ozoneVideo.outstreamRender(bid); diff --git a/modules/paapi.js b/modules/paapi.js index c6cd380c1c9..9ae2c870e5d 100644 --- a/modules/paapi.js +++ b/modules/paapi.js @@ -34,10 +34,8 @@ const pendingBuyersForAuction = auctionStore(); let latestAuctionForAdUnit = {}; let moduleConfig = {}; -['paapi', 'fledgeForGpt'].forEach(ns => { - config.getConfig(ns, config => { - init(config[ns], ns); - }); +config.getConfig('paapi', config => { + init(config.paapi); }); export function reset() { @@ -45,10 +43,7 @@ export function reset() { latestAuctionForAdUnit = {}; } -export function init(cfg, configNamespace) { - if (configNamespace !== 'paapi') { - logWarn(`'${configNamespace}' configuration options will be renamed to 'paapi'; consider using setConfig({paapi: [...]}) instead`); - } +export function init(cfg) { if (cfg && cfg.enabled === true) { moduleConfig = cfg; logInfo(`${MODULE} enabled (browser ${isFledgeSupported() ? 'supports' : 'does NOT support'} runAdAuction)`, cfg); @@ -59,6 +54,7 @@ export function init(cfg, configNamespace) { } getHook('addPaapiConfig').before(addPaapiConfigHook); +getHook('makeBidRequests').before(addPaapiData); getHook('makeBidRequests').after(markForFledge); events.on(EVENTS.AUCTION_END, onAuctionEnd); @@ -147,7 +143,7 @@ function setFPD(target, {ortb2, ortb2Imp}) { } export function addPaapiConfigHook(next, request, paapiConfig) { - if (getFledgeConfig().enabled) { + if (getFledgeConfig(config.getCurrentBidder()).enabled) { const {adUnitCode, auctionId} = request; // eslint-disable-next-line no-inner-declarations @@ -163,8 +159,9 @@ export function addPaapiConfigHook(next, request, paapiConfig) { const {config, igb} = paapiConfig; if (config) { config.auctionSignals = setFPD(config.auctionSignals || {}, request); + const pbs = config.perBuyerSignals = config.perBuyerSignals ?? {}; (config.interestGroupBuyers || []).forEach(buyer => { - deepSetValue(config, `perBuyerSignals.${buyer}`, setFPD(config.perBuyerSignals?.[buyer] || {}, request)); + pbs[buyer] = setFPD(pbs[buyer] ?? {}, request); }) storePendingData(pendingConfigsForAuction, config); } @@ -305,12 +302,11 @@ function isFledgeSupported() { return 'runAdAuction' in navigator && 'joinAdInterestGroup' in navigator; } -function getFledgeConfig() { - const bidder = config.getCurrentBidder(); - const useGlobalConfig = moduleConfig.enabled && (bidder == null || !moduleConfig.bidders?.length || moduleConfig.bidders?.includes(bidder)); +function getFledgeConfig(bidder) { + const enabled = moduleConfig.enabled && (bidder == null || !moduleConfig.bidders?.length || moduleConfig.bidders?.includes(bidder)); return { - enabled: config.getConfig('fledgeEnabled') ?? useGlobalConfig, - ae: config.getConfig('defaultForSlots') ?? (useGlobalConfig ? moduleConfig.defaultForSlots : undefined) + enabled, + ae: enabled ? moduleConfig.defaultForSlots : undefined }; } @@ -337,40 +333,49 @@ function getRequestedSize(adUnit) { })(); } +export function addPaapiData(next, adUnits, ...args) { + if (isFledgeSupported() && moduleConfig.enabled) { + adUnits.forEach(adUnit => { + // https://github.com/InteractiveAdvertisingBureau/openrtb/blob/main/extensions/community_extensions/Protected%20Audience%20Support.md + const igsAe = adUnit.ortb2Imp?.ext?.igs != null + ? adUnit.ortb2Imp.ext.igs.ae || 1 + : null; + const extAe = adUnit.ortb2Imp?.ext?.ae; + if (igsAe !== extAe && igsAe != null && extAe != null) { + logWarn(MODULE, `Ad unit defines conflicting ortb2Imp.ext.ae and ortb2Imp.ext.igs, using the latter`, adUnit); + } + const ae = igsAe ?? extAe ?? moduleConfig.defaultForSlots; + if (ae) { + deepSetValue(adUnit, 'ortb2Imp.ext.ae', ae); + adUnit.ortb2Imp.ext.igs = Object.assign({ + ae: ae, + biddable: 1 + }, adUnit.ortb2Imp.ext.igs); + const requestedSize = getRequestedSize(adUnit); + if (requestedSize) { + deepSetValue(adUnit, 'ortb2Imp.ext.paapi.requestedSize', requestedSize); + } + adUnit.bids.forEach(bidReq => { + if (!getFledgeConfig(bidReq.bidder).enabled) { + deepSetValue(bidReq, 'ortb2Imp.ext.ae', 0); + bidReq.ortb2Imp.ext.igs = {ae: 0, biddable: 0}; + } + }) + } + }) + } + next(adUnits, ...args); +} + export function markForFledge(next, bidderRequests) { if (isFledgeSupported()) { bidderRequests.forEach((bidderReq) => { - config.runWithBidder(bidderReq.bidderCode, () => { - const {enabled, ae} = getFledgeConfig(); - Object.assign(bidderReq, { - fledgeEnabled: enabled, - paapi: { - enabled, - componentSeller: !!moduleConfig.componentSeller?.auctionConfig - } - }); - bidderReq.bids.forEach(bidReq => { - // https://github.com/InteractiveAdvertisingBureau/openrtb/blob/main/extensions/community_extensions/Protected%20Audience%20Support.md - const igsAe = bidReq.ortb2Imp?.ext?.igs != null - ? bidReq.ortb2Imp.ext.igs.ae || 1 - : null - const extAe = bidReq.ortb2Imp?.ext?.ae; - if (igsAe !== extAe && igsAe != null && extAe != null) { - logWarn(MODULE, `Bid request defines conflicting ortb2Imp.ext.ae and ortb2Imp.ext.igs, using the latter`, bidReq); - } - const bidAe = igsAe ?? extAe ?? ae; - if (bidAe) { - deepSetValue(bidReq, 'ortb2Imp.ext.ae', bidAe); - bidReq.ortb2Imp.ext.igs = Object.assign({ - ae: bidAe, - biddable: 1 - }, bidReq.ortb2Imp.ext.igs) - const requestedSize = getRequestedSize(bidReq); - if (requestedSize) { - deepSetValue(bidReq, 'ortb2Imp.ext.paapi.requestedSize', requestedSize); - } - } - }); + const {enabled} = getFledgeConfig(bidderReq.bidderCode); + Object.assign(bidderReq, { + paapi: { + enabled, + componentSeller: !!moduleConfig.componentSeller?.auctionConfig + } }); }); } @@ -378,7 +383,7 @@ export function markForFledge(next, bidderRequests) { } export function setImpExtAe(imp, bidRequest, context) { - if (!context.bidderRequest.fledgeEnabled) { + if (!context.bidderRequest.paapi?.enabled) { delete imp.ext?.ae; delete imp.ext?.igs; } @@ -386,18 +391,6 @@ export function setImpExtAe(imp, bidRequest, context) { registerOrtbProcessor({type: IMP, name: 'impExtAe', fn: setImpExtAe}); -function paapiResponseParser(configs, response, context) { - configs.forEach((config) => { - const impCtx = context.impContext[config.impid]; - if (!impCtx?.imp?.ext?.ae) { - logWarn(MODULE, 'Received auction configuration for an impression that was not in the request or did not ask for it', config, impCtx?.imp); - } else { - impCtx.paapiConfigs = impCtx.paapiConfigs || []; - impCtx.paapiConfigs.push(config); - } - }); -} - export function parseExtIgi(response, ortbResponse, context) { paapiResponseParser( (ortbResponse.ext?.igi || []).flatMap(igi => { @@ -419,6 +412,18 @@ export function parseExtIgi(response, ortbResponse, context) { ) } +function paapiResponseParser(configs, response, context) { + configs.forEach((config) => { + const impCtx = context.impContext[config.impid]; + if (!impCtx?.imp?.ext?.ae) { + logWarn(MODULE, 'Received auction configuration for an impression that was not in the request or did not ask for it', config, impCtx?.imp); + } else { + impCtx.paapiConfigs = impCtx.paapiConfigs || []; + impCtx.paapiConfigs.push(config); + } + }); +} + // to make it easier to share code between the PBS adapter and adapters whose backend is PBS, break up // fledge response processing in two steps: first aggregate all the auction configs by their imp... @@ -449,7 +454,7 @@ export function setResponsePaapiConfigs(response, ortbResponse, context) { registerOrtbProcessor({ type: RESPONSE, - name: 'fledgeAuctionConfigs', + name: 'paapiConfigs', priority: -1, fn: setResponsePaapiConfigs, }); diff --git a/modules/fledgeForGpt.js b/modules/paapiForGpt.js similarity index 68% rename from modules/fledgeForGpt.js rename to modules/paapiForGpt.js index a356785dbe1..61133014e28 100644 --- a/modules/fledgeForGpt.js +++ b/modules/paapiForGpt.js @@ -3,40 +3,39 @@ */ import {getHook, submodule} from '../src/hook.js'; import {deepAccess, logInfo, logWarn, sizeTupleToSizeString} from '../src/utils.js'; -import {getGptSlotForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; import {config} from '../src/config.js'; import {getGlobal} from '../src/prebidGlobal.js'; -// import parent module to keep backwards-compat for NPM consumers after paapi was split from fledgeForGpt -// there's a special case in webpack.conf.js to avoid duplicating build output on non-npm builds -// TODO: remove this in prebid 9 -// eslint-disable-next-line prebid/validate-imports -import './paapi.js'; import {keyCompare} from '../src/utils/reducers.js'; -const MODULE = 'fledgeForGpt'; +import {getGPTSlotsForAdUnits, targeting} from '../src/targeting.js'; -let getPAAPIConfig; +const MODULE = 'paapiForGpt'; -// for backwards compat, we attempt to automatically set GPT configuration as soon as we -// have the auction configs available. Disabling this allows one to call pbjs.setPAAPIConfigForGPT at their -// own pace. -let autoconfig = true; +let getPAAPIConfig; -Object.entries({ - [MODULE]: MODULE, - 'paapi': 'paapi.gpt' -}).forEach(([topic, ns]) => { - const configKey = `${ns}.autoconfig`; - config.getConfig(topic, (cfg) => { - autoconfig = deepAccess(cfg, configKey, true); - }); +config.getConfig('paapi', (cfg) => { + if (deepAccess(cfg, 'paapi.gpt.configWithTargeting', true)) { + logInfo(MODULE, 'enabling PAAPI configuration with setTargetingForGPTAsync') + targeting.setTargetingForGPT.before(setTargetingHook); + } else { + targeting.setTargetingForGPT.getHooks({hook: setTargetingHook}).remove(); + } }); +export function setTargetingHookFactory(setPaapiConfig = getGlobal().setPAAPIConfigForGPT) { + return function(next, adUnit, customSlotMatching) { + const adUnitCodes = Array.isArray(adUnit) ? adUnit : [adUnit] + adUnitCodes + .map(adUnitCode => adUnitCode == null ? undefined : {adUnitCode}) + .forEach(filters => setPaapiConfig(filters, customSlotMatching)) + next(adUnit, customSlotMatching); + } +} + export function slotConfigurator() { const PREVIOUSLY_SET = {}; - return function setComponentAuction(adUnitCode, auctionConfigs, reset = true) { - const gptSlot = getGptSlotForAdUnitCode(adUnitCode); - if (gptSlot && gptSlot.setConfig) { + return function setComponentAuction(adUnitCode, gptSlots, auctionConfigs, reset = true) { + if (gptSlots.length > 0) { let previous = PREVIOUSLY_SET[adUnitCode] ?? {}; let configsBySeller = Object.fromEntries(auctionConfigs.map(cfg => [cfg.seller, cfg])); const sellers = Object.keys(configsBySeller); @@ -52,8 +51,10 @@ export function slotConfigurator() { const componentAuction = Object.entries(configsBySeller) .map(([configKey, auctionConfig]) => ({configKey, auctionConfig})); if (componentAuction.length > 0) { - gptSlot.setConfig({componentAuction}); - logInfo(MODULE, `register component auction configs for: ${adUnitCode}: ${gptSlot.getAdUnitPath()}`, auctionConfigs); + gptSlots.forEach(gptSlot => { + gptSlot.setConfig({componentAuction}); + logInfo(MODULE, `register component auction configs for: ${adUnitCode}: ${gptSlot.getAdUnitPath()}`, auctionConfigs); + }); } } else if (auctionConfigs.length > 0) { logWarn(MODULE, `unable to register component auction config for ${adUnitCode}`, auctionConfigs); @@ -63,17 +64,6 @@ export function slotConfigurator() { const setComponentAuction = slotConfigurator(); -export function onAuctionConfigFactory(setGptConfig = setComponentAuction) { - return function onAuctionConfig(auctionId, configsByAdUnit, markAsUsed) { - if (autoconfig) { - Object.entries(configsByAdUnit).forEach(([adUnitCode, cfg]) => { - setGptConfig(adUnitCode, cfg?.componentAuctions ?? []); - markAsUsed(adUnitCode); - }); - } - } -} - export const getPAAPISizeHook = (() => { /* https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing#faq @@ -138,20 +128,22 @@ export const getPAAPISizeHook = (() => { export function setPAAPIConfigFactory( getConfig = (filters) => getPAAPIConfig(filters, true), - setGptConfig = setComponentAuction) { + setGptConfig = setComponentAuction, + getSlots = getGPTSlotsForAdUnits) { /** * Configure GPT slots with PAAPI auction configs. * `filters` are the same filters accepted by `pbjs.getPAAPIConfig`; */ - return function(filters = {}) { + return function(filters = {}, customSlotMatching) { let some = false; - Object.entries( - getConfig(filters) || {} - ).forEach(([au, config]) => { + const cfg = getConfig(filters) || {}; + const auToSlots = getSlots(Object.keys(cfg), customSlotMatching); + + Object.entries(cfg).forEach(([au, config]) => { if (config != null) { some = true; } - setGptConfig(au, config?.componentAuctions || [], true); + setGptConfig(au, auToSlots[au], config?.componentAuctions || [], true); }) if (!some) { logInfo(`${MODULE}: No component auctions available to set`); @@ -162,10 +154,10 @@ export function setPAAPIConfigFactory( * Configure GPT slots with PAAPI component auctions. Accepts the same filter arguments as `pbjs.getPAAPIConfig`. */ getGlobal().setPAAPIConfigForGPT = setPAAPIConfigFactory(); +const setTargetingHook = setTargetingHookFactory(); submodule('paapi', { name: 'gpt', - onAuctionConfig: onAuctionConfigFactory(), init(params) { getPAAPIConfig = params.getPAAPIConfig; getHook('getPAAPISize').before(getPAAPISizeHook); diff --git a/modules/fledgeForGpt.md b/modules/paapiForGpt.md similarity index 55% rename from modules/fledgeForGpt.md rename to modules/paapiForGpt.md index 28f44da6459..31cde2e268d 100644 --- a/modules/fledgeForGpt.md +++ b/modules/paapiForGpt.md @@ -1,22 +1,22 @@ # Overview -This module allows Prebid.js to support FLEDGE by integrating it with GPT's [experimental FLEDGE +This module allows Prebid.js to support PAAPI by integrating it with GPT's [experimental PAAPI support](https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing). -To learn more about FLEDGE in general, go [here](https://github.com/WICG/turtledove/blob/main/FLEDGE.md). +To learn more about PAAPI in general, go [here](https://github.com/WICG/turtledove/blob/main/PAAPI.md). -This document covers the steps necessary for publishers to enable FLEDGE on their inventory. It also describes -the changes Bid Adapters need to implement in order to support FLEDGE. +This document covers the steps necessary for publishers to enable PAAPI on their inventory. It also describes +the changes Bid Adapters need to implement in order to support PAAPI. ## Publisher Integration -Publishers wishing to enable FLEDGE support must do two things. First, they must compile Prebid.js with support for this module. -This is accomplished by adding the `fledgeForGpt` module to the list of modules they are already using: +Publishers wishing to enable PAAPI support must do two things. First, they must compile Prebid.js with support for this module. +This is accomplished by adding the `paapiForGpt` module to the list of modules they are already using: ``` -gulp build --modules=fledgeForGpt,... +gulp build --modules=paapiForGpt,... ``` -Second, they must enable FLEDGE in their Prebid.js configuration. -This is done through module level configuration, but to provide a high degree of flexiblity for testing, FLEDGE settings also exist at the bidder level and slot level. +Second, they must enable PAAPI in their Prebid.js configuration. +This is done through module level configuration, but to provide a high degree of flexiblity for testing, PAAPI settings also exist the slot level. ### Module Configuration This module exposes the following settings: @@ -27,14 +27,13 @@ This module exposes the following settings: |bidders | Array[String] |Optional list of bidders |Defaults to all bidders | |defaultForSlots | Number |Default value for `imp.ext.ae` in requests for specified bidders |Should be 1 | -As noted above, FLEDGE support is disabled by default. To enable it, set the `enabled` value to `true` for this module and configure `defaultForSlots` to be `1` (meaning _Client-side auction_). -using the `setConfig` method of Prebid.js. Optionally, a list of -bidders to apply these settings to may be provided: +As noted above, PAAPI support is disabled by default. To enable it, set the `enabled` value to `true` for this module and configure `defaultForSlots` to be `1` (meaning _Client-side auction_). +using the `setConfig` method of Prebid.js. Optionally, a list of bidders to apply these settings to may be provided: ```js pbjs.que.push(function() { pbjs.setConfig({ - fledgeForGpt: { + paapi: { enabled: true, bidders: ['openx', 'rtbhouse'], defaultForSlots: 1 @@ -43,35 +42,14 @@ pbjs.que.push(function() { }); ``` -### Bidder Configuration -This module adds the following setting for bidders: - -|Name |Type |Description |Notes | -| :------------ | :------------ | :------------ |:------------ | -| fledgeEnabled | Boolean | Enable/disable a bidder to participate in FLEDGE | Defaults to `false` | -|defaultForSlots | Number |Default value for `imp.ext.ae` in requests for specified bidders |Should be 1| - -Individual bidders may be further included or excluded here using the `setBidderConfig` method -of Prebid.js: - -```js -pbjs.setBidderConfig({ - bidders: ["openx"], - config: { - fledgeEnabled: true, - defaultForSlots: 1 - } -}); -``` - ### AdUnit Configuration -All adunits can be opted-in to FLEDGE in the global config via the `defaultForSlots` parameter. +All adunits can be opted-in to PAAPI in the global config via the `defaultForSlots` parameter. If needed, adunits can be configured individually by setting an attribute of the `ortb2Imp` object for that adunit. This attribute will take precedence over `defaultForSlots` setting. |Name |Type |Description |Notes | | :------------ | :------------ | :------------ |:------------ | -| ortb2Imp.ext.ae | Integer | Auction Environment: 1 indicates FLEDGE eligible, 0 indicates it is not | Absence indicates this is not FLEDGE eligible | +| ortb2Imp.ext.ae | Integer | Auction Environment: 1 indicates PAAPI eligible, 0 indicates it is not | Absence indicates this is not PAAPI eligible | The `ae` field stands for Auction Environment and was chosen to be consistent with the field that GAM passes to bidders in their Open Bidding and Exchange Bidding APIs. More details on that can be found @@ -91,31 +69,31 @@ pbjs.addAdUnits({ ``` ## Bid Adapter Integration -Chrome has enabled a two-tier auction in FLEDGE. This allows multiple sellers (frequently SSPs) to act on behalf of the publisher with +Chrome has enabled a two-tier auction in PAAPI. This allows multiple sellers (frequently SSPs) to act on behalf of the publisher with a single entity serving as the final decision maker. In their [current approach](https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing), GPT has opted to run the final auction layer while allowing other SSPs/sellers to participate as -[Component Auctions](https://github.com/WICG/turtledove/blob/main/FLEDGE.md#21-initiating-an-on-device-auction) which feed their -bids to the final layer. To learn more about Component Auctions, go [here](https://github.com/WICG/turtledove/blob/main/FLEDGE.md#24-scoring-bids-in-component-auctions). +[Component Auctions](https://github.com/WICG/turtledove/blob/main/PAAPI.md#21-initiating-an-on-device-auction) which feed their +bids to the final layer. To learn more about Component Auctions, go [here](https://github.com/WICG/turtledove/blob/main/PAAPI.md#24-scoring-bids-in-component-auctions). -The FLEDGE auction, including Component Auctions, are configured via an `AuctionConfig` object that defines the parameters of the auction for a given -seller. This module enables FLEDGE support by allowing bid adaptors to return `AuctionConfig` objects in addition to bids. If a bid adaptor returns an +The PAAPI auction, including Component Auctions, are configured via an `AuctionConfig` object that defines the parameters of the auction for a given +seller. This module enables PAAPI support by allowing bid adaptors to return `AuctionConfig` objects in addition to bids. If a bid adaptor returns an `AuctionConfig` object, Prebid.js will register it with the appropriate GPT ad slot so the bidder can participate as a Component Auction in the overall -FLEDGE auction for that slot. More details on the GPT API can be found [here](https://developers.google.com/publisher-tag/reference#googletag.config.componentauctionconfig). +PAAPI auction for that slot. More details on the GPT API can be found [here](https://developers.google.com/publisher-tag/reference#googletag.config.componentauctionconfig). -Modifying a bid adapter to support FLEDGE is a straightforward process and consists of the following steps: -1. Detecting when a bid request is FLEDGE eligible +Modifying a bid adapter to support PAAPI is a straightforward process and consists of the following steps: +1. Detecting when a bid request is PAAPI eligible 2. Responding with AuctionConfig -FLEDGE eligibility is made available to bid adapters through the `bidderRequest.fledgeEnabled` field. +PAAPI eligibility is made available to bid adapters through the `bidderRequest.paapi.enabled` field. The [`bidderRequest`](https://docs.prebid.org/dev-docs/bidder-adaptor.html#bidderrequest-parameters) object is passed to the [`buildRequests`](https://docs.prebid.org/dev-docs/bidder-adaptor.html#building-the-request) method of an adapter. Bid adapters -who wish to participate should read this flag and pass it to their server. FLEDGE eligibility depends on a number of parameters: +who wish to participate should read this flag and pass it to their server. PAAPI eligibility depends on a number of parameters: 1. Chrome enablement 2. Publisher participatipon in the [Origin Trial](https://developer.chrome.com/docs/privacy-sandbox/unified-origin-trial/#configure) 3. Publisher Prebid.js configuration (detailed above) -When a bid request is FLEDGE enabled, a bid adapter can return a tuple consisting of bids and AuctionConfig objects rather than just a list of bids: +When a bid request is PAAPI enabled, a bid adapter can return a tuple consisting of bids and AuctionConfig objects rather than just a list of bids: ```js function interpretResponse(resp, req) { @@ -138,8 +116,8 @@ An AuctionConfig must be associated with an adunit and auction, and this is acco `validBidRequests` array passed to the `buildRequests` function - see [here](https://docs.prebid.org/dev-docs/bidder-adaptor.html#ad-unit-params-in-the-validbidrequests-array) for more details. This means that the AuctionConfig objects returned from `interpretResponse` must contain a `bidId` field whose value corresponds to the request it should be associated with. This may raise the question: why isn't the AuctionConfig object returned as part of the bid? The -answer is that it's possible to participate in the FLEDGE auction without returning a contextual bid. +answer is that it's possible to participate in the PAAPI auction without returning a contextual bid. An example of this can be seen in the OpenX OpenRTB bid adapter [here](https://github.com/prebid/Prebid.js/blob/master/modules/openxOrtbBidAdapter.js#L327). -Other than the addition of the `bidId` field, the AuctionConfig object should adhere to the requirements set forth in FLEDGE. The details of creating an AuctionConfig object are beyond the scope of this document. +Other than the addition of the `bidId` field, the AuctionConfig object should adhere to the requirements set forth in PAAPI. The details of creating an AuctionConfig object are beyond the scope of this document. diff --git a/modules/pairIdSystem.js b/modules/pairIdSystem.js index dbff4c6a402..778857bae1c 100644 --- a/modules/pairIdSystem.js +++ b/modules/pairIdSystem.js @@ -50,9 +50,11 @@ export const pairIdSubmodule = { return value && Array.isArray(value) ? {'pairId': value} : undefined }, /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @returns {id: string | undefined } + * Performs action to obtain ID and return a value in the callback's response argument. + * @function getId + * @param {Object} config - The configuration object. + * @param {Object} config.params - The parameters from the configuration. + * @returns {{id: string[] | undefined}} The obtained IDs or undefined if no IDs are found. */ getId(config) { const pairIdsString = pairIdFromLocalStorage(PAIR_ID_KEY) || pairIdFromCookie(PAIR_ID_KEY) @@ -67,13 +69,28 @@ export const pairIdSubmodule = { const configParams = (config && config.params) || {}; if (configParams && configParams.liveramp) { - let LRStorageLocation = configParams.liveramp.storageKey || DEFAULT_LIVERAMP_PAIR_ID_KEY - const liverampValue = pairIdFromLocalStorage(LRStorageLocation) || pairIdFromCookie(LRStorageLocation) - try { - const obj = JSON.parse(atob(liverampValue)); - ids = ids.concat(obj.envelope); - } catch (error) { - logInfo(error) + let LRStorageLocation = configParams.liveramp.storageKey || DEFAULT_LIVERAMP_PAIR_ID_KEY; + const liverampValue = pairIdFromLocalStorage(LRStorageLocation) || pairIdFromCookie(LRStorageLocation); + + if (liverampValue) { + try { + const parsedValue = atob(liverampValue); + if (parsedValue) { + const obj = JSON.parse(parsedValue); + + if (obj && typeof obj === 'object' && obj.envelope) { + ids = ids.concat(obj.envelope); + } else { + logInfo('Pairid: Parsed object is not valid or does not contain envelope'); + } + } else { + logInfo('Pairid: Decoded value is empty'); + } + } catch (error) { + logInfo('Pairid: Error parsing JSON: ', error); + } + } else { + logInfo('Pairid: liverampValue for pairId from storage is empty or null'); } } diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js deleted file mode 100644 index 5651bdf0434..00000000000 --- a/modules/parrableIdSystem.js +++ /dev/null @@ -1,416 +0,0 @@ -/** - * This module adds Parrable to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/parrableIdSystem - * @requires module:modules/userId - */ - -// ci trigger: 1 - -import { - contains, - deepClone, - inIframe, - isEmpty, - isPlainObject, - logError, - logWarn, - pick, - timestamp -} from '../src/utils.js'; -import {find} from '../src/polyfill.js'; -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {uspDataHandler} from '../src/adapterManager.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; - -/** - * @typedef {import('../modules/userId/index.js').Submodule} Submodule - * @typedef {import('../modules/userId/index.js').SubmoduleConfig} SubmoduleConfig - * @typedef {import('../modules/userId/index.js').ConsentData} ConsentData - */ - -const PARRABLE_URL = 'https://h.parrable.com/prebid'; -const PARRABLE_COOKIE_NAME = '_parrable_id'; -const PARRABLE_GVLID = 928; -const LEGACY_ID_COOKIE_NAME = '_parrable_eid'; -const LEGACY_OPTOUT_COOKIE_NAME = '_parrable_optout'; -const ONE_YEAR_MS = 364 * 24 * 60 * 60 * 1000; -const EXPIRE_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:00 GMT'; -const MODULE_NAME = 'parrableId'; - -const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); - -function getExpirationDate() { - const oneYearFromNow = new Date(timestamp() + ONE_YEAR_MS); - return oneYearFromNow.toGMTString(); -} - -function deserializeParrableId(parrableIdStr) { - const parrableId = {}; - const values = parrableIdStr.split(','); - - values.forEach(function(value) { - const pair = value.split(':'); - if (pair[0] === 'ccpaOptout' || pair[0] === 'ibaOptout') { // unpack a value of 0 or 1 as boolean - parrableId[pair[0]] = Boolean(+pair[1]); - } else if (!isNaN(pair[1])) { // convert to number if is a number - parrableId[pair[0]] = +pair[1] - } else { - parrableId[pair[0]] = pair[1] - } - }); - - return parrableId; -} - -function serializeParrableId(parrableIdAndParams) { - let components = []; - - if (parrableIdAndParams.eid) { - components.push('eid:' + parrableIdAndParams.eid); - } - if (parrableIdAndParams.ibaOptout) { - components.push('ibaOptout:1'); - } - if (parrableIdAndParams.ccpaOptout) { - components.push('ccpaOptout:1'); - } - if (parrableIdAndParams.tpcSupport !== undefined) { - const tpcSupportComponent = parrableIdAndParams.tpcSupport === true ? 'tpc:1' : 'tpc:0'; - const tpcUntil = `tpcUntil:${parrableIdAndParams.tpcUntil}`; - components.push(tpcSupportComponent); - components.push(tpcUntil); - } - if (parrableIdAndParams.filteredUntil) { - components.push(`filteredUntil:${parrableIdAndParams.filteredUntil}`); - components.push(`filterHits:${parrableIdAndParams.filterHits}`); - } - - return components.join(','); -} - -function isValidConfig(configParams) { - if (!configParams) { - logError('User ID - parrableId submodule requires configParams'); - return false; - } - if (!configParams.partners && !configParams.partner) { - logError('User ID - parrableId submodule requires partner list'); - return false; - } - if (configParams.storage) { - logWarn('User ID - parrableId submodule does not require a storage config'); - } - return true; -} - -function encodeBase64UrlSafe(base64) { - const ENC = { - '+': '-', - '/': '_', - '=': '.' - }; - return base64.replace(/[+/=]/g, (m) => ENC[m]); -} - -function readCookie() { - const parrableIdStr = storage.getCookie(PARRABLE_COOKIE_NAME); - if (parrableIdStr) { - const parsedCookie = deserializeParrableId(decodeURIComponent(parrableIdStr)); - const { tpc, tpcUntil, filteredUntil, filterHits, ...parrableId } = parsedCookie; - let { eid, ibaOptout, ccpaOptout, ...params } = parsedCookie; - - if ((Date.now() / 1000) >= tpcUntil) { - params.tpc = undefined; - } - - if ((Date.now() / 1000) < filteredUntil) { - params.shouldFilter = true; - params.filteredUntil = filteredUntil; - } else { - params.shouldFilter = false; - params.filterHits = filterHits; - } - return { parrableId, params }; - } - return null; -} - -function writeCookie(parrableIdAndParams) { - if (parrableIdAndParams) { - const parrableIdStr = encodeURIComponent(serializeParrableId(parrableIdAndParams)); - storage.setCookie(PARRABLE_COOKIE_NAME, parrableIdStr, getExpirationDate(), 'lax'); - } -} - -function readLegacyCookies() { - const eid = storage.getCookie(LEGACY_ID_COOKIE_NAME); - const ibaOptout = (storage.getCookie(LEGACY_OPTOUT_COOKIE_NAME) === 'true'); - if (eid || ibaOptout) { - const parrableId = {}; - if (eid) { - parrableId.eid = eid; - } - if (ibaOptout) { - parrableId.ibaOptout = ibaOptout; - } - return parrableId; - } - return null; -} - -function migrateLegacyCookies(parrableId) { - if (parrableId) { - writeCookie(parrableId); - if (parrableId.eid) { - storage.setCookie(LEGACY_ID_COOKIE_NAME, '', EXPIRE_COOKIE_DATE); - } - if (parrableId.ibaOptout) { - storage.setCookie(LEGACY_OPTOUT_COOKIE_NAME, '', EXPIRE_COOKIE_DATE); - } - } -} - -function shouldFilterImpression(configParams, parrableId) { - const config = configParams.timezoneFilter; - - if (!config) { - return false; - } - - if (parrableId) { - return false; - } - - const offset = (new Date()).getTimezoneOffset() / 60; - const zone = Intl.DateTimeFormat().resolvedOptions().timeZone; - - function isZoneListed(list, zone) { - // IE does not provide a timeZone in IANA format so zone will be empty - const zoneLowercase = zone && zone.toLowerCase(); - return !!(list && zone && find(list, zn => zn.toLowerCase() === zoneLowercase)); - } - - function isAllowed() { - if (isEmpty(config.allowedZones) && - isEmpty(config.allowedOffsets)) { - return true; - } - if (isZoneListed(config.allowedZones, zone)) { - return true; - } - if (contains(config.allowedOffsets, offset)) { - return true; - } - return false; - } - - function isBlocked() { - if (isEmpty(config.blockedZones) && - isEmpty(config.blockedOffsets)) { - return false; - } - if (isZoneListed(config.blockedZones, zone)) { - return true; - } - if (contains(config.blockedOffsets, offset)) { - return true; - } - return false; - } - - return isBlocked() || !isAllowed(); -} - -function epochFromTtl(ttl) { - return Math.floor((Date.now() / 1000) + ttl); -} - -function incrementFilterHits(parrableId, params) { - params.filterHits += 1; - writeCookie({ ...parrableId, ...params }) -} - -function fetchId(configParams, gdprConsentData) { - if (!isValidConfig(configParams)) return; - - let { parrableId, params } = readCookie() || {}; - if (!parrableId) { - parrableId = readLegacyCookies(); - migrateLegacyCookies(parrableId); - } - - if (shouldFilterImpression(configParams, parrableId)) { - return null; - } - - const eid = parrableId ? parrableId.eid : null; - const refererInfo = getRefererInfo(); - const tpcSupport = params ? params.tpc : null; - const shouldFilter = params ? params.shouldFilter : null; - const uspString = uspDataHandler.getConsentData(); - const gdprApplies = (gdprConsentData && typeof gdprConsentData.gdprApplies === 'boolean' && gdprConsentData.gdprApplies); - const gdprConsentString = (gdprConsentData && gdprApplies && gdprConsentData.consentString) || ''; - const partners = configParams.partners || configParams.partner; - const trackers = typeof partners === 'string' - ? partners.split(',') - : partners; - - const data = { - eid, - trackers, - url: refererInfo.page, - prebidVersion: '$prebid.version$', - isIframe: inIframe(), - tpcSupport - }; - - if (shouldFilter === false) { - data.filterHits = params.filterHits; - } - - const searchParams = { - data: encodeBase64UrlSafe(btoa(JSON.stringify(data))), - gdpr: gdprApplies ? 1 : 0, - _rand: Math.random() - }; - - if (uspString) { - searchParams.us_privacy = uspString; - } - - if (gdprApplies) { - searchParams.gdpr_consent = gdprConsentString; - } - - const options = { - method: 'GET', - withCredentials: true - }; - - const callback = function (cb) { - const callbacks = { - success: response => { - let newParrableId = parrableId ? deepClone(parrableId) : {}; - let newParams = {}; - if (response) { - try { - let responseObj = JSON.parse(response); - if (responseObj) { - if (responseObj.ccpaOptout !== true) { - newParrableId.eid = responseObj.eid; - } else { - newParrableId.eid = null; - newParrableId.ccpaOptout = true; - } - if (responseObj.ibaOptout === true) { - newParrableId.ibaOptout = true; - } - if (responseObj.tpcSupport !== undefined) { - newParams.tpcSupport = responseObj.tpcSupport; - newParams.tpcUntil = epochFromTtl(responseObj.tpcSupportTtl); - } - if (responseObj.filterTtl) { - newParams.filteredUntil = epochFromTtl(responseObj.filterTtl); - newParams.filterHits = 0; - } - } - } catch (error) { - logError(error); - cb(); - } - writeCookie({ ...newParrableId, ...newParams }); - cb(newParrableId); - } else { - logError('parrableId: ID fetch returned an empty result'); - cb(); - } - }, - error: error => { - logError(`parrableId: ID fetch encountered an error`, error); - cb(); - } - }; - - if (shouldFilter) { - incrementFilterHits(parrableId, params); - } else { - ajax(PARRABLE_URL, callbacks, searchParams, options); - } - }; - - return { - callback, - id: parrableId - }; -} - -/** @type {Submodule} */ -export const parrableIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - /** - * Global Vendor List ID - * @type {number} - */ - gvlid: PARRABLE_GVLID, - - /** - * decode the stored id value for passing to bid requests - * @function - * @param {ParrableId} parrableId - * @return {(Object|undefined} - */ - decode(parrableId) { - if (parrableId && isPlainObject(parrableId)) { - return { parrableId }; - } - return undefined; - }, - - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData} [consentData] - * @returns {function(callback:function), id:ParrableId} - */ - getId(config, gdprConsentData, currentStoredId) { - const configParams = (config && config.params) || {}; - return fetchId(configParams, gdprConsentData); - }, - eids: { - 'parrableId': { - source: 'parrable.com', - atype: 1, - getValue: function(parrableId) { - if (parrableId.eid) { - return parrableId.eid; - } - if (parrableId.ccpaOptout) { - // If the EID was suppressed due to a non consenting ccpa optout then - // we still wish to provide this as a reason to the adapters - return ''; - } - return null; - }, - getUidExt: function(parrableId) { - const extendedData = pick(parrableId, [ - 'ibaOptout', - 'ccpaOptout' - ]); - if (Object.keys(extendedData).length) { - return extendedData; - } - } - }, - }, -}; - -submodule('userId', parrableIdSubmodule); diff --git a/modules/permutiveRtdProvider.js b/modules/permutiveRtdProvider.js index c42a15d9197..bb2dff6189e 100644 --- a/modules/permutiveRtdProvider.js +++ b/modules/permutiveRtdProvider.js @@ -95,7 +95,8 @@ export function getModuleConfig(customModuleConfig) { /** * Sets ortb2 config for ac bidders * @param {Object} bidderOrtb2 - The ortb2 object for the all bidders - * @param {Object} customModuleConfig - Publisher config for module + * @param {Object} moduleConfig - Publisher config for module + * @param {Object} segmentData - Segment data grouped by bidder or type */ export function setBidderRtb (bidderOrtb2, moduleConfig, segmentData) { const acBidders = deepAccess(moduleConfig, 'params.acBidders') @@ -129,13 +130,13 @@ export function setBidderRtb (bidderOrtb2, moduleConfig, segmentData) { /** * Updates `user.data` object in existing bidder config with Permutive segments - * @param string bidder - The bidder + * @param {string} bidder - The bidder identifier * @param {Object} currConfig - Current bidder config - * @param {Object[]} transformationConfigs - array of objects with `id` and `config` properties, used to determine - * the transformations on user data to include the ORTB2 object * @param {string[]} segmentIDs - Permutive segment IDs * @param {string[]} sspSegmentIDs - Permutive SSP segment IDs * @param {Object} topics - Privacy Sandbox Topics, keyed by IAB taxonomy version (600, 601, etc.) + * @param {Object[]} transformationConfigs - array of objects with `id` and `config` properties, used to determine + * the transformations on user data to include the ORTB2 object * @param {Object} segmentData - The segments available for targeting * @return {Object} Merged ortb2 object */ @@ -270,7 +271,7 @@ function setSegments (reqBidsConfigObj, moduleConfig, segmentData) { */ function makeSafe (fn) { try { - fn() + return fn() } catch (e) { logError(e) } @@ -310,23 +311,71 @@ export function isPermutiveOnPage () { * @param {number} maxSegs - Maximum number of segments to be included * @return {Object} */ -export function getSegments (maxSegs) { - const legacySegs = readSegments('_psegs', []).map(Number).filter(seg => seg >= 1000000).map(String) - const _ppam = readSegments('_ppam', []) - const _pcrprs = readSegments('_pcrprs', []) - +export function getSegments(maxSegs) { const segments = { - ac: [..._pcrprs, ..._ppam, ...legacySegs], - ix: readSegments('_pindexs', []), - rubicon: readSegments('_prubicons', []), - appnexus: readSegments('_papns', []), - gam: readSegments('_pdfps', []), - ssp: readSegments('_pssps', { - cohorts: [], - ssps: [] + ac: + makeSafe(() => { + const legacySegs = + makeSafe(() => + readSegments('_psegs', []) + .map(Number) + .filter((seg) => seg >= 1000000) + .map(String), + ) || []; + const _ppam = makeSafe(() => readSegments('_ppam', []).map(String)) || []; + const _pcrprs = makeSafe(() => readSegments('_pcrprs', []).map(String)) || []; + + return [..._pcrprs, ..._ppam, ...legacySegs]; + }) || [], + + ix: + makeSafe(() => { + const _pindexs = readSegments('_pindexs', []); + return _pindexs.map(String); + }) || [], + + rubicon: + makeSafe(() => { + const _prubicons = readSegments('_prubicons', []); + return _prubicons.map(String); + }) || [], + + appnexus: + makeSafe(() => { + const _papns = readSegments('_papns', []); + return _papns.map(String); + }) || [], + + gam: + makeSafe(() => { + const _pdfps = readSegments('_pdfps', []); + return _pdfps.map(String); + }) || [], + + ssp: makeSafe(() => { + const _pssps = readSegments('_pssps', { + cohorts: [], + ssps: [], + }); + + return { + cohorts: makeSafe(() => _pssps.cohorts.map(String)) || [], + ssps: makeSafe(() => _pssps.ssps.map(String)) || [], + }; }), - topics: readSegments('_ppsts', {}), - } + + topics: + makeSafe(() => { + const _ppsts = readSegments('_ppsts', {}); + + const topics = {}; + for (const [k, value] of Object.entries(_ppsts)) { + topics[k] = makeSafe(() => value.map(String)) || []; + } + + return topics; + }) || {}, + }; for (const bidder in segments) { if (bidder === 'ssp') { @@ -342,7 +391,8 @@ export function getSegments (maxSegs) { } } - return segments + logger.logInfo(`Read segments`, segments) + return segments; } /** @@ -393,7 +443,7 @@ function iabSegmentId(permutiveSegmentId, iabIds) { * Pull the latest configuration and cohort information and update accordingly. * * @param reqBidsConfigObj - Bidder provided config for request - * @param customModuleConfig - Publisher provide config + * @param moduleConfig - Publisher provided config */ export function readAndSetCohorts(reqBidsConfigObj, moduleConfig) { const segmentData = getSegments(deepAccess(moduleConfig, 'params.maxSegs')) diff --git a/modules/pgamsspBidAdapter.js b/modules/pgamsspBidAdapter.js index fdc6bcf302f..859bfc9de7e 100644 --- a/modules/pgamsspBidAdapter.js +++ b/modules/pgamsspBidAdapter.js @@ -1,253 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'pgamssp'; const AD_URL = 'https://us-east.pgammedia.com/pbjs'; const SYNC_URL = 'https://cs.pgammedia.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor, - eids: [] - }; - - if (bid.userId) { - getUserId(placement.eids, bid.userId.uid2?.id, 'uidapi.com'); - getUserId(placement.eids, bid.userId.id5id?.uid, 'id5-sync.com'); - } - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} -function getUserId(eids, id, source, uidExt) { - if (id) { - var uid = { id }; - if (uidExt) { - uid.ext = uidExt; - } - eids.push({ - source, - uids: [ uid ] - }); - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - tmax: bidderRequest.timeout - }; - - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - - if (bidderRequest.gdprConsent) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { - syncUrl += '&gpp=' + gppConsent.gppString; - syncUrl += '&gpp_sid=' + gppConsent.applicableSections.join(','); - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/pirIdSystem.js b/modules/pirIdSystem.js deleted file mode 100644 index 233176028d3..00000000000 --- a/modules/pirIdSystem.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * This module adds pirId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/pirId - * @requires module:modules/userId - */ - -import { MODULE_TYPE_UID } from '../src/activities/modules.js'; -import { getStorageManager } from '../src/storageManager.js'; -import { submodule } from '../src/hook.js'; -import {domainOverrideToRootDomain} from '../libraries/domainOverrideToRootDomain/index.js'; - -/** - * @typedef {import('../modules/userId/index.js').Submodule} Submodule - * @typedef {import('../modules/userId/index.js').IdResponse} IdResponse - */ - -const MODULE_NAME = 'pirId'; -const ID_TOKEN = 'WPxid'; -export const storage = getStorageManager({ moduleName: MODULE_NAME, moduleType: MODULE_TYPE_UID }); - -/** - * Reads the ID token from local storage or cookies. - * @returns {string|undefined} The ID token, or undefined if not found. - */ -export const readId = () => storage.getDataFromLocalStorage(ID_TOKEN) || storage.getCookie(ID_TOKEN); - -/** @type {Submodule} */ -export const pirIdSubmodule = { - name: MODULE_NAME, - gvlid: 676, - - /** - * decode the stored id value for passing to bid requests - * @function decode - * @param {string} value - * @returns {(Object|undefined)} - */ - decode(value) { - return typeof value === 'string' ? { 'pirId': value } : undefined; - }, - - /** - * performs action to obtain id and return a value - * @function - * @returns {(IdResponse|undefined)} - */ - getId() { - const pirIdToken = readId(); - - return pirIdToken ? { id: pirIdToken } : undefined; - }, - domainOverride: domainOverrideToRootDomain(storage, MODULE_NAME), - eids: { - 'pirId': { - source: 'pir.wp.pl', - atype: 1 - }, - }, -}; - -submodule('userId', pirIdSubmodule); diff --git a/modules/pirIdSystem.md b/modules/pirIdSystem.md deleted file mode 100644 index 913804f85c4..00000000000 --- a/modules/pirIdSystem.md +++ /dev/null @@ -1,27 +0,0 @@ -# Overview - -Module Name: pirIDSystem -Module Type: UserID Module -Maintainer: pawel.grudzien@grupawp.pl - -# Description - -User identification system for WPM - -### Prebid Params example - -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'pirID', - storage: { - type: 'cookie', - name: 'pirIdToken', - expires: 7, - refreshInSeconds: 360 - }, - }] - } -}); -``` diff --git a/modules/pixfutureBidAdapter.js b/modules/pixfutureBidAdapter.js index 1c3f9b8da1a..c7ed1ec989d 100644 --- a/modules/pixfutureBidAdapter.js +++ b/modules/pixfutureBidAdapter.js @@ -5,7 +5,6 @@ import {config} from '../src/config.js'; import {find, includes} from '../src/polyfill.js'; import {deepAccess, isArray, isFn, isNumber, isPlainObject} from '../src/utils.js'; import {auctionManager} from '../src/auctionManager.js'; -import {getGlobal} from '../src/prebidGlobal.js'; import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js'; @@ -126,7 +125,7 @@ export const spec = { method: 'POST', options: {withCredentials: true}, data: { - v: getGlobal().version, + v: 'v' + '$prebid.version$', pageUrl: referer, bidId: bidRequest.bidId, // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 @@ -277,7 +276,7 @@ function bidToTag(bid) { } tag.keywords = getANKeywordParam(bid.ortb2, bid.params.keywords) - let gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); + let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); if (gpid) { tag.gpid = gpid; } diff --git a/modules/playdigoBidAdapter.js b/modules/playdigoBidAdapter.js index 6c4ea6492d9..e41e86c4c47 100644 --- a/modules/playdigoBidAdapter.js +++ b/modules/playdigoBidAdapter.js @@ -1,199 +1,19 @@ -import { logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'playdigo'; const AD_URL = 'https://server.playdigo.com/pbjs'; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!bid.getFloor || typeof bid.getFloor !== 'function') { - return 0; - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} +const SYNC_URL = 'https://cs.playdigo.com'; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - tmax: config.getConfig('bidderTimeout') - }; - - if (bidderRequest.gdprConsent) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/prebidServerBidAdapter/config.js b/modules/prebidServerBidAdapter/config.js index 87274504f64..a1bad2d69ba 100644 --- a/modules/prebidServerBidAdapter/config.js +++ b/modules/prebidServerBidAdapter/config.js @@ -11,7 +11,7 @@ export const S2S_VENDORS = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync', noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/cookie_sync' }, - timeout: 1000 + maxTimeout: 1000 }, 'rubicon': { adapter: 'prebidServer', @@ -24,7 +24,7 @@ export const S2S_VENDORS = { p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', }, - timeout: 500 + maxTimeout: 500 }, 'openx': { adapter: 'prebidServer', @@ -37,7 +37,7 @@ export const S2S_VENDORS = { p1Consent: 'https://prebid.openx.net/cookie_sync', noP1Consent: 'https://prebid.openx.net/cookie_sync' }, - timeout: 1000 + maxTimeout: 1000 }, 'openwrap': { adapter: 'prebidServer', @@ -46,6 +46,6 @@ export const S2S_VENDORS = { p1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs', noP1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs' }, - timeout: 500 + maxTimeout: 500 } } diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 8c5b89b5794..edae21e97a7 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -25,7 +25,7 @@ import {includes} from '../../src/polyfill.js'; import {S2S_VENDORS} from './config.js'; import {ajax} from '../../src/ajax.js'; import {hook} from '../../src/hook.js'; -import {hasPurpose1Consent} from '../../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../../src/utils/gdpr.js'; import {buildPBSRequest, interpretPBSResponse} from './ortbConverter.js'; import {useMetrics} from '../../src/utils/perfMetrics.js'; import {isActivityAllowed} from '../../src/activities/rules.js'; @@ -82,6 +82,7 @@ let eidPermissions; * @property {string} [syncEndpoint] endpoint URL for syncing cookies * @property {Object} [extPrebid] properties will be merged into request.ext.prebid * @property {Object} [ortbNative] base value for imp.native.request + * @property {Number} [maxTimeout] */ /** @@ -89,7 +90,6 @@ let eidPermissions; */ export const s2sDefaultConfig = { bidders: Object.freeze([]), - timeout: 1000, syncTimeout: 1000, maxBids: 1, adapter: 'prebidServer', @@ -100,7 +100,8 @@ export const s2sDefaultConfig = { eventtrackers: [ {event: 1, methods: [1, 2]} ], - } + }, + maxTimeout: 1500 }; config.setDefaults({ @@ -178,7 +179,7 @@ function setS2sConfig(options) { const activeBidders = []; const optionsValid = normalizedOptions.every((option, i, array) => { - formatUrlParams(options); + formatUrlParams(option); const updateSuccess = updateConfigDefaultVendor(option); if (updateSuccess !== false) { const valid = validateConfigRequiredProps(option); @@ -487,7 +488,12 @@ export function PrebidServer() { doClientSideSyncs(requestedBidders, gdprConsent, uspConsent, gppConsent); }, onError(msg, error) { - logError(`Prebid server call failed: '${msg}'`, error); + const {p1Consent = '', noP1Consent = ''} = s2sBidRequest?.s2sConfig?.endpoint || {}; + if (p1Consent === noP1Consent) { + logError(`Prebid server call failed: '${msg}'. Endpoint: "${p1Consent}"}`, error); + } else { + logError(`Prebid server call failed: '${msg}'. Endpoints: p1Consent "${p1Consent}", noP1Consent "${noP1Consent}"}`, error); + } bidRequests.forEach(bidderRequest => events.emit(EVENTS.BIDDER_ERROR, { error, bidderRequest })); done(error.timedOut); }, @@ -509,7 +515,9 @@ export function PrebidServer() { } }, onFledge: (params) => { - addPaapiConfig({auctionId: bidRequests[0].auctionId, ...params}, {config: params.config}); + config.runWithBidder(params.bidder, () => { + addPaapiConfig({auctionId: bidRequests[0].auctionId, ...params}, {config: params.config}); + }) } }) } @@ -549,6 +557,7 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques const requestJson = request && JSON.stringify(request); logInfo('BidRequest: ' + requestJson); const endpointUrl = getMatchingConsentUrl(s2sBidRequest.s2sConfig.endpoint, gdprConsent); + const customHeaders = deepAccess(s2sBidRequest, 's2sConfig.customHeaders', {}); if (request && requestJson && endpointUrl) { const networkDone = s2sBidRequest.metrics.startTiming('net'); ajax( @@ -559,10 +568,10 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques let result; try { result = JSON.parse(response); - const {bids, fledgeAuctionConfigs} = s2sBidRequest.metrics.measureTime('interpretResponse', () => interpretPBSResponse(result, request)); + const {bids, paapi} = s2sBidRequest.metrics.measureTime('interpretResponse', () => interpretPBSResponse(result, request)); bids.forEach(onBid); - if (fledgeAuctionConfigs) { - fledgeAuctionConfigs.forEach(onFledge); + if (paapi) { + paapi.forEach(onFledge); } } catch (error) { logError(error); @@ -583,7 +592,8 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques { contentType: 'text/plain', withCredentials: true, - browsingTopics: isActivityAllowed(ACTIVITY_TRANSMIT_UFPD, s2sActivityParams(s2sBidRequest.s2sConfig)) + browsingTopics: isActivityAllowed(ACTIVITY_TRANSMIT_UFPD, s2sActivityParams(s2sBidRequest.s2sConfig)), + customHeaders } ); } else { diff --git a/modules/prebidServerBidAdapter/ortbConverter.js b/modules/prebidServerBidAdapter/ortbConverter.js index d445a52dcc6..242c65c7dfa 100644 --- a/modules/prebidServerBidAdapter/ortbConverter.js +++ b/modules/prebidServerBidAdapter/ortbConverter.js @@ -25,6 +25,7 @@ import {isActivityAllowed} from '../../src/activities/rules.js'; import {ACTIVITY_TRANSMIT_TID} from '../../src/activities/activities.js'; import {currencyCompare} from '../../libraries/currencyUtils/currency.js'; import {minimum} from '../../src/utils/reducers.js'; +import {s2sDefaultConfig} from './index.js'; const DEFAULT_S2S_TTL = 60; const DEFAULT_S2S_CURRENCY = 'USD'; @@ -57,8 +58,8 @@ const PBS_CONVERTER = ortbConverter({ let {s2sBidRequest, requestedBidders, eidPermissions} = context; const request = buildRequest(imps, proxyBidderRequest, context); - request.tmax = s2sBidRequest.s2sConfig.timeout; - request.ext.tmaxmax = request.ext.tmaxmax || context.s2sBidRequest.requestBidsTimeout; + request.tmax = s2sBidRequest.s2sConfig.timeout ?? Math.min(s2sBidRequest.requestBidsTimeout * 0.75, s2sBidRequest.s2sConfig.maxTimeout ?? s2sDefaultConfig.maxTimeout); + request.ext.tmaxmax = request.ext.tmaxmax || s2sBidRequest.requestBidsTimeout; [request.app, request.dooh, request.site].forEach(section => { if (section && !section.publisher?.id) { @@ -231,7 +232,7 @@ const PBS_CONVERTER = ortbConverter({ // override to process each request context.actualBidderRequests.forEach(req => orig(response, ortbResponse, {...context, bidderRequest: req, bidRequests: req.bids})); }, - fledgeAuctionConfigs(orig, response, ortbResponse, context) { + paapiConfigs(orig, response, ortbResponse, context) { const configs = Object.values(context.impContext) .flatMap((impCtx) => (impCtx.paapiConfigs || []).map(cfg => { const bidderReq = impCtx.actualBidderRequests.find(br => br.bidderCode === cfg.bidder); @@ -240,11 +241,12 @@ const PBS_CONVERTER = ortbConverter({ adUnitCode: impCtx.adUnit.code, ortb2: bidderReq?.ortb2, ortb2Imp: bidReq?.ortb2Imp, + bidder: cfg.bidder, config: cfg.config }; })); if (configs.length > 0) { - response.fledgeAuctionConfigs = configs; + response.paapi = configs; } } } @@ -300,7 +302,9 @@ export function buildPBSRequest(s2sBidRequest, bidderRequests, adUnits, requeste const proxyBidderRequest = { ...Object.fromEntries(Object.entries(bidderRequests[0]).filter(([k]) => !BIDDER_SPECIFIC_REQUEST_PROPS.has(k))), - fledgeEnabled: bidderRequests.some(req => req.fledgeEnabled) + paapi: { + enabled: bidderRequests.some(br => br.paapi?.enabled) + } } return PBS_CONVERTER.toORTB({ diff --git a/modules/prebidmanagerAnalyticsAdapter.md b/modules/prebidmanagerAnalyticsAdapter.md deleted file mode 100644 index 030e79b406f..00000000000 --- a/modules/prebidmanagerAnalyticsAdapter.md +++ /dev/null @@ -1,9 +0,0 @@ -# Overview - -Module Name: Prebid Manager Analytics Adapter -Module Type: Analytics Adapter -Maintainer: admin@prebidmanager.com - -# Description - -Analytics adapter for Prebid Manager. Contact admin@prebidmanager.com for information. diff --git a/modules/precisoBidAdapter.js b/modules/precisoBidAdapter.js index 9125f6f3911..b4f1b665d91 100644 --- a/modules/precisoBidAdapter.js +++ b/modules/precisoBidAdapter.js @@ -1,4 +1,4 @@ -import { logMessage, isFn, deepAccess, logInfo } from '../src/utils.js'; +import { isFn, deepAccess, logInfo } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; @@ -34,14 +34,7 @@ export const spec = { const countryCode = getCountryCodeByTimezone(city); logInfo(`The country code for ${city} is ${countryCode}`); - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page) - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; + location = bidderRequest?.refererInfo ?? null; let request = { id: validBidRequests[0].bidderRequestId, @@ -87,8 +80,8 @@ export const spec = { // Show a map centered at latitude / longitude. }) || { utcoffset: new Date().getTimezoneOffset() }, city: city, - 'host': location.host, - 'page': location.pathname, + 'host': location?.domain ?? '', + 'page': location?.page ?? '', 'coppa': config.getConfig('coppa') === true ? 1 : 0 // userId: validBidRequests[0].userId }; diff --git a/modules/programmaticaBidAdapter.js b/modules/programmaticaBidAdapter.js index 7d52e305189..aeca74120d6 100644 --- a/modules/programmaticaBidAdapter.js +++ b/modules/programmaticaBidAdapter.js @@ -1,6 +1,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { hasPurpose1Consent } from '../src/utils/gpdr.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; import { deepAccess, parseSizesInput, isArray } from '../src/utils.js'; const BIDDER_CODE = 'programmatica'; diff --git a/modules/pstudioBidAdapter.js b/modules/pstudioBidAdapter.js index 77a11ac58c6..1265d5c546f 100644 --- a/modules/pstudioBidAdapter.js +++ b/modules/pstudioBidAdapter.js @@ -14,8 +14,8 @@ import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'pstudio'; const ENDPOINT = 'https://exchange.pstudio.tadex.id/prebid-bid' const TIME_TO_LIVE = 300; -// in case that the publisher limits number of user syncs, thisse syncs will be discarded from the end of the list -// so more improtant syncing calls should be at the start of the list +// in case that the publisher limits number of user syncs, these syncs will be discarded from the end of the list +// so more important syncing calls should be at the start of the list const USER_SYNCS = [ // PARTNER_UID is a partner user id { @@ -40,6 +40,7 @@ const VIDEO_PARAMS = [ 'protocols', 'startdelay', 'placement', + 'plcmt', 'skip', 'skipafter', 'minbitrate', diff --git a/modules/pubCircleBidAdapter.js b/modules/pubCircleBidAdapter.js index 54224fd0403..c63b80b819c 100644 --- a/modules/pubCircleBidAdapter.js +++ b/modules/pubCircleBidAdapter.js @@ -1,231 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'pubcircle'; const AD_URL = 'https://ml.pubcircle.ai/pbjs'; const SYNC_URL = 'https://cs.pubcircle.ai'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - placement.placementId = placementId; - placement.type = 'publisher'; - - if (bid.userId) { - getUserId(placement.eids, bid.userId.uid2 && bid.userId.uid2.id, 'uidapi.com'); - getUserId(placement.eids, bid.userId.lotamePanoramaId, 'lotame.com'); - getUserId(placement.eids, bid.userId.idx, 'idx.lat'); - getUserId(placement.eids, bid.userId.idl_env, 'liveramp.com'); - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - -function getUserId(eids, id, source, uidExt) { - if (id) { - var uid = { id }; - if (uidExt) { - uid.ext = uidExt; - } - eids.push({ - source, - uids: [ uid ] - }); - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && params.placementId); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - }, - - onBidViewable: function (bid) { - // to do : we need to implement js tag to fire pixel with viewability counter - } + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/pubgeniusBidAdapter.js b/modules/pubgeniusBidAdapter.js index d92a9352cee..617123746e5 100644 --- a/modules/pubgeniusBidAdapter.js +++ b/modules/pubgeniusBidAdapter.js @@ -155,7 +155,7 @@ function buildVideoParams(videoMediaType, videoParams) { 'maxduration', 'protocols', 'startdelay', - 'placement', + 'plcmt', 'skip', 'skipafter', 'minbitrate', @@ -166,17 +166,6 @@ function buildVideoParams(videoMediaType, videoParams) { 'linearity', ]); - switch (videoMediaType.context) { - case 'instream': - params.placement = 1; - break; - case 'outstream': - params.placement = 2; - break; - default: - break; - } - if (videoMediaType.playerSize) { params.w = videoMediaType.playerSize[0][0]; params.h = videoMediaType.playerSize[0][1]; @@ -301,8 +290,7 @@ function isValidBanner(banner) { function isValidVideo(videoMediaType, videoParams) { const params = buildVideoParams(videoMediaType, videoParams); - return !!(params.placement && - isValidSize([params.w, params.h]) && + return !!(isValidSize([params.w, params.h]) && params.mimes && params.mimes.length && isArrayOfNums(params.protocols) && params.protocols.length); } diff --git a/modules/publirBidAdapter.js b/modules/publirBidAdapter.js index 432e123458c..2cf55aa86cb 100644 --- a/modules/publirBidAdapter.js +++ b/modules/publirBidAdapter.js @@ -2,32 +2,26 @@ import { logWarn, logInfo, isArray, - isFn, deepAccess, - isEmpty, - contains, timestamp, triggerPixel, - getDNT, - getBidIdParameter } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; import { getStorageManager } from '../src/storageManager.js'; import { ajax } from '../src/ajax.js'; +import { + generateBidsParams, + generateGeneralParams, +} from '../libraries/riseUtils/index.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'publir'; const ADAPTER_VERSION = '1.0.0'; const TTL = 360; const CURRENCY = 'USD'; -const DEFAULT_SELLER_ENDPOINT = 'https://prebid.publir.com/publirPrebidEndPoint'; +const BASE_URL = 'https://prebid.publir.com/publirPrebidEndPoint'; const DEFAULT_IMPS_ENDPOINT = 'https://prebidimpst.publir.com/publirPrebidImpressionTracker'; -const SUPPORTED_SYNC_METHODS = { - IFRAME: 'iframe', - PIXEL: 'pixel' -} export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { @@ -40,25 +34,26 @@ export const spec = { logWarn('pubId is a mandatory param for Publir adapter'); return false; } - return true; }, buildRequests: function (validBidRequests, bidderRequest) { - const reqObj = {}; + const combinedRequestsObject = {}; + const generalObject = validBidRequests[0]; - reqObj.params = generatePubGeneralsParams(generalObject, bidderRequest); - reqObj.bids = generatePubBidParams(validBidRequests, bidderRequest); - reqObj.bids.timestamp = timestamp(); + combinedRequestsObject.params = generateGeneralParams(generalObject, bidderRequest, ADAPTER_VERSION); + combinedRequestsObject.bids = generateBidsParams(validBidRequests, bidderRequest); + combinedRequestsObject.bids.timestamp = timestamp(); + let options = { withCredentials: false }; return { method: 'POST', - url: DEFAULT_SELLER_ENDPOINT, - data: reqObj, + url: BASE_URL, + data: combinedRequestsObject, options - } + }; }, interpretResponse: function ({ body }) { const bidResponses = []; @@ -109,20 +104,20 @@ export const spec = { const syncs = []; for (const response of serverResponses) { if (response.body && response.body.params) { - if (syncOptions.iframeEnabled && response.body.params.userSyncURL) { + if (syncOptions.iframeEnabled && deepAccess(response, 'body.params.userSyncURL')) { syncs.push({ type: 'iframe', - url: response.body.params.userSyncURL + url: deepAccess(response, 'body.params.userSyncURL') }); } - if (syncOptions.pixelEnabled && isArray(response.body.params.userSyncPixels)) { + if (syncOptions.pixelEnabled && isArray(deepAccess(response, 'body.params.userSyncPixels'))) { const pixels = response.body.params.userSyncPixels.map(pixel => { return { type: 'image', url: pixel - } - }) - syncs.push(...pixels) + }; + }); + syncs.push(...pixels); } } } @@ -141,251 +136,3 @@ export const spec = { }; registerBidder(spec); - -/** - * Get floor price - * @param bid {bid} - * @returns {Number} - */ -function getFloor(bid, mediaType) { - if (!isFn(bid.getFloor)) { - return 0; - } - let floorResult = bid.getFloor({ - currency: CURRENCY, - mediaType: mediaType, - size: '*' - }); - return floorResult.currency === CURRENCY && floorResult.floor ? floorResult.floor : 0; -} - -/** - * Get the the ad sizes array from the bid - * @param bid {bid} - * @returns {Array} - */ -function getSizesArray(bid, mediaType) { - let sizesArray = [] - - if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) { - sizesArray = bid.mediaTypes[mediaType].sizes; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizesArray = bid.sizes; - } - - return sizesArray; -} - -/** - * Get schain string value - * @param schainObject {Object} - * @returns {string} - */ -function getSupplyChain(schainObject) { - if (isEmpty(schainObject)) { - return ''; - } - let scStr = `${schainObject.ver},${schainObject.complete}`; - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - return scStr; -} - -/** - * Get encoded node value - * @param val {string} - * @returns {string} - */ -function getEncodedValIfNotEmpty(val) { - return !isEmpty(val) ? encodeURIComponent(val) : ''; -} - -function getAllowedSyncMethod(filterSettings, bidderCode) { - const iframeConfigsToCheck = ['all', 'iframe']; - const pixelConfigToCheck = 'image'; - if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { - return SUPPORTED_SYNC_METHODS.IFRAME; - } - if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { - return SUPPORTED_SYNC_METHODS.PIXEL; - } -} - -/** - * Check if sync rule is supported - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - const isInclude = syncRule.filter === 'include'; - const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - return isInclude && contains(bidders, bidderCode); -} - -/** - * get device type - * @param ua {ua} - * @returns {string} - */ -function getDeviceType(ua) { - if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(ua.toLowerCase())) { - return '5'; - } - if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(ua.toLowerCase())) { - return '4'; - } - if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i.test(ua.toLowerCase())) { - return '3'; - } - return '1'; -} - -function generatePubBidParams(validBidRequests, bidderRequest) { - const bidsArray = []; - - if (validBidRequests.length) { - validBidRequests.forEach(bid => { - bidsArray.push(generateBidParameters(bid, bidderRequest)); - }); - } - return bidsArray; -} - -/** - * Generate bid specific parameters - * @param {bid} bid - * @param {bidderRequest} bidderRequest - * @returns {Object} bid specific params object - */ -function generateBidParameters(bid, bidderRequest) { - const { params } = bid; - const mediaType = isBanner(bid) ? BANNER : VIDEO; - const sizesArray = getSizesArray(bid, mediaType); - - // fix floor price in case of NAN - if (isNaN(params.floorPrice)) { - params.floorPrice = 0; - } - - const bidObject = { - mediaType, - adUnitCode: getBidIdParameter('adUnitCode', bid), - sizes: sizesArray, - floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice), - bidId: getBidIdParameter('bidId', bid), - bidderRequestId: getBidIdParameter('bidderRequestId', bid), - loop: getBidIdParameter('bidderRequestsCount', bid), - transactionId: bid.ortb2Imp?.ext?.tid, - coppa: 0 - }; - - const pubId = params.pubId; - if (pubId) { - bidObject.pubId = pubId; - } - - const sua = deepAccess(bid, `ortb2.device.sua`); - if (sua) { - bidObject.sua = sua; - } - - const coppa = deepAccess(bid, `ortb2.regs.coppa`) - if (coppa) { - bidObject.coppa = 1; - } - - return bidObject; -} - -function isBanner(bid) { - return bid.mediaTypes && bid.mediaTypes.banner; -} - -function getLocalStorage(cookieObjName) { - if (storage.localStorageIsEnabled()) { - const lstData = storage.getDataFromLocalStorage(cookieObjName); - return lstData; - } - return ''; -} - -/** - * Generate params that are common between all bids - * @param generalObject - * @param {bidderRequest} bidderRequest - * @returns {object} the common params object - */ -function generatePubGeneralsParams(generalObject, bidderRequest) { - const domain = bidderRequest.refererInfo; - const { syncEnabled, filterSettings } = config.getConfig('userSync') || {}; - const { bidderCode } = bidderRequest; - const generalBidParams = generalObject.params; - const timeout = bidderRequest.timeout; - const generalParams = { - wrapper_type: 'prebidjs', - wrapper_vendor: '$$PREBID_GLOBAL$$', - wrapper_version: '$prebid.version$', - adapter_version: ADAPTER_VERSION, - auction_start: bidderRequest.auctionStart, - publisher_id: generalBidParams.pubId, - publisher_name: domain, - site_domain: domain, - dnt: getDNT() ? 1 : 0, - device_type: getDeviceType(navigator.userAgent), - ua: navigator.userAgent, - is_wrapper: !!generalBidParams.isWrapper, - session_id: generalBidParams.sessionId || getBidIdParameter('bidderRequestId', generalObject), - tmax: timeout, - user_cookie: getLocalStorage('_publir_prebid_creative') - }; - - const userIdsParam = getBidIdParameter('userId', generalObject); - if (userIdsParam) { - generalParams.userIds = JSON.stringify(userIdsParam); - } - - const ortb2Metadata = bidderRequest.ortb2 || {}; - if (ortb2Metadata.site) { - generalParams.site_metadata = JSON.stringify(ortb2Metadata.site); - } - if (ortb2Metadata.user) { - generalParams.user_metadata = JSON.stringify(ortb2Metadata.user); - } - - if (syncEnabled) { - const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); - if (allowedSyncMethod) { - generalParams.cs_method = allowedSyncMethod; - } - } - - if (bidderRequest.uspConsent) { - generalParams.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies; - generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - - if (generalObject.schain) { - generalParams.schain = getSupplyChain(generalObject.schain); - } - - if (bidderRequest && bidderRequest.refererInfo) { - generalParams.page_url = deepAccess(bidderRequest, 'refererInfo.page') || deepAccess(window, 'location.href'); - } - - return generalParams; -} diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index 9e1fa49fef2..e54db34d401 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -281,7 +281,7 @@ function isOWPubmaticBid(adapterName) { }) } -function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { +function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid, e) { highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null; return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) { adUnit.bids[bidId].forEach(function(bid) { @@ -290,6 +290,16 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { return; } const pg = window.parseFloat(Number(bid.bidResponse?.adserverTargeting?.hb_pb || bid.bidResponse?.adserverTargeting?.pwtpb).toFixed(BID_PRECISION)); + + const prebidBidsReceived = e?.bidsReceived; + if (isArray(prebidBidsReceived) && prebidBidsReceived.length > 0) { + prebidBidsReceived.forEach(function(iBid) { + if (iBid.adId === bid.adId) { + bid.bidderCode = iBid.bidderCode; + } + }); + } + partnerBids.push({ 'pn': adapterName, 'bc': bid.bidderCode || bid.bidder, @@ -391,7 +401,7 @@ function executeBidsLoggerCall(e, highestCpmBids) { outputObj['pdvid'] = '' + profileVersionId; outputObj['dvc'] = {'plt': getDevicePlatform()}; outputObj['tgid'] = getTgId(); - outputObj['pbv'] = getGlobal()?.version || '-1'; + outputObj['pbv'] = '$prebid.version$' || '-1'; if (floorData && floorFetchStatus) { outputObj['fmv'] = floorData.floorRequestData ? floorData.floorRequestData.modelVersion || undefined : undefined; @@ -407,7 +417,7 @@ function executeBidsLoggerCall(e, highestCpmBids) { 'au': origAdUnit.owAdUnitId || getGptSlotInfoForAdUnitCode(adUnitId)?.gptSlot || adUnitId, 'mt': getAdUnitAdFormats(origAdUnit), 'sz': getSizesForAdUnit(adUnit, adUnitId), - 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)), + 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId), e), 'fskp': floorData && floorFetchStatus ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined, 'sid': generateUUID() }; @@ -559,7 +569,8 @@ function bidResponseHandler(args) { logWarn(LOG_PRE_FIX + 'Got null requestId in bidResponseHandler'); return; } - let bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId][0]; + let requestId = args.originalRequestId || args.requestId; + let bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[requestId][0]; if (!bid) { logError(LOG_PRE_FIX + 'Could not find associated bid request for bid response with requestId: ', args.requestId); return; @@ -567,7 +578,9 @@ function bidResponseHandler(args) { if ((bid.bidder && args.bidderCode && bid.bidder !== args.bidderCode) || (bid.bidder === args.bidderCode && bid.status === SUCCESS)) { bid = copyRequiredBidDetails(args); - cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId].push(bid); + cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[requestId].push(bid); + } else if (args.originalRequestId) { + bid.bidId = args.requestId; } if (args.floorData) { @@ -598,7 +611,7 @@ function bidRejectedHandler(args) { function bidderDoneHandler(args) { cache.auctions[args.auctionId].bidderDonePendingCount--; args.bids.forEach(bid => { - let cachedBid = cache.auctions[bid.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId || bid.requestId]; + let cachedBid = cache.auctions[bid.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId || bid.originalRequestId || bid.requestId]; if (typeof bid.serverResponseTimeMs !== 'undefined') { cachedBid.serverLatencyTimeMs = bid.serverResponseTimeMs; } @@ -613,7 +626,7 @@ function bidderDoneHandler(args) { function bidWonHandler(args) { let auctionCache = cache.auctions[args.auctionId]; - auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.requestId; + auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.originalRequestId || args.requestId; auctionCache.adUnitCodes[args.adUnitCode].bidWonAdId = args.adId; executeBidWonLoggerCall(args.auctionId, args.adUnitCode); } @@ -631,7 +644,7 @@ function bidTimeoutHandler(args) { // db = 0 and t = 1 means bidder did respond with a bid but post timeout args.forEach(badBid => { let auctionCache = cache.auctions[badBid.auctionId]; - let bid = auctionCache.adUnitCodes[badBid.adUnitCode].bids[ badBid.bidId || badBid.requestId ][0]; + let bid = auctionCache.adUnitCodes[badBid.adUnitCode].bids[ badBid.bidId || badBid.originalRequestId || badBid.requestId ][0]; if (bid) { bid.status = ERROR; bid.error = { diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 5b470fdc34a..85018a73a54 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -68,6 +68,10 @@ const NATIVE_ASSET_IMAGE_TYPE = { 'IMAGE': 3 } +const BANNER_CUSTOM_PARAMS = { + 'battr': DATA_TYPES.ARRAY +} + const NET_REVENUE = true; const dealChannelValues = { 1: 'PMP', @@ -551,6 +555,14 @@ function _createBannerRequest(bid) { } bannerObj.pos = 0; bannerObj.topframe = inIframe() ? 0 : 1; + + // Adding Banner custom params + const bannerCustomParams = {...deepAccess(bid, 'ortb2Imp.banner')}; + for (let key in BANNER_CUSTOM_PARAMS) { + if (bannerCustomParams.hasOwnProperty(key)) { + bannerObj[key] = _checkParamDataType(key, bannerCustomParams[key], BANNER_CUSTOM_PARAMS[key]); + } + } } else { logWarn(LOG_WARN_PREFIX + 'Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.'); bannerObj = UNDEFINED; @@ -663,7 +675,7 @@ function _createImpressionObject(bid, bidderRequest) { var sizes = bid.hasOwnProperty('sizes') ? bid.sizes : []; var mediaTypes = ''; var format = []; - var isFledgeEnabled = bidderRequest?.fledgeEnabled; + var isFledgeEnabled = bidderRequest?.paapi?.enabled; impObj = { id: bid.bidId, @@ -1094,7 +1106,6 @@ export const spec = { /** * Make a server request from the list of BidRequests. * - * @param {validBidRequests} - an array of bids * @return ServerRequest Info describing the request to the server. */ buildRequests: (validBidRequests, bidderRequest) => { @@ -1419,7 +1430,7 @@ export const spec = { }); return { bids: bidResponses, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, } } } catch (error) { diff --git a/modules/pubwiseBidAdapter.js b/modules/pubwiseBidAdapter.js index eca0c971050..639a39d4636 100644 --- a/modules/pubwiseBidAdapter.js +++ b/modules/pubwiseBidAdapter.js @@ -63,6 +63,7 @@ const VIDEO_CUSTOM_PARAMS = { 'battr': DATA_TYPES.ARRAY, 'linearity': DATA_TYPES.NUMBER, 'placement': DATA_TYPES.NUMBER, + 'plcmt': DATA_TYPES.NUMBER, 'minbitrate': DATA_TYPES.NUMBER, 'maxbitrate': DATA_TYPES.NUMBER, 'skip': DATA_TYPES.NUMBER diff --git a/modules/pubxaiAnalyticsAdapter.js b/modules/pubxaiAnalyticsAdapter.js index d4a7ec70a70..afa8b01bfca 100644 --- a/modules/pubxaiAnalyticsAdapter.js +++ b/modules/pubxaiAnalyticsAdapter.js @@ -1,208 +1,346 @@ -import { deepAccess, parseSizesInput, getWindowLocation, buildUrl } from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; +import { + getGptSlotInfoForAdUnitCode, getGptSlotForAdUnitCode +} from '../libraries/gptUtils/gptUtils.js'; +import { getDeviceType, getBrowser, getOS } from '../libraries/userAgentUtils/index.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import adapterManager from '../src/adapterManager.js'; +import { sendBeacon } from '../src/ajax.js' import { EVENTS } from '../src/constants.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { + deepAccess, parseSizesInput, getWindowLocation, buildUrl, cyrb53Hash +} from '../src/utils.js'; + +let initOptions; const emptyUrl = ''; const analyticsType = 'endpoint'; -const pubxaiAnalyticsVersion = 'v1.2.0'; +const adapterCode = 'pubxai'; +const pubxaiAnalyticsVersion = 'v2.0.0'; const defaultHost = 'api.pbxai.com'; const auctionPath = '/analytics/auction'; const winningBidPath = '/analytics/bidwon'; +const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: adapterCode }) -let initOptions; -let auctionTimestamp; -let auctionCache = []; -let events = { - bids: [], - floorDetail: {}, - pageDetail: {}, - deviceDetail: {} -}; - -function getStorage() { - try { - return window.top['sessionStorage']; - } catch (e) { - return null; +/** + * The sendCache is a global cache object which tracks the pending sends + * back to pubx.ai. The data may be removed from this cache, post send. + */ +export const sendCache = new Proxy( + {}, + { + get: (target, name) => { + if (!target.hasOwnProperty(name)) { + target[name] = []; + } + return target[name]; + }, } -} +); -var pubxaiAnalyticsAdapter = Object.assign(adapter( +/** + * auctionCache is a global cache object which stores all auction histories + * for the session. When getting a key from the auction cache, any + * information already known about the auction or associated data (floor + * data configured by prebid, browser data, user data etc) is added to + * the cache automatically. + */ +export const auctionCache = new Proxy( + {}, { - emptyUrl, - analyticsType - }), { - track({ eventType, args }) { - if (typeof args !== 'undefined') { - if (eventType === EVENTS.BID_TIMEOUT) { - args.forEach(item => { mapBidResponse(item, 'timeout'); }); - } else if (eventType === EVENTS.AUCTION_INIT) { - events.auctionInit = args; - events.floorDetail = {}; - events.bids = []; - const floorData = deepAccess(args, 'bidderRequests.0.bids.0.floorData'); - if (typeof floorData !== 'undefined') { - Object.assign(events.floorDetail, floorData); - } - auctionTimestamp = args.timestamp; - } else if (eventType === EVENTS.BID_RESPONSE) { - mapBidResponse(args, 'response'); - } else if (eventType === EVENTS.BID_WON) { - send({ - winningBid: mapBidResponse(args, 'bidwon') - }, 'bidwon'); + get: (target, name) => { + if (!target.hasOwnProperty(name)) { + target[name] = { + bids: [], + auctionDetail: { + refreshRank: Object.keys(target).length, + auctionId: name, + }, + floorDetail: {}, + pageDetail: { + host: getWindowLocation().host, + path: getWindowLocation().pathname, + search: getWindowLocation().search, + }, + deviceDetail: { + platform: navigator.platform, + deviceType: getDeviceType(), + deviceOS: getOS(), + browser: getBrowser(), + }, + userDetail: { + userIdTypes: Object.keys(getGlobal().getUserIds?.() || {}), + }, + consentDetail: { + consentTypes: Object.keys(getGlobal().getConsentMetadata?.() || {}), + }, + pmacDetail: JSON.parse(storage.getDataFromLocalStorage('pubx:pmac')) || {}, // {auction_1: {floor:0.23,maxBid:0.34,bidCount:3},auction_2:{floor:0.13,maxBid:0.14,bidCount:2} + initOptions: { + ...initOptions, + auctionId: name, // back-compat + }, + sendAs: [], + }; } - } - if (eventType === EVENTS.AUCTION_END) { - send(events, 'auctionEnd'); - } + return target[name]; + }, } -}); +); -function mapBidResponse(bidResponse, status) { - if (typeof bidResponse !== 'undefined') { - let bid = { - adUnitCode: bidResponse.adUnitCode, - gptSlotCode: getGptSlotInfoForAdUnitCode(bidResponse.adUnitCode).gptSlot || null, - auctionId: bidResponse.auctionId, - bidderCode: bidResponse.bidder, - cpm: bidResponse.cpm, - creativeId: bidResponse.creativeId, - currency: bidResponse.currency, - floorData: bidResponse.floorData, - mediaType: bidResponse.mediaType, - netRevenue: bidResponse.netRevenue, - requestTimestamp: bidResponse.requestTimestamp, - responseTimestamp: bidResponse.responseTimestamp, - status: bidResponse.status, - statusMessage: bidResponse.statusMessage, - timeToRespond: bidResponse.timeToRespond, - transactionId: bidResponse.transactionId - }; - if (status !== 'bidwon') { - Object.assign(bid, { - bidId: status === 'timeout' ? bidResponse.bidId : bidResponse.requestId, - renderStatus: status === 'timeout' ? 3 : 2, - sizes: parseSizesInput(bidResponse.size).toString(), +/** + * Fetch extra ad server data for a specific ad slot (bid) + * @param {object} bid an output from extractBid + * @returns {object} key value pairs from the adserver + */ +const getAdServerDataForBid = (bid) => { + const gptSlot = getGptSlotForAdUnitCode(bid); + if (gptSlot) { + return Object.fromEntries( + gptSlot + .getTargetingKeys() + .filter( + (key) => + key.startsWith('pubx-') || + (key.startsWith('hb_') && (key.match(/_/g) || []).length === 1) + ) + .map((key) => [key, gptSlot.getTargeting(key)]) + ); + } + return {}; // TODO: support more ad servers +}; + +/** + * extracts and derives valuable data from a prebid bidder bidResponse object + * @param {object} bidResponse a prebid bidder bidResponse (see + * https://docs.prebid.org/dev-docs/publisher-api-reference/getBidResponses.html) + * @returns {object} + */ +const extractBid = (bidResponse) => { + return { + adUnitCode: bidResponse.adUnitCode, + gptSlotCode: + getGptSlotInfoForAdUnitCode(bidResponse.adUnitCode).gptSlot || null, + auctionId: bidResponse.auctionId, + bidderCode: bidResponse.bidder, + cpm: bidResponse.cpm, + creativeId: bidResponse.creativeId, + dealId: bidResponse.dealId, + currency: bidResponse.currency, + floorData: bidResponse.floorData, + mediaType: bidResponse.mediaType, + netRevenue: bidResponse.netRevenue, + requestTimestamp: bidResponse.requestTimestamp, + responseTimestamp: bidResponse.responseTimestamp, + status: bidResponse.status, + sizes: parseSizesInput(bidResponse.size).toString(), + statusMessage: bidResponse.statusMessage, + timeToRespond: bidResponse.timeToRespond, + transactionId: bidResponse.transactionId, + bidId: bidResponse.bidId || bidResponse.requestId, + placementId: bidResponse.params + ? deepAccess(bidResponse, 'params.0.placementId') + : null, + source: bidResponse.source || 'null', + }; +}; + +/** + * Track the events emitted by prebid and handle each case. See https://docs.prebid.org/dev-docs/publisher-api-reference/getEvents.html for more info + * @param {object} event the prebid event emmitted + * @param {string} event.eventType the type of the event + * @param {object} event.args the arguments of the emitted event + */ +const track = ({ eventType, args }) => { + switch (eventType) { + // handle invalid bids, and remove them from the adUnit cache + case EVENTS.BID_TIMEOUT: + args.map(extractBid).forEach((bid) => { + bid.renderStatus = 3; + auctionCache[bid.auctionId].bids.push(bid); + }); + break; + // handle valid bid responses and record them as part of an auction + case EVENTS.BID_RESPONSE: + const bid = Object.assign(extractBid(args), { renderStatus: 2 }); + auctionCache[bid.auctionId].bids.push(bid); + break; + // capture extra information from the auction, and if there were no bids + // (and so no chance of a win) send the auction + case EVENTS.AUCTION_END: + Object.assign( + auctionCache[args.auctionId].floorDetail, + args.adUnits + .map((i) => i?.bids.length && i.bids[0]?.floorData) + .find((i) => i) || {} + ); + auctionCache[args.auctionId].deviceDetail.cdep = args.bidderRequests + .map((bidRequest) => bidRequest.ortb2?.device?.ext?.cdep) + .find((i) => i); + Object.assign(auctionCache[args.auctionId].auctionDetail, { + adUnitCodes: args.adUnits.map((i) => i.code), + timestamp: args.timestamp, }); - events.bids.push(bid); - } else { - Object.assign(bid, { - bidId: bidResponse.requestId, - floorProvider: events.floorDetail?.floorProvider || null, - floorFetchStatus: events.floorDetail?.fetchStatus || null, - floorLocation: events.floorDetail?.location || null, - floorModelVersion: events.floorDetail?.modelVersion || null, - floorSkipRate: events.floorDetail?.skipRate || 0, - isFloorSkipped: events.floorDetail?.skipped || false, + if ( + auctionCache[args.auctionId].bids.every((bid) => bid.renderStatus === 3) + ) { + prepareSend(args.auctionId); + } + break; + // send the prebid winning bid back to pubx + case EVENTS.BID_WON: + const winningBid = extractBid(args); + const floorDetail = auctionCache[winningBid.auctionId].floorDetail; + Object.assign(winningBid, { + floorProvider: floorDetail?.floorProvider || null, + floorFetchStatus: floorDetail?.fetchStatus || null, + floorLocation: floorDetail?.location || null, + floorModelVersion: floorDetail?.modelVersion || null, + floorSkipRate: floorDetail?.skipRate || 0, + isFloorSkipped: floorDetail?.skipped || false, isWinningBid: true, - placementId: bidResponse.params ? deepAccess(bidResponse, 'params.0.placementId') : null, - renderedSize: bidResponse.size, - renderStatus: 4 + renderedSize: args.size, + renderStatus: 4, }); - return bid; - } - } -} - -export function getDeviceType() { - if ((/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(navigator.userAgent.toLowerCase()))) { - return 'tablet'; - } - if ((/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(navigator.userAgent.toLowerCase()))) { - return 'mobile'; + winningBid.adServerData = getAdServerDataForBid(winningBid); + auctionCache[winningBid.auctionId].winningBid = winningBid; + prepareSend(winningBid.auctionId); + break; + // do nothing + default: + break; } - return 'desktop'; -} - -export function getBrowser() { - if (/Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor)) return 'Chrome'; - else if (navigator.userAgent.match('CriOS')) return 'Chrome'; - else if (/Firefox/.test(navigator.userAgent)) return 'Firefox'; - else if (/Edg/.test(navigator.userAgent)) return 'Microsoft Edge'; - else if (/Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor)) return 'Safari'; - else if (/Trident/.test(navigator.userAgent) || /MSIE/.test(navigator.userAgent)) return 'Internet Explorer'; - else return 'Others'; -} - -export function getOS() { - if (navigator.userAgent.indexOf('Android') != -1) return 'Android'; - if (navigator.userAgent.indexOf('like Mac') != -1) return 'iOS'; - if (navigator.userAgent.indexOf('Win') != -1) return 'Windows'; - if (navigator.userAgent.indexOf('Mac') != -1) return 'Macintosh'; - if (navigator.userAgent.indexOf('Linux') != -1) return 'Linux'; - if (navigator.appVersion.indexOf('X11') != -1) return 'Unix'; - return 'Others'; -} +}; -// add sampling rate -pubxaiAnalyticsAdapter.shouldFireEventRequest = function (samplingRate = 1) { - return (Math.floor((Math.random() * samplingRate + 1)) === parseInt(samplingRate)); +/** + * If true, send data back to pubxai + * @param {string} auctionId + * @param {number} samplingRate + * @returns {boolean} + */ +const shouldFireEventRequest = (auctionId, samplingRate = 1) => { + return parseInt(cyrb53Hash(auctionId)) % samplingRate === 0; }; -function send(data, status) { - if (pubxaiAnalyticsAdapter.shouldFireEventRequest(initOptions.samplingRate)) { - let location = getWindowLocation(); - const storage = getStorage(); - data.initOptions = initOptions; - data.pageDetail = {}; - Object.assign(data.pageDetail, { - host: location.host, - path: location.pathname, - search: location.search - }); - if (typeof data !== 'undefined' && typeof data.auctionInit !== 'undefined') { - data.pageDetail.adUnits = data.auctionInit.adUnitCodes; - data.initOptions.auctionId = data.auctionInit.auctionId; - delete data.auctionInit; - - data.pmcDetail = {}; - Object.assign(data.pmcDetail, { - bidDensity: storage ? storage.getItem('pbx:dpbid') : null, - maxBid: storage ? storage.getItem('pbx:mxbid') : null, - auctionId: storage ? storage.getItem('pbx:aucid') : null, - }); +/** + * prepare the payload for sending auction data back to pubx.ai + * @param {string} auctionId the auction to send + */ +const prepareSend = (auctionId) => { + const auctionData = Object.assign({}, auctionCache[auctionId]); + if (!shouldFireEventRequest(auctionId, initOptions.samplingRate)) { + return; + } + [ + { + path: winningBidPath, + requiredKeys: [ + 'winningBid', + 'pageDetail', + 'deviceDetail', + 'floorDetail', + 'auctionDetail', + 'userDetail', + 'consentDetail', + 'pmacDetail', + 'initOptions', + ], + eventType: 'win', + }, + { + path: auctionPath, + requiredKeys: [ + 'bids', + 'pageDetail', + 'deviceDetail', + 'floorDetail', + 'auctionDetail', + 'userDetail', + 'consentDetail', + 'pmacDetail', + 'initOptions', + ], + eventType: 'auction', + }, + ].forEach(({ path, requiredKeys, eventType }) => { + const data = Object.fromEntries( + requiredKeys.map((key) => [key, auctionData[key]]) + ); + if ( + auctionCache[auctionId].sendAs.includes(eventType) || + !requiredKeys.every((key) => !!auctionData[key]) + ) { + return; } - data.deviceDetail = {}; - Object.assign(data.deviceDetail, { - platform: navigator.platform, - deviceType: getDeviceType(), - deviceOS: getOS(), - browser: getBrowser() - }); - - let pubxaiAnalyticsRequestUrl = buildUrl({ + const pubxaiAnalyticsRequestUrl = buildUrl({ protocol: 'https', - hostname: (initOptions && initOptions.hostName) || defaultHost, - pathname: status == 'bidwon' ? winningBidPath : auctionPath, + hostname: + (auctionData.initOptions && auctionData.initOptions.hostName) || + defaultHost, + pathname: path, search: { - auctionTimestamp: auctionTimestamp, + auctionTimestamp: auctionData.auctionDetail.timestamp, pubxaiAnalyticsVersion: pubxaiAnalyticsVersion, - prebidVersion: getGlobal().version + prebidVersion: '$prebid.version$', + }, + }); + sendCache[pubxaiAnalyticsRequestUrl].push(data); + auctionCache[auctionId].sendAs.push(eventType); + }); +}; + +const send = () => { + const toBlob = (d) => new Blob([JSON.stringify(d)], { type: 'text/json' }); + + Object.entries(sendCache).forEach(([requestUrl, events]) => { + let payloadStart = 0; + + events.forEach((event, index, arr) => { + const payload = arr.slice(payloadStart, index + 2); + const payloadTooLarge = toBlob(payload).size > 65536; + + if (payloadTooLarge || index + 1 === arr.length) { + sendBeacon( + requestUrl, + toBlob(payloadTooLarge ? payload.slice(0, -1) : payload) + ); + payloadStart = index; } }); - if (status == 'bidwon') { - ajax(pubxaiAnalyticsRequestUrl, undefined, JSON.stringify(data), { method: 'POST', contentType: 'text/json' }); - } else if (status == 'auctionEnd' && auctionCache.indexOf(data.initOptions.auctionId) === -1) { - ajax(pubxaiAnalyticsRequestUrl, undefined, JSON.stringify(data), { method: 'POST', contentType: 'text/json' }); - auctionCache.push(data.initOptions.auctionId); + + events.splice(0); + }); +}; + +// register event listener to send logs when user leaves page +if (document.visibilityState) { + document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'hidden') { + send(); } - } + }); } -pubxaiAnalyticsAdapter.originEnableAnalytics = pubxaiAnalyticsAdapter.enableAnalytics; -pubxaiAnalyticsAdapter.enableAnalytics = function (config) { +// declare the analytics adapter +var pubxaiAnalyticsAdapter = Object.assign( + adapter({ + emptyUrl, + analyticsType, + }), + { track } +); + +pubxaiAnalyticsAdapter.originEnableAnalytics = + pubxaiAnalyticsAdapter.enableAnalytics; +pubxaiAnalyticsAdapter.enableAnalytics = (config) => { initOptions = config.options; pubxaiAnalyticsAdapter.originEnableAnalytics(config); }; adapterManager.registerAnalyticsAdapter({ adapter: pubxaiAnalyticsAdapter, - code: 'pubxai' + code: adapterCode, }); export default pubxaiAnalyticsAdapter; diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js index 516254b358b..50747616872 100644 --- a/modules/pulsepointBidAdapter.js +++ b/modules/pulsepointBidAdapter.js @@ -1,7 +1,6 @@ import { ortbConverter } from '../libraries/ortbConverter/converter.js'; import {isArray} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; const DEFAULT_CURRENCY = 'USD'; const KNOWN_PARAMS = ['cp', 'ct', 'cf', 'battr', 'deals']; @@ -58,13 +57,6 @@ export const spec = { url: 'https://bh.contextweb.com/visitormatch/prebid' }]; } - }, - transformBidParams: function(params) { - return convertTypes({ - 'cf': 'string', - 'cp': 'number', - 'ct': 'number' - }, params); } }; diff --git a/modules/qtBidAdapter.js b/modules/qtBidAdapter.js index e26aad8f9ec..f9f8b9b9efe 100644 --- a/modules/qtBidAdapter.js +++ b/modules/qtBidAdapter.js @@ -1,239 +1,19 @@ -import { logMessage, logError, deepAccess } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'qt'; const AD_URL = 'https://endpoint1.qt.io/pbjs'; const SYNC_URL = 'https://cs.qt.io'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes, transactionId, userIdAsEids } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.plcmt = mediaTypes[VIDEO].plcmt; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - if (transactionId) { - placement.ext = placement.ext || {}; - placement.ext.tid = transactionId; - } - - if (userIdAsEids && userIdAsEids.length) { - placement.eids = userIdAsEids; - } - - return placement; -} - -function getBidFloor(bid) { - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0, - tmax: bidderRequest.timeout - }; - - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - - if (bidderRequest.gdprConsent) { - request.gdpr = { - consentString: bidderRequest.gdprConsent.consentString - }; - } - - if (bidderRequest.gppConsent) { - request.gpp = bidderRequest.gppConsent.gppString; - request.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - request.gpp = bidderRequest.ortb2.regs.gpp; - request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { - syncUrl += '&gpp=' + gppConsent.gppString; - syncUrl += '&gpp_sid=' + gppConsent.applicableSections.join(','); - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 1ba23302367..ea907f0429c 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -49,7 +49,6 @@ function makeVideoImp(bid) { maxbitrate: video.maxbitrate, playbackmethod: video.playbackmethod, delivery: video.delivery, - placement: video.placement, api: video.api, w: video.w, h: video.h @@ -58,7 +57,7 @@ function makeVideoImp(bid) { return { video: videoCopy, placementCode: bid.placementCode, - bidFloor: bid.params.bidFloor || DEFAULT_BID_FLOOR + bidFloor: DEFAULT_BID_FLOOR }; } @@ -76,7 +75,7 @@ function makeBannerImp(bid) { }) }, placementCode: bid.placementCode, - bidFloor: bid.params.bidFloor || DEFAULT_BID_FLOOR + bidFloor: DEFAULT_BID_FLOOR }; } diff --git a/modules/raynRtdProvider.js b/modules/raynRtdProvider.js index d558c360c4a..ee3d18be381 100644 --- a/modules/raynRtdProvider.js +++ b/modules/raynRtdProvider.js @@ -14,6 +14,7 @@ import { deepAccess, deepSetValue, logError, logMessage, mergeDeep } from '../sr const MODULE_NAME = 'realTimeData'; const SUBMODULE_NAME = 'rayn'; const RAYN_TCF_ID = 1220; +const RAYN_PERSONA_TAXONOMY_ID = 103015; const LOG_PREFIX = 'RaynJS: '; export const SEGMENTS_RESOLVER = 'rayn.io'; export const RAYN_LOCAL_STORAGE_KEY = 'rayn-segtax'; @@ -77,6 +78,32 @@ export function generateOrtbDataObject(segtax, segment, maxTier) { }; } +/** + * Create and return ORTB2 object with segtax and personaIds + * @param {number} segtax + * @param {Array} personaIds + * @return {Array} + */ +export function generatePersonaOrtbDataObject(segtax, personaIds) { + const segmentIds = []; + + try { + segmentIds.push(...personaIds.map((id) => { + return { id }; + })) + } catch (error) { + logError(LOG_PREFIX, error); + } + + return { + name: SEGMENTS_RESOLVER, + ext: { + segtax, + }, + segment: segmentIds, + }; +} + /** * Generates checksum * @param {string} url @@ -127,8 +154,14 @@ export function setSegmentsAsBidderOrtb2(bidConfig, bidders, integrationConfig, deepSetValue(raynOrtb2, 'site.content.data', raynContentData); } + const raynUserData = []; if (integrationConfig.iabAudienceCategories.v1_1.enabled && segments[4]) { - const raynUserData = [generateOrtbDataObject(4, segments[4], integrationConfig.iabAudienceCategories.v1_1.tier)]; + raynUserData.push(generateOrtbDataObject(4, segments[4], integrationConfig.iabAudienceCategories.v1_1.tier)); + } + if (segments[RAYN_PERSONA_TAXONOMY_ID]) { + raynUserData.push(generatePersonaOrtbDataObject(RAYN_PERSONA_TAXONOMY_ID, segments[RAYN_PERSONA_TAXONOMY_ID])); + } + if (raynUserData.length > 0) { deepSetValue(raynOrtb2, 'user.data', raynUserData); } @@ -163,8 +196,8 @@ function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) { segments[checksum] || (segments[4] && integrationConfig.iabAudienceCategories.v1_1.enabled && !integrationConfig.iabContentCategories.v2_2.enabled && - !integrationConfig.iabContentCategories.v3_0.enabled - ) + !integrationConfig.iabContentCategories.v3_0.enabled) || + segments[RAYN_PERSONA_TAXONOMY_ID] )) { logMessage(LOG_PREFIX, `Segtax data from localStorage: ${JSON.stringify(segments)}`); setSegmentsAsBidderOrtb2(reqBidsConfigObj, bidders, integrationConfig, segments, checksum); diff --git a/modules/relaidoBidAdapter.js b/modules/relaidoBidAdapter.js index a180d04cc71..69f9be8d107 100644 --- a/modules/relaidoBidAdapter.js +++ b/modules/relaidoBidAdapter.js @@ -19,7 +19,7 @@ import { isSlotMatchingAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; const BIDDER_CODE = 'relaido'; const BIDDER_DOMAIN = 'api.relaido.jp'; -const ADAPTER_VERSION = '1.2.0'; +const ADAPTER_VERSION = '1.2.1'; const DEFAULT_TTL = 300; const UUID_KEY = 'relaido_uuid'; @@ -270,6 +270,7 @@ function outstreamRender(bid) { height: bid.height, vastXml: bid.vastXml, mediaType: bid.mediaType, + placementId: bid.placementId, }); }); } diff --git a/modules/relevatehealthBidAdapter.js b/modules/relevatehealthBidAdapter.js new file mode 100644 index 00000000000..e010f3d8fcd --- /dev/null +++ b/modules/relevatehealthBidAdapter.js @@ -0,0 +1,161 @@ +import { + registerBidder +} from '../src/adapters/bidderFactory.js'; +import { + BANNER +} from '../src/mediaTypes.js'; +import { + deepAccess, + generateUUID, + isArray, + logError +} from '../src/utils.js'; +const BIDDER_CODE = 'relevatehealth'; +const ENDPOINT_URL = 'https://rtb.relevate.health/prebid/relevate'; + +function buildRequests(bidRequests, bidderRequest) { + const requests = []; + // Loop through each bid request + bidRequests.forEach(bid => { + // Construct the bid request object + const request = { + id: generateUUID(), + placementId: bid.params.placement_id, + imp: [{ + id: bid.bidId, + banner: getBanner(bid), + bidfloor: getFloor(bid) + }], + site: getSite(bidderRequest), + user: buildUser(bid) + }; + // Get uspConsent from bidderRequest + if (bidderRequest && bidderRequest.uspConsent) { + request.us_privacy = bidderRequest.uspConsent; + } + // Get GPP Consent from bidderRequest + if (bidderRequest?.gppConsent?.gppString) { + request.gpp = bidderRequest.gppConsent.gppString; + request.gpp_sid = bidderRequest.gppConsent.applicableSections; + } else if (bidderRequest?.ortb2?.regs?.gpp) { + request.gpp = bidderRequest.ortb2.regs.gpp; + request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; + } + // Get coppa compliance from bidderRequest + if (bidderRequest?.ortb2?.regs?.coppa) { + request.coppa = 1; + } + // Push the constructed bid request to the requests array + requests.push(request); + }); + // Return the array of bid requests + return { + method: 'POST', + url: ENDPOINT_URL, + data: JSON.stringify(requests), + options: { + contentType: 'application/json', + } + }; +} +// Format the response as per the standards +function interpretResponse(bidResponse, bidRequest) { + let resp = []; + if (bidResponse && bidResponse.body) { + try { + let bids = bidResponse.body.seatbid && bidResponse.body.seatbid[0] ? bidResponse.body.seatbid[0].bid : []; + if (bids) { + bids.forEach(bidObj => { + let newBid = formatResponse(bidObj); + newBid.mediaType = BANNER; + resp.push(newBid); + }); + } + } catch (err) { + logError(err); + } + } + return resp; +} +// Function to check if Bid is valid +function isBidRequestValid(bid) { + return !!(bid.params.placement_id && bid.params.user_id); +} +// Function to get banner details +function getBanner(bid) { + if (deepAccess(bid, 'mediaTypes.banner')) { + // Fetch width and height from MediaTypes object, if not provided in bid params + if (deepAccess(bid, 'mediaTypes.banner.sizes') && !bid.params.height && !bid.params.width) { + let sizes = deepAccess(bid, 'mediaTypes.banner.sizes'); + if (isArray(sizes) && sizes.length > 0) { + return { + h: sizes[0][1], + w: sizes[0][0] + }; + } + } else { + return { + h: bid.params.height, + w: bid.params.width + }; + } + } +} +// Function to get bid_floor +function getFloor(bid) { + if (bid.params && bid.params.bid_floor) { + return bid.params.bid_floor; + } else { + return 0; + } +} +// Function to get site details +function getSite(bidderRequest) { + let site = {}; + if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.page) { + site.name = bidderRequest.refererInfo.domain; + } else { + site.name = ''; + } + return site; +} +// Function to format response +function formatResponse(bid) { + return { + requestId: bid && bid.impid ? bid.impid : undefined, + cpm: bid && bid.price ? bid.price : 0.0, + width: bid && bid.w ? bid.w : 0, + height: bid && bid.h ? bid.h : 0, + ad: bid && bid.adm ? bid.adm : '', + meta: { + advertiserDomains: bid && bid.adomain ? bid.adomain : [] + }, + creativeId: bid && bid.crid ? bid.crid : undefined, + netRevenue: false, + currency: bid && bid.cur ? bid.cur : 'USD', + ttl: 300, + dealId: bid && bid.dealId ? bid.dealId : undefined + }; +} +// Function to build the user object +function buildUser(bid) { + if (bid && bid.params) { + return { + id: bid.params.user_id && typeof bid.params.user_id == 'string' ? bid.params.user_id : '', + // TODO: commented out because of rule violations + buyeruid: '', // localStorage.getItem('adx_profile_guid') ? localStorage.getItem('adx_profile_guid') : '', + keywords: bid.params.keywords && typeof bid.params.keywords == 'string' ? bid.params.keywords : '', + customdata: bid.params.customdata && typeof bid.params.customdata == 'string' ? bid.params.customdata : '' + }; + } +} +// Export const spec +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: BANNER, + isBidRequestValid, + buildRequests, + interpretResponse +} + +registerBidder(spec); diff --git a/modules/relevatehealthBidAdapter.md b/modules/relevatehealthBidAdapter.md new file mode 100644 index 00000000000..432e4fcec02 --- /dev/null +++ b/modules/relevatehealthBidAdapter.md @@ -0,0 +1,40 @@ +# Overview + +``` +Module Name: relevatehealth Bidder Adapter +Module Type: Bidder Adapter +Maintainer: marketingops@relevatehealth.com +``` + +# Description + +relevatehealth currently supports the BANNER type ads through prebid js + +Module that connects to relevatehealth's demand sources. + +# Banner Test Request +``` + var adUnits = [ + { + code: 'banner-ad', + mediaTypes: { + banner: { + sizes: [[160, 600]], + } + } + bids: [ + { + bidder: 'relevatehealth', + params: { + placement_id: 110011, // Required parameter + user_id: '1111111' // Required parameter + width: 160, // Optional parameter + height: 600, // Optional parameter + domain: '', // Optional parameter + bid_floor: 0.5 // Optional parameter + } + } + ] + } + ]; +``` diff --git a/modules/richaudienceBidAdapter.js b/modules/richaudienceBidAdapter.js old mode 100755 new mode 100644 index b63e31266fb..c6a3a5427bd --- a/modules/richaudienceBidAdapter.js +++ b/modules/richaudienceBidAdapter.js @@ -37,7 +37,6 @@ export const spec = { pid: bid.params.pid, supplyType: bid.params.supplyType, currencyCode: config.getConfig('currency.adServerCurrency'), - // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 auctionId: bid.auctionId, bidId: bid.bidId, BidRequestsCount: bid.bidRequestsCount, @@ -45,7 +44,6 @@ export const spec = { bidderRequestId: bid.bidderRequestId, tagId: bid.adUnitCode, sizes: raiGetSizes(bid), - // TODO: is 'page' the right value here? referer: (typeof bidderRequest.refererInfo.page != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.page) : null), numIframes: (typeof bidderRequest.refererInfo.numIframes != 'undefined' ? bidderRequest.refererInfo.numIframes : null), transactionId: bid.ortb2Imp?.ext?.tid, @@ -60,7 +58,6 @@ export const spec = { gpid: raiSetPbAdSlot(bid) }; - // TODO: is 'page' the right value here? REFERER = (typeof bidderRequest.refererInfo.page != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.page) : null) payload.gdpr_consent = ''; @@ -154,7 +151,7 @@ export const spec = { * * @param {syncOptions} Publisher prebid configuration * @param {serverResponses} Response from the server - * @param {gdprConsent} GPDR consent object + * @param {gdprConsent} GDPR consent object * @returns {Array} */ getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent, gppConsent) { diff --git a/modules/richaudienceBidAdapter.md b/modules/richaudienceBidAdapter.md index f888117b166..35298b8421d 100644 --- a/modules/richaudienceBidAdapter.md +++ b/modules/richaudienceBidAdapter.md @@ -3,7 +3,7 @@ ``` Module Name: Rich Audience Bidder Adapter Module Type: Bidder Adapter -Maintainer: cert@richaudience.com +Maintainer: integrations@richaudience.com ``` # Description diff --git a/modules/rasBidAdapter.js b/modules/ringieraxelspringerBidAdapter.js similarity index 89% rename from modules/rasBidAdapter.js rename to modules/ringieraxelspringerBidAdapter.js index 74abd0fb4a1..1fd6e327b9b 100644 --- a/modules/rasBidAdapter.js +++ b/modules/ringieraxelspringerBidAdapter.js @@ -8,7 +8,7 @@ import { import { getAllOrtbKeywords } from '../libraries/keywords/keywords.js'; import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; -const BIDDER_CODE = 'ras'; +const BIDDER_CODE = 'ringieraxelspringer'; const VERSION = '1.0'; const getEndpoint = (network) => { @@ -106,38 +106,66 @@ function parseOrtbResponse(ad) { return false; } - const { image, Image, title, url, Headline, Thirdpartyclicktracker, imp, impression, impression1, impressionJs1 } = ad.data.fields; + const { image, Image, title, url, Headline, Thirdpartyclicktracker, thirdPartyClickTracker2, imp, impression, impression1, impressionJs1, partner_logo: partnerLogo, adInfo, body } = ad.data.fields; const { dsaurl, height, width, adclick } = ad.data.meta; const emsLink = ad.ems_link; const link = adclick + (url || Thirdpartyclicktracker); const eventtrackers = prepareEventtrackers(emsLink, imp, impression, impression1, impressionJs1); + const clicktrackers = thirdPartyClickTracker2 ? [thirdPartyClickTracker2] : []; + const ortb = { ver: '1.2', assets: [ { - id: 2, + id: 0, + data: { + value: body || '', + type: 2 + }, + }, + { + id: 1, + data: { + value: adInfo || '', + // Body2 type + type: 10 + }, + }, + { + id: 3, img: { - url: image || Image || '', + type: 1, + url: partnerLogo || '', w: width, h: height } }, { id: 4, - title: { - text: title || Headline || '' + img: { + type: 3, + url: image || Image || '', + w: width, + h: height } }, { - id: 3, + id: 5, data: { value: deepAccess(ad, 'data.meta.advertiser_name', null), type: 1 } - } + }, + { + id: 6, + title: { + text: title || Headline || '' + } + }, ], link: { - url: link + url: link, + clicktrackers }, eventtrackers }; @@ -154,7 +182,7 @@ function parseNativeResponse(ad) { return false; } - const { image, Image, title, leadtext, url, Calltoaction, Body, Headline, Thirdpartyclicktracker } = ad.data.fields; + const { image, Image, title, leadtext, url, Calltoaction, Body, Headline, Thirdpartyclicktracker, adInfo, partner_logo: partnerLogo } = ad.data.fields; const { dsaurl, height, width, adclick } = ad.data.meta; const link = adclick + (url || Thirdpartyclicktracker); const nativeResponse = { @@ -165,10 +193,15 @@ function parseNativeResponse(ad) { width, height }, - + icon: { + url: partnerLogo || '', + width, + height + }, clickUrl: link, cta: Calltoaction || '', body: leadtext || Body || '', + body2: adInfo || '', sponsoredBy: deepAccess(ad, 'data.meta.advertiser_name', null) || '', ortb: parseOrtbResponse(ad) }; @@ -192,7 +225,7 @@ const buildBid = (ad, mediaType) => { creativeId: ad.adid ? parseInt(ad.adid.split(',')[2], 10) : 0, netRevenue: true, currency: ad.currency || 'USD', - dealId: null, + dealId: ad.prebid_deal || null, actgMatch: ad.actg_match || 0, meta: { mediaType: BANNER }, mediaType: BANNER, @@ -243,6 +276,8 @@ const getSlots = (bidRequests) => { queryString += `&cre_format${i}=native`; } + queryString += `&kvhb_format${i}=${creFormat === 'native' ? 'native' : 'banner'}`; + if (sizes) { queryString += `&iusizes${i}=${encodeURIComponent(sizes)}`; } @@ -329,7 +364,7 @@ export const spec = { const slotsQuery = getSlots(bidRequests); const contextQuery = getContextParams(bidRequests, bidderRequest); const gdprQuery = getGdprParams(bidderRequest); - const fledgeEligible = Boolean(bidderRequest && bidderRequest.fledgeEnabled); + const fledgeEligible = Boolean(bidderRequest?.paapi?.enabled); const network = bidRequests[0].params.network; const bidIds = bidRequests.map((bid) => ({ slot: bid.params.slot, @@ -357,7 +392,7 @@ export const spec = { if (fledgeAuctionConfigs) { // Return a tuple of bids and auctionConfigs. It is possible that bids could be null. - return {bids, fledgeAuctionConfigs}; + return {bids, paapi: fledgeAuctionConfigs}; } else { return bids; } diff --git a/modules/rasBidAdapter.md b/modules/ringieraxelspringerBidAdapter.md similarity index 88% rename from modules/rasBidAdapter.md rename to modules/ringieraxelspringerBidAdapter.md index cf169fedb63..b3a716f9f56 100644 --- a/modules/rasBidAdapter.md +++ b/modules/ringieraxelspringerBidAdapter.md @@ -21,7 +21,7 @@ var adUnits = [{ } }, bids: [{ - bidder: 'ras', + bidder: 'ringieraxelspringer', params: { network: '4178463', site: 'test', @@ -36,11 +36,11 @@ var adUnits = [{ | Name | Scope | Type | Description | Example | |------------------------------|----------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------| -| network | required | String | Specific identifier provided by RAS | `"4178463"` | -| site | required | String | Specific identifier name (case-insensitive) that is associated with this ad unit and provided by RAS | `"example_com"` | +| network | required | String | Specific identifier provided by Ringier Axel Springer | `"4178463"` | +| site | required | String | Specific identifier name (case-insensitive) that is associated with this ad unit and provided by Ringier Axel Springer | `"example_com"` | | area | required | String | Ad unit category name; only case-insensitive alphanumeric with underscores and hyphens are allowed | `"sport"` | -| slot | required | String | Ad unit placement name (case-insensitive) provided by RAS | `"slot"` | -| slotSequence | optional | Number | Ad unit sequence position provided by RAS | `1` | +| slot | required | String | Ad unit placement name (case-insensitive) provided by Ringier Axel Springer | `"slot"` | +| slotSequence | optional | Number | Ad unit sequence position provided by Ringier Axel Springer | `1` | | pageContext | optional | Object | Web page context data | `{}` | | pageContext.dr | optional | String | Document referrer URL address | `"https://example.com/"` | | pageContext.du | optional | String | Document URL address | `"https://example.com/sport/football/article.html?id=932016a5-02fc-4d5c-b643-fafc2f270f06"` | diff --git a/modules/riseBidAdapter.js b/modules/riseBidAdapter.js index 72170706fc0..236c048982a 100644 --- a/modules/riseBidAdapter.js +++ b/modules/riseBidAdapter.js @@ -2,18 +2,17 @@ import { logWarn, logInfo, isArray, - isFn, deepAccess, - isEmpty, - contains, - timestamp, triggerPixel, - isInteger, - getBidIdParameter } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { + getEndpoint, + generateBidsParams, + generateGeneralParams, + buildBidResponse, +} from '../libraries/riseUtils/index.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'rise'; @@ -21,15 +20,11 @@ const ADAPTER_VERSION = '6.0.0'; const TTL = 360; const DEFAULT_CURRENCY = 'USD'; const DEFAULT_GVLID = 1043; -const DEFAULT_SELLER_ENDPOINT = 'https://hb.yellowblue.io/'; +const BASE_URL = 'https://hb.yellowblue.io/'; const MODES = { PRODUCTION: 'hb-multi', TEST: 'hb-multi-test' -} -const SUPPORTED_SYNC_METHODS = { - IFRAME: 'iframe', - PIXEL: 'pixel' -} +}; export const spec = { code: BIDDER_CODE, @@ -59,48 +54,23 @@ export const spec = { // use data from the first bid, to create the general params for all bids const generalObject = validBidRequests[0]; const testMode = generalObject.params.testMode; - const rtbDomain = generalObject.params.rtbDomain; + const rtbDomain = generalObject.params.rtbDomain || BASE_URL; combinedRequestsObject.params = generateGeneralParams(generalObject, bidderRequest); combinedRequestsObject.bids = generateBidsParams(validBidRequests, bidderRequest); return { method: 'POST', - url: getEndpoint(testMode, rtbDomain), + url: getEndpoint(testMode, rtbDomain, MODES), data: combinedRequestsObject } }, - interpretResponse: function ({body}) { + interpretResponse: function ({ body }) { const bidResponses = []; if (body.bids) { body.bids.forEach(adUnit => { - const bidResponse = { - requestId: adUnit.requestId, - cpm: adUnit.cpm, - currency: adUnit.currency || DEFAULT_CURRENCY, - width: adUnit.width, - height: adUnit.height, - ttl: adUnit.ttl || TTL, - creativeId: adUnit.creativeId, - netRevenue: adUnit.netRevenue || true, - nurl: adUnit.nurl, - mediaType: adUnit.mediaType, - meta: { - mediaType: adUnit.mediaType - } - }; - - if (adUnit.mediaType === VIDEO) { - bidResponse.vastXml = adUnit.vastXml; - } else if (adUnit.mediaType === BANNER) { - bidResponse.ad = adUnit.ad; - } - - if (adUnit.adomain && adUnit.adomain.length) { - bidResponse.meta.advertiserDomains = adUnit.adomain; - } - + const bidResponse = buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER); bidResponses.push(bidResponse); }); } @@ -110,20 +80,20 @@ export const spec = { getUserSyncs: function (syncOptions, serverResponses) { const syncs = []; for (const response of serverResponses) { - if (syncOptions.iframeEnabled && response.body.params.userSyncURL) { + if (syncOptions.iframeEnabled && deepAccess(response, 'body.params.userSyncURL')) { syncs.push({ type: 'iframe', - url: response.body.params.userSyncURL + url: deepAccess(response, 'body.params.userSyncURL') }); } - if (syncOptions.pixelEnabled && isArray(response.body.params.userSyncPixels)) { + if (syncOptions.pixelEnabled && isArray(deepAccess(response, 'body.params.userSyncPixels'))) { const pixels = response.body.params.userSyncPixels.map(pixel => { return { type: 'image', url: pixel } - }) - syncs.push(...pixels) + }); + syncs.push(...pixels); } } return syncs; @@ -141,354 +111,3 @@ export const spec = { }; registerBidder(spec); - -/** - * Get floor price - * @param bid {bid} - * @param mediaType {string} - * @returns {Number} - */ -function getFloor(bid, mediaType) { - if (!isFn(bid.getFloor)) { - return 0; - } - let floorResult = bid.getFloor({ - currency: DEFAULT_CURRENCY, - mediaType: mediaType, - size: '*' - }); - return floorResult.currency === DEFAULT_CURRENCY && floorResult.floor ? floorResult.floor : 0; -} - -/** - * Get the the ad sizes array from the bid - * @param bid {bid} - * @returns {Array} - */ -function getSizesArray(bid, mediaType) { - let sizesArray = [] - - if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) { - sizesArray = bid.mediaTypes[mediaType].sizes; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizesArray = bid.sizes; - } - - return sizesArray; -} - -/** - * Get schain string value - * @param schainObject {Object} - * @returns {string} - */ -function getSupplyChain(schainObject) { - if (isEmpty(schainObject)) { - return ''; - } - let scStr = `${schainObject.ver},${schainObject.complete}`; - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - return scStr; -} - -/** - * Get encoded node value - * @param val {string} - * @returns {string} - */ -function getEncodedValIfNotEmpty(val) { - return !isEmpty(val) ? encodeURIComponent(val) : ''; -} - -/** - * Get preferred user-sync method based on publisher configuration - * @param bidderCode {string} - * @returns {string} - */ -function getAllowedSyncMethod(filterSettings, bidderCode) { - const iframeConfigsToCheck = ['all', 'iframe']; - const pixelConfigToCheck = 'image'; - if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { - return SUPPORTED_SYNC_METHODS.IFRAME; - } - if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { - return SUPPORTED_SYNC_METHODS.PIXEL; - } -} - -/** - * Check if sync rule is supported - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - const isInclude = syncRule.filter === 'include'; - const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - return isInclude && contains(bidders, bidderCode); -} - -/** - * Get the seller endpoint - * @param testMode {boolean} - * @param rtbDomain {string} - * @returns {string} - */ -function getEndpoint(testMode, rtbDomain) { - const SELLER_ENDPOINT = rtbDomain ? `https://${rtbDomain}/` : DEFAULT_SELLER_ENDPOINT; - return testMode - ? SELLER_ENDPOINT + MODES.TEST - : SELLER_ENDPOINT + MODES.PRODUCTION; -} - -/** - * get device type - * @param uad {ua} - * @returns {string} - */ -function getDeviceType(ua) { - if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i - .test(ua.toLowerCase())) { - return '5'; - } - if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i - .test(ua.toLowerCase())) { - return '4'; - } - if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i - .test(ua.toLowerCase())) { - return '3'; - } - return '1'; -} - -function generateBidsParams(validBidRequests, bidderRequest) { - const bidsArray = []; - - if (validBidRequests.length) { - validBidRequests.forEach(bid => { - bidsArray.push(generateBidParameters(bid, bidderRequest)); - }); - } - - return bidsArray; -} - -/** - * Generate bid specific parameters - * @param {bid} bid - * @param {bidderRequest} bidderRequest - * @returns {Object} bid specific params object - */ -function generateBidParameters(bid, bidderRequest) { - const {params} = bid; - const mediaType = isBanner(bid) ? BANNER : VIDEO; - const sizesArray = getSizesArray(bid, mediaType); - // fix floor price in case of NAN - if (isNaN(params.floorPrice)) { - params.floorPrice = 0; - } - - const bidObject = { - mediaType, - adUnitCode: getBidIdParameter('adUnitCode', bid), - sizes: sizesArray, - floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice), - bidId: getBidIdParameter('bidId', bid), - bidderRequestId: getBidIdParameter('bidderRequestId', bid), - loop: getBidIdParameter('bidderRequestsCount', bid), - transactionId: bid.ortb2Imp?.ext?.tid, - coppa: 0, - }; - - const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`); - if (pos) { - bidObject.pos = pos; - } - - const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`); - if (gpid) { - bidObject.gpid = gpid; - } - - const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`); - if (placementId) { - bidObject.placementId = placementId; - } - - const mimes = deepAccess(bid, `mediaTypes.${mediaType}.mimes`); - if (mimes) { - bidObject.mimes = mimes; - } - - const api = deepAccess(bid, `mediaTypes.${mediaType}.api`); - if (api) { - bidObject.api = api; - } - - const sua = deepAccess(bid, `ortb2.device.sua`); - if (sua) { - bidObject.sua = sua; - } - - const coppa = deepAccess(bid, `ortb2.regs.coppa`) - if (coppa) { - bidObject.coppa = 1; - } - - if (mediaType === VIDEO) { - const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`); - let playbackMethodValue; - - // verify playbackMethod is of type integer array, or integer only. - if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) { - // only the first playbackMethod in the array will be used, according to OpenRTB 2.5 recommendation - playbackMethodValue = playbackMethod[0]; - } else if (isInteger(playbackMethod)) { - playbackMethodValue = playbackMethod; - } - - if (playbackMethodValue) { - bidObject.playbackMethod = playbackMethodValue; - } - - const placement = deepAccess(bid, `mediaTypes.video.placement`); - if (placement) { - bidObject.placement = placement; - } - - const minDuration = deepAccess(bid, `mediaTypes.video.minduration`); - if (minDuration) { - bidObject.minDuration = minDuration; - } - - const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`); - if (maxDuration) { - bidObject.maxDuration = maxDuration; - } - - const skip = deepAccess(bid, `mediaTypes.video.skip`); - if (skip) { - bidObject.skip = skip; - } - - const linearity = deepAccess(bid, `mediaTypes.video.linearity`); - if (linearity) { - bidObject.linearity = linearity; - } - - const protocols = deepAccess(bid, `mediaTypes.video.protocols`); - if (protocols) { - bidObject.protocols = protocols; - } - - const plcmt = deepAccess(bid, `mediaTypes.video.plcmt`); - if (plcmt) { - bidObject.plcmt = plcmt; - } - } - - return bidObject; -} - -function isBanner(bid) { - return bid.mediaTypes && bid.mediaTypes.banner; -} - -/** - * Generate params that are common between all bids - * @param {single bid object} generalObject - * @param {bidderRequest} bidderRequest - * @returns {object} the common params object - */ -function generateGeneralParams(generalObject, bidderRequest) { - const domain = window.location.hostname; - const {syncEnabled, filterSettings} = config.getConfig('userSync') || {}; - const {bidderCode} = bidderRequest; - const generalBidParams = generalObject.params; - const timeout = bidderRequest.timeout; - - // these params are snake_case instead of camelCase to allow backwards compatability on the server. - // in the future, these will be converted to camelCase to match our convention. - const generalParams = { - wrapper_type: 'prebidjs', - wrapper_vendor: '$$PREBID_GLOBAL$$', - wrapper_version: '$prebid.version$', - adapter_version: ADAPTER_VERSION, - auction_start: timestamp(), - publisher_id: generalBidParams.org, - publisher_name: domain, - site_domain: domain, - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, - device_type: getDeviceType(navigator.userAgent), - ua: navigator.userAgent, - is_wrapper: !!generalBidParams.isWrapper, - session_id: generalBidParams.sessionId || getBidIdParameter('bidderRequestId', generalObject), - tmax: timeout - }; - - const userIdsParam = getBidIdParameter('userId', generalObject); - if (userIdsParam) { - generalParams.userIds = JSON.stringify(userIdsParam); - } - - const ortb2Metadata = bidderRequest.ortb2 || {}; - if (ortb2Metadata.site) { - generalParams.site_metadata = JSON.stringify(ortb2Metadata.site); - } - if (ortb2Metadata.user) { - generalParams.user_metadata = JSON.stringify(ortb2Metadata.user); - } - - if (syncEnabled) { - const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); - if (allowedSyncMethod) { - generalParams.cs_method = allowedSyncMethod; - } - } - - if (bidderRequest.uspConsent) { - generalParams.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies; - generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - - if (bidderRequest && bidderRequest.gppConsent) { - generalParams.gpp = bidderRequest.gppConsent.gppString; - generalParams.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - generalParams.gpp = bidderRequest.ortb2.regs.gpp; - generalParams.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - if (generalBidParams.ifa) { - generalParams.ifa = generalBidParams.ifa; - } - - if (generalObject.schain) { - generalParams.schain = getSupplyChain(generalObject.schain); - } - - if (bidderRequest && bidderRequest.refererInfo) { - // TODO: is 'ref' the right value here? - generalParams.referrer = deepAccess(bidderRequest, 'refererInfo.ref'); - // TODO: does the fallback make sense here? - generalParams.page_url = deepAccess(bidderRequest, 'refererInfo.page') || deepAccess(window, 'location.href'); - } - - return generalParams; -} diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js index 1cd97696770..7e2a7da3b61 100644 --- a/modules/rtbhouseBidAdapter.js +++ b/modules/rtbhouseBidAdapter.js @@ -114,7 +114,7 @@ export const spec = { let computedEndpointUrl = ENDPOINT_URL; - if (bidderRequest.fledgeEnabled) { + if (bidderRequest.paapi?.enabled) { const fledgeConfig = config.getConfig('fledgeConfig') || { seller: FLEDGE_SELLER_URL, decisionLogicUrl: FLEDGE_DECISION_LOGIC_URL, @@ -209,7 +209,7 @@ export const spec = { logInfo('Response with FLEDGE:', { bids, fledgeAuctionConfigs }); return { bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, } } return bids; @@ -250,7 +250,7 @@ function mapImpression(slot, bidderRequest) { imp.bidfloor = bidfloor; } - if (bidderRequest.fledgeEnabled) { + if (bidderRequest.paapi?.enabled) { imp.ext = imp.ext || {}; imp.ext.ae = slot?.ortb2Imp?.ext?.ae } else { diff --git a/modules/rtbhouseBidAdapter.md b/modules/rtbhouseBidAdapter.md index 338ba6b4df4..7fcae1299b2 100644 --- a/modules/rtbhouseBidAdapter.md +++ b/modules/rtbhouseBidAdapter.md @@ -69,7 +69,7 @@ Please reach out to pmp@rtbhouse.com to receive your own # Protected Audience API (FLEDGE) support There’s an option to receive demand for Protected Audience API (FLEDGE/PAAPI) ads using RTB House bid adapter. -Prebid’s [fledgeForGpt](https://docs.prebid.org/dev-docs/modules/fledgeForGpt.html) +Prebid’s [paapiForGpt](https://docs.prebid.org/dev-docs/modules/paapiForGpt.html) module and Google Ad Manager is currently required. The following steps should be taken to setup Protected Audience for RTB House: @@ -77,15 +77,15 @@ The following steps should be taken to setup Protected Audience for RTB House: 1. Reach out to your RTB House representative for setup coordination. 2. Build and enable FLEDGE module as described in -[fledgeForGpt](https://docs.prebid.org/dev-docs/modules/fledgeForGpt.html) +[paapiForGpt](https://docs.prebid.org/dev-docs/modules/paapiForGpt.html) module documentation. a. Make sure to enable RTB House bidder to participate in FLEDGE. If there are any other bidders to be allowed for that, add them to the **bidders** array: ```javascript - pbjs.setBidderConfig({ - bidders: ["rtbhouse"], - config: { - fledgeEnabled: true + pbjs.setConfig({ + paapi: { + bidders: ["rtbhouse"], + enabled: true } }); ``` @@ -93,15 +93,15 @@ module documentation. b. If you as a publisher have your own [decisionLogicUrl](https://github.com/WICG/turtledove/blob/main/FLEDGE.md#21-initiating-an-on-device-auction) you may utilize it by setting up a dedicated `fledgeConfig` object: ```javascript - pbjs.setBidderConfig({ - bidders: ["rtbhouse"], - config: { - fledgeEnabled: true, - fledgeConfig: { - seller: 'https://seller.domain', - decisionLogicUrl: 'https://seller.domain/decisionLogicFile.js', - sellerTimeout: 100 - } + pbjs.setConfig({ + paapi: { + bidders: ["rtbhouse"], + enabled: true + }, + fledgeConfig: { + seller: 'https://seller.domain', + decisionLogicUrl: 'https://seller.domain/decisionLogicFile.js', + sellerTimeout: 100 } }); ``` diff --git a/modules/rtdModule/index.js b/modules/rtdModule/index.js index 0c654fc28b0..18736c6b0ec 100644 --- a/modules/rtdModule/index.js +++ b/modules/rtdModule/index.js @@ -188,10 +188,12 @@ let _dataProviders = []; let _userConsent; /** - * Register a RTD submodule. + * Register a Real-Time Data (RTD) submodule. * - * @param {RtdSubmodule} submodule - * @returns {function()} a de-registration function that will unregister the module when called. + * @param {Object} submodule The RTD submodule to register. + * @param {string} submodule.name The name of the RTD submodule. + * @param {number} [submodule.gvlid] The Global Vendor List ID (GVLID) of the RTD submodule. + * @returns {function(): void} A de-registration function that will unregister the module when called. */ export function attachRealTimeDataProvider(submodule) { registeredSubModules.push(submodule); diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 9e47807bdc0..64bcdf78399 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -736,7 +736,7 @@ export const spec = { }); if (fledgeAuctionConfigs) { - return { bids, fledgeAuctionConfigs }; + return { bids, paapi: fledgeAuctionConfigs }; } else { return bids; } diff --git a/modules/seedingAllianceBidAdapter.js b/modules/seedingAllianceBidAdapter.js index e287ea7ff78..f998df27d5c 100755 --- a/modules/seedingAllianceBidAdapter.js +++ b/modules/seedingAllianceBidAdapter.js @@ -3,17 +3,21 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {_map, deepSetValue, isArray, isEmpty, replaceAuctionPrice} from '../src/utils.js'; +import {_map, generateUUID, deepSetValue, isArray, isEmpty, replaceAuctionPrice} from '../src/utils.js'; import {config} from '../src/config.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import {getStorageManager} from '../src/storageManager.js'; const GVL_ID = 371; const BIDDER_CODE = 'seedingAlliance'; const DEFAULT_CUR = 'EUR'; const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=pb'; +const NATIVENDO_KEY = 'nativendo_id'; const NATIVE_ASSET_IDS = { 0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon' }; +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); + const NATIVE_PARAMS = { title: { id: 0, name: 'title' }, body: { id: 1, name: 'data', type: 2 }, @@ -37,6 +41,7 @@ export const spec = { validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); let url = bidderRequest.refererInfo.page; + let eids = getEids(validBidRequests[0]); const imps = validBidRequests.map((bidRequest, id) => { const imp = { @@ -130,11 +135,14 @@ export const spec = { deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString); deepSetValue(request, 'regs.ext.gdpr', (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean' && bidderRequest.gdprConsent.gdprApplies) ? 1 : 0); + deepSetValue(request, 'user.ext.eids', eids); } + let endpoint = config.getConfig('seedingAlliance.endpoint') || ENDPOINT_URL; + return { method: 'POST', - url: config.getConfig('seedingAlliance.endpoint') || ENDPOINT_URL, + url: endpoint, data: JSON.stringify(request), bidRequests: validBidRequests }; @@ -191,6 +199,45 @@ export const spec = { } }; +const getNativendoID = () => { + let nativendoID = storage.localStorageIsEnabled() && + storage.getDataFromLocalStorage(NATIVENDO_KEY); + + if (!nativendoID) { + if (storage.localStorageIsEnabled()) { + nativendoID = generateUUID(); + storage.setDataInLocalStorage(NATIVENDO_KEY, nativendoID); + } + } + + return nativendoID; +} + +const getEids = (bidRequest) => { + const eids = []; + const nativendoID = getNativendoID(); + + if (nativendoID) { + const nativendoUserEid = { + source: 'nativendo.de', + uids: [ + { + id: nativendoID, + atype: 1 + } + ] + }; + + eids.push(nativendoUserEid); + } + + if (bidRequest.userIdAsEids) { + eids.push(bidRequest.userIdAsEids); + } + + return eids; +} + function transformSizes(requestSizes) { if (!isArray(requestSizes)) { return []; diff --git a/modules/seedtagBidAdapter.js b/modules/seedtagBidAdapter.js index 284e62e70fe..f3bcd70c714 100644 --- a/modules/seedtagBidAdapter.js +++ b/modules/seedtagBidAdapter.js @@ -119,6 +119,7 @@ function buildBidRequest(validBidRequest) { const bidRequest = { id: validBidRequest.bidId, transactionId: validBidRequest.ortb2Imp?.ext?.tid, + gpid: validBidRequest.ortb2Imp?.ext?.gpid, sizes: validBidRequest.sizes, supplyTypes: mediaTypes, adUnitId: params.adUnitId, @@ -332,6 +333,10 @@ export const spec = { payload.badv = bidderRequest.ortb2?.badv } + if (bidderRequest.ortb2?.device?.sua) { + payload.sua = bidderRequest.ortb2.device.sua + } + const payloadString = JSON.stringify(payload); return { diff --git a/modules/setupadBidAdapter.js b/modules/setupadBidAdapter.js index 55677d51c56..4ee6dd7c085 100644 --- a/modules/setupadBidAdapter.js +++ b/modules/setupadBidAdapter.js @@ -1,26 +1,54 @@ import { _each, - createTrackPixelHtml, - deepAccess, isStr, getBidIdParameter, triggerPixel, logWarn, + deepSetValue, } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const BIDDER_CODE = 'setupad'; const ENDPOINT = 'https://prebid.setupad.io/openrtb2/auction'; const SYNC_ENDPOINT = 'https://cookie.stpd.cloud/sync?'; -const REPORT_ENDPOINT = 'https://adapter-analytics.setupad.io/api/adapter-analytics'; +const REPORT_ENDPOINT = 'https://adapter-analytics.setupad.io/api/adapter-analytics?'; const GVLID = 1241; const TIME_TO_LIVE = 360; -const biddersCreativeIds = {}; - -function getEids(bidRequest) { - if (deepAccess(bidRequest, 'userIdAsEids')) return bidRequest.userIdAsEids; -} +export const biddersCreativeIds = {}; // export only for tests +const NET_REVENUE = true; +const TEST_REQUEST = 0; // used only for testing + +const converter = ortbConverter({ + context: { + netRevenue: NET_REVENUE, + ttl: TIME_TO_LIVE, + }, + imp(buildImp, bidRequest, context) { + const imp = buildImp(bidRequest, context); + deepSetValue( + imp, + 'ext.prebid.storedrequest.id', + getBidIdParameter('placement_id', bidRequest.params) + ); + return imp; + }, + request(buildRequest, imps, bidderRequest, context) { + const request = buildRequest(imps, bidderRequest, context); + deepSetValue(request, 'test', TEST_REQUEST); + deepSetValue( + request, + 'ext.prebid.storedrequest.id', + getBidIdParameter( + 'account_id', + bidderRequest.bids.find((bid) => bid.hasOwnProperty('params')).params + ) + ); + deepSetValue(request, 'setupad', 'adapter'); + return request; + }, +}); export const spec = { code: BIDDER_CODE, @@ -28,101 +56,26 @@ export const spec = { gvlid: GVLID, isBidRequestValid: function (bid) { - return !!(bid.params.placement_id && isStr(bid.params.placement_id)); + return !!( + bid.params.placement_id && + isStr(bid.params.placement_id) && + bid.params.account_id && + isStr(bid.params.account_id) + ); }, buildRequests: function (validBidRequests, bidderRequest) { - const requests = []; - - _each(validBidRequests, function (bid) { - const id = getBidIdParameter('placement_id', bid.params); - const accountId = getBidIdParameter('account_id', bid.params); - const auctionId = bid.auctionId; - const bidId = bid.bidId; - const eids = getEids(bid) || undefined; - let sizes = bid.sizes; - if (sizes && !Array.isArray(sizes[0])) sizes = [sizes]; - - const site = { - page: bidderRequest?.refererInfo?.page, - ref: bidderRequest?.refererInfo?.ref, - domain: bidderRequest?.refererInfo?.domain, - }; - const device = { - w: bidderRequest?.ortb2?.device?.w, - h: bidderRequest?.ortb2?.device?.h, - }; - - const payload = { - id: bid?.bidderRequestId, - ext: { - prebid: { - storedrequest: { - id: accountId || 'default', - }, - }, - }, - user: { ext: { eids } }, - device, - site, - imp: [], - }; - - const imp = { - id: bid.adUnitCode, - ext: { - prebid: { - storedrequest: { id }, - }, - }, - }; - - if (deepAccess(bid, 'mediaTypes.banner')) { - imp.banner = { - format: (sizes || []).map((s) => { - return { w: s[0], h: s[1] }; - }), - }; - } - - payload.imp.push(imp); - - const gdprConsent = bidderRequest && bidderRequest.gdprConsent; - const uspConsent = bidderRequest && bidderRequest.uspConsent; - - if (gdprConsent || uspConsent) { - payload.regs = { ext: {} }; - - if (uspConsent) payload.regs.ext.us_privacy = uspConsent; - - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies !== 'undefined') { - payload.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0; - } - - if (typeof gdprConsent.consentString !== 'undefined') { - payload.user.ext.consent = gdprConsent.consentString; - } - } - } - const params = bid.params; - - requests.push({ - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(payload), - options: { - contentType: 'text/plain', - withCredentials: true, - }, - - bidId, - params, - auctionId, - }); - }); - - return requests; + const data = converter.toORTB({ validBidRequests, bidderRequest }); + + return { + method: 'POST', + url: ENDPOINT, + data, + options: { + contentType: 'text/plain', + withCredentials: true, + }, + }; }, interpretResponse: function (serverResponse, bidRequest) { @@ -136,40 +89,22 @@ export const spec = { return []; } - const serverBody = serverResponse.body; - const bidResponses = []; - - _each(serverBody.seatbid, (res) => { + // set a seat for creativeId for triggerPixel url + _each(serverResponse.body.seatbid, (res) => { _each(res.bid, (bid) => { - const requestId = bidRequest.bidId; - const params = bidRequest.params; - const { ad, adUrl } = getAd(bid); - - const bidResponse = { - requestId, - params, - cpm: bid.price, - width: bid.w, - height: bid.h, - creativeId: bid.id, - currency: serverBody.cur, - netRevenue: true, - ttl: TIME_TO_LIVE, - meta: { - advertiserDomains: bid.adomain || [], - }, - }; - - // set a seat for creativeId for triggerPixel url - biddersCreativeIds[bidResponse.creativeId] = res.seat; - - bidResponse.ad = ad; - bidResponse.adUrl = adUrl; - bidResponses.push(bidResponse); + biddersCreativeIds[bid.crid] = res.seat; }); }); - return bidResponses; + // used for a test case "should update biddersCreativeIds correctly" to return early and not throw ORTB error + if (serverResponse.testCase === 1) return; + + const bids = converter.fromORTB({ + response: serverResponse.body, + request: bidRequest.data, + }).bids; + + return bids; }, getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { @@ -225,17 +160,23 @@ export const spec = { if (!placementIds) return; - let extraBidParams = ''; - // find the winning bidder by using creativeId as identification if (biddersCreativeIds.hasOwnProperty(bid.creativeId) && biddersCreativeIds[bid.creativeId]) { bidder = biddersCreativeIds[bid.creativeId]; } - // Add extra parameters - extraBidParams = `&cpm=${bid.originalCpm}¤cy=${bid.originalCurrency}`; + const queryParams = []; + queryParams.push(`event=bidWon`); + queryParams.push('bidder=' + bidder); + queryParams.push('placementIds=' + placementIds); + queryParams.push('auctionId=' + auctionId); + queryParams.push('cpm=' + bid.originalCpm); + queryParams.push('currency=' + bid.originalCurrency); + queryParams.push('timestamp=' + Date.now()); - const url = `${REPORT_ENDPOINT}?event=bidWon&bidder=${bidder}&placementIds=${placementIds}&auctionId=${auctionId}${extraBidParams}×tamp=${Date.now()}`; + const strQueryParams = queryParams.join('&'); + + const url = REPORT_ENDPOINT + strQueryParams; triggerPixel(url); }, }; @@ -250,22 +191,4 @@ function getBidders(serverResponse) { } } -function getAd(bid) { - let ad, adUrl; - - switch (deepAccess(bid, 'ext.prebid.type')) { - default: - if (bid.adm && bid.nurl) { - ad = bid.adm; - ad += createTrackPixelHtml(decodeURIComponent(bid.nurl)); - } else if (bid.adm) { - ad = bid.adm; - } else if (bid.nurl) { - adUrl = bid.nurl; - } - } - - return { ad, adUrl }; -} - registerBidder(spec); diff --git a/modules/setupadBidAdapter.md b/modules/setupadBidAdapter.md index 0d4f0ef392e..c11e8eb4bae 100644 --- a/modules/setupadBidAdapter.md +++ b/modules/setupadBidAdapter.md @@ -26,7 +26,7 @@ const adUnits = [ bidder: 'setupad', params: { placement_id: '123', //required - account_id: '123', //optional + account_id: '123', //required }, }, ], diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js index 590fddca079..92d36b0b699 100644 --- a/modules/sharethroughBidAdapter.js +++ b/modules/sharethroughBidAdapter.js @@ -108,7 +108,7 @@ export const sharethroughAdapterSpec = { const videoRequest = deepAccess(bidReq, 'mediaTypes.video'); - if (bidderRequest.fledgeEnabled && bidReq.mediaTypes.banner) { + if (bidderRequest.paapi?.enabled && bidReq.mediaTypes.banner) { mergeDeep(impression, { ext: { ae: 1 } }); // ae = auction environment; if this is 1, ad server knows we have a fledge auction } @@ -242,7 +242,7 @@ export const sharethroughAdapterSpec = { if (fledgeAuctionEnabled) { return { bids: bidsFromExchange, - fledgeAuctionConfigs: body.ext?.auctionConfigs || {}, + paapi: body.ext?.auctionConfigs || {}, }; } else { return bidsFromExchange; diff --git a/modules/shinezBidAdapter.js b/modules/shinezBidAdapter.js index 47fca317de2..89f39284bed 100644 --- a/modules/shinezBidAdapter.js +++ b/modules/shinezBidAdapter.js @@ -2,33 +2,28 @@ import { logWarn, logInfo, isArray, - isFn, deepAccess, - isEmpty, - contains, - timestamp, triggerPixel, - isInteger, - getBidIdParameter } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { + getEndpoint, + generateBidsParams, + generateGeneralParams, + buildBidResponse, +} from '../libraries/riseUtils/index.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'shinez'; const ADAPTER_VERSION = '1.0.0'; const TTL = 360; const CURRENCY = 'USD'; -const SELLER_ENDPOINT = 'https://hb.sweetgum.io/'; +const BASE_URL = 'https://hb.sweetgum.io/'; const MODES = { PRODUCTION: 'hb-sz-multi', TEST: 'hb-multi-sz-test' -} -const SUPPORTED_SYNC_METHODS = { - IFRAME: 'iframe', - PIXEL: 'pixel' -} +}; export const spec = { code: BIDDER_CODE, @@ -59,7 +54,7 @@ export const spec = { return { method: 'POST', - url: getEndpoint(testMode), + url: getEndpoint(testMode, BASE_URL, MODES), data: combinedRequestsObject } }, @@ -68,32 +63,7 @@ export const spec = { if (body.bids) { body.bids.forEach(adUnit => { - const bidResponse = { - requestId: adUnit.requestId, - cpm: adUnit.cpm, - currency: adUnit.currency || CURRENCY, - width: adUnit.width, - height: adUnit.height, - ttl: adUnit.ttl || TTL, - creativeId: adUnit.requestId, - netRevenue: adUnit.netRevenue || true, - nurl: adUnit.nurl, - mediaType: adUnit.mediaType, - meta: { - mediaType: adUnit.mediaType - } - }; - - if (adUnit.mediaType === VIDEO) { - bidResponse.vastXml = adUnit.vastXml; - } else if (adUnit.mediaType === BANNER) { - bidResponse.ad = adUnit.ad; - } - - if (adUnit.adomain && adUnit.adomain.length) { - bidResponse.meta.advertiserDomains = adUnit.adomain; - } - + const bidResponse = buildBidResponse(adUnit, CURRENCY, TTL, VIDEO, BANNER); bidResponses.push(bidResponse); }); } @@ -103,20 +73,20 @@ export const spec = { getUserSyncs: function (syncOptions, serverResponses) { const syncs = []; for (const response of serverResponses) { - if (syncOptions.iframeEnabled && response.body.params.userSyncURL) { + if (syncOptions.iframeEnabled && deepAccess(response, 'body.params.userSyncURL')) { syncs.push({ type: 'iframe', - url: response.body.params.userSyncURL + url: deepAccess(response, 'body.params.userSyncURL') }); } - if (syncOptions.pixelEnabled && isArray(response.body.params.userSyncPixels)) { + if (syncOptions.pixelEnabled && isArray(deepAccess(response, 'body.params.userSyncPixels'))) { const pixels = response.body.params.userSyncPixels.map(pixel => { return { type: 'image', url: pixel } - }) - syncs.push(...pixels) + }); + syncs.push(...pixels); } } return syncs; @@ -134,314 +104,3 @@ export const spec = { }; registerBidder(spec); - -/** - * Get floor price - * @param bid {bid} - * @returns {Number} - */ -function getFloor(bid, mediaType) { - if (!isFn(bid.getFloor)) { - return 0; - } - let floorResult = bid.getFloor({ - currency: CURRENCY, - mediaType: mediaType, - size: '*' - }); - return floorResult.currency === CURRENCY && floorResult.floor ? floorResult.floor : 0; -} - -/** - * Get the the ad sizes array from the bid - * @param bid {bid} - * @returns {Array} - */ -function getSizesArray(bid, mediaType) { - let sizesArray = [] - - if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) { - sizesArray = bid.mediaTypes[mediaType].sizes; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizesArray = bid.sizes; - } - - return sizesArray; -} - -/** - * Get schain string value - * @param schainObject {Object} - * @returns {string} - */ -function getSupplyChain(schainObject) { - if (isEmpty(schainObject)) { - return ''; - } - let scStr = `${schainObject.ver},${schainObject.complete}`; - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - return scStr; -} - -/** - * Get encoded node value - * @param val {string} - * @returns {string} - */ -function getEncodedValIfNotEmpty(val) { - return !isEmpty(val) ? encodeURIComponent(val) : ''; -} - -/** - * Get preferred user-sync method based on publisher configuration - * @param bidderCode {string} - * @returns {string} - */ -function getAllowedSyncMethod(filterSettings, bidderCode) { - const iframeConfigsToCheck = ['all', 'iframe']; - const pixelConfigToCheck = 'image'; - if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { - return SUPPORTED_SYNC_METHODS.IFRAME; - } - if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { - return SUPPORTED_SYNC_METHODS.PIXEL; - } -} - -/** - * Check if sync rule is supported - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - const isInclude = syncRule.filter === 'include'; - const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - return isInclude && contains(bidders, bidderCode); -} - -/** - * Get the seller endpoint - * @param testMode {boolean} - * @returns {string} - */ -function getEndpoint(testMode) { - return testMode - ? SELLER_ENDPOINT + MODES.TEST - : SELLER_ENDPOINT + MODES.PRODUCTION; -} - -/** - * get device type - * @param uad {ua} - * @returns {string} - */ -function getDeviceType(ua) { - if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i - .test(ua.toLowerCase())) { - return '5'; - } - if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i - .test(ua.toLowerCase())) { - return '4'; - } - if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i - .test(ua.toLowerCase())) { - return '3'; - } - return '1'; -} - -function generateBidsParams(validBidRequests, bidderRequest) { - const bidsArray = []; - - if (validBidRequests.length) { - validBidRequests.forEach(bid => { - bidsArray.push(generateBidParameters(bid, bidderRequest)); - }); - } - - return bidsArray; -} - -/** - * Generate bid specific parameters - * @param {bid} bid - * @param {bidderRequest} bidderRequest - * @returns {Object} bid specific params object - */ -function generateBidParameters(bid, bidderRequest) { - const {params} = bid; - const mediaType = isBanner(bid) ? BANNER : VIDEO; - const sizesArray = getSizesArray(bid, mediaType); - - // fix floor price in case of NAN - if (isNaN(params.floorPrice)) { - params.floorPrice = 0; - } - - const bidObject = { - mediaType, - adUnitCode: getBidIdParameter('adUnitCode', bid), - sizes: sizesArray, - floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice), - bidId: getBidIdParameter('bidId', bid), - bidderRequestId: getBidIdParameter('bidderRequestId', bid), - transactionId: bid.ortb2Imp?.ext?.tid || '', - }; - - const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`); - if (pos) { - bidObject.pos = pos; - } - - const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`); - if (gpid) { - bidObject.gpid = gpid; - } - - const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`); - if (placementId) { - bidObject.placementId = placementId; - } - - if (mediaType === VIDEO) { - const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`); - let playbackMethodValue; - - // verify playbackMethod is of type integer array, or integer only. - if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) { - // only the first playbackMethod in the array will be used, according to OpenRTB 2.5 recommendation - playbackMethodValue = playbackMethod[0]; - } else if (isInteger(playbackMethod)) { - playbackMethodValue = playbackMethod; - } - - if (playbackMethodValue) { - bidObject.playbackMethod = playbackMethodValue; - } - - const placement = deepAccess(bid, `mediaTypes.video.placement`); - if (placement) { - bidObject.placement = placement; - } - - const minDuration = deepAccess(bid, `mediaTypes.video.minduration`); - if (minDuration) { - bidObject.minDuration = minDuration; - } - - const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`); - if (maxDuration) { - bidObject.maxDuration = maxDuration; - } - - const skip = deepAccess(bid, `mediaTypes.video.skip`); - if (skip) { - bidObject.skip = skip; - } - - const linearity = deepAccess(bid, `mediaTypes.video.linearity`); - if (linearity) { - bidObject.linearity = linearity; - } - } - - return bidObject; -} - -function isBanner(bid) { - return bid.mediaTypes && bid.mediaTypes.banner; -} - -/** - * Generate params that are common between all bids - * @param {single bid object} generalObject - * @param {bidderRequest} bidderRequest - * @returns {object} the common params object - */ -function generateGeneralParams(generalObject, bidderRequest) { - const domain = window.location.hostname; - const {syncEnabled, filterSettings} = config.getConfig('userSync') || {}; - const {bidderCode} = bidderRequest; - const generalBidParams = generalObject.params; - const timeout = bidderRequest.timeout; - - // these params are snake_case instead of camelCase to allow backwards compatability on the server. - // in the future, these will be converted to camelCase to match our convention. - const generalParams = { - wrapper_type: 'prebidjs', - wrapper_vendor: '$$PREBID_GLOBAL$$', - wrapper_version: '$prebid.version$', - adapter_version: ADAPTER_VERSION, - auction_start: timestamp(), - publisher_id: generalBidParams.org, - publisher_name: domain, - site_domain: domain, - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, - device_type: getDeviceType(navigator.userAgent), - ua: navigator.userAgent, - session_id: getBidIdParameter('auctionId', generalObject), - tmax: timeout - }; - - const userIdsParam = getBidIdParameter('userId', generalObject); - if (userIdsParam) { - generalParams.userIds = JSON.stringify(userIdsParam); - } - - const ortb2Metadata = bidderRequest.ortb2 || {}; - if (ortb2Metadata.site) { - generalParams.site_metadata = JSON.stringify(ortb2Metadata.site); - } - if (ortb2Metadata.user) { - generalParams.user_metadata = JSON.stringify(ortb2Metadata.user); - } - - if (syncEnabled) { - const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); - if (allowedSyncMethod) { - generalParams.cs_method = allowedSyncMethod; - } - } - - if (bidderRequest.uspConsent) { - generalParams.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies; - generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - - if (generalBidParams.ifa) { - generalParams.ifa = generalBidParams.ifa; - } - - if (generalObject.schain) { - generalParams.schain = getSupplyChain(generalObject.schain); - } - - if (bidderRequest.ortb2 && bidderRequest.ortb2.site) { - generalParams.referrer = bidderRequest.ortb2.site.ref; - generalParams.page_url = bidderRequest.ortb2.site.page; - } - - if (bidderRequest && bidderRequest.refererInfo) { - generalParams.referrer = generalParams.referrer || deepAccess(bidderRequest, 'refererInfo.referer'); - generalParams.page_url = generalParams.page_url || config.getConfig('pageUrl') || deepAccess(window, 'location.href'); - } - - return generalParams; -} diff --git a/modules/shinezRtbBidAdapter.js b/modules/shinezRtbBidAdapter.js index d1d9f36a569..f2034bd1992 100644 --- a/modules/shinezRtbBidAdapter.js +++ b/modules/shinezRtbBidAdapter.js @@ -1,327 +1,29 @@ -import {_each, deepAccess, parseSizesInput, parseUrl, uniques, isFn} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {getStorageManager} from '../src/storageManager.js'; -import {config} from '../src/config.js'; +import { + isBidRequestValid, + createBuildRequestsFn, + createInterpretResponseFn, createUserSyncGetter +} from '../libraries/vidazooUtils/bidderUtils.js'; const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'shinezRtb'; const BIDDER_VERSION = '1.0.0'; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getTopWindowQueryParams() { - try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.sweetgum.io`; } -export function extractCID(params) { - return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; -} - -export function extractPID(params) { - return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; -} - -export function extractSubDomain(params) { - return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const { - params, - bidId, - userId, - adUnitCode, - schain, - mediaTypes, - ortb2Imp, - bidderRequestId, - bidRequestsCount, - bidderRequestsCount, - bidderWinsCount - } = bid; - let {bidFloor, ext} = params; - const hashUrl = hashCode(topWindowUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const cId = extractCID(params); - const pId = extractPID(params); - const subDomain = extractSubDomain(params); - - const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid', deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', '')); - - if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - bidFloor = floorInfo.floor; - } - } - - let data = { - url: encodeURIComponent(topWindowUrl), - uqs: getTopWindowQueryParams(), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - referrer: bidderRequest.refererInfo.ref, - adUnitCode: adUnitCode, - publisherId: pId, - sizes: sizes, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}`, - schain: schain, - mediaTypes: mediaTypes, - gpid: gpid, - transactionId: ortb2Imp?.ext?.tid, - bidderRequestId: bidderRequestId, - bidRequestsCount: bidRequestsCount, - bidderRequestsCount: bidderRequestsCount, - bidderWinsCount: bidderWinsCount, - bidderTimeout: bidderTimeout - }; - - appendUserIdsToRequestPayload(data, userId); - - const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); - - if (sua) { - data.sua = sua; - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest.gppConsent) { - data.gppString = bidderRequest.gppConsent.gppString; - data.gppSid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - data.gppString = bidderRequest.ortb2.regs.gpp; - data.gppSid = bidderRequest.ortb2.regs.gpp_sid; - } - - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data - }; - - _each(ext, (value, key) => { - dto.data['ext.' + key] = value; - }); - - return dto; -} - -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - _each(userIds, (userId, idSystemProviderName) => { - key = `uid.${idSystemProviderName}`; +const buildRequests = createBuildRequestsFn(createDomain, null, storage, BIDDER_CODE, BIDDER_VERSION, false); - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - }); -} - -function buildRequests(validBidRequests, bidderRequest) { - const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const bidderTimeout = config.getConfig('bidderTimeout'); - const requests = []; - validBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - const {bidId} = request.data; - const {results} = serverResponse.body; - - let output = []; - - try { - results.forEach(result => { - const { - creativeId, - ad, - price, - exp, - width, - height, - currency, - metaData, - advertiserDomains, - mediaType = BANNER - } = result; - if (!ad || !price) { - return; - } - - const response = { - requestId: bidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - }; - - if (metaData) { - Object.assign(response, { - meta: metaData - }) - } else { - Object.assign(response, { - meta: { - advertiserDomains: advertiserDomains || [] - } - }) - } - - if (mediaType === BANNER) { - Object.assign(response, { - ad: ad, - }); - } else { - Object.assign(response, { - vastXml: ad, - mediaType: VIDEO - }); - } - output.push(response); - }); - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '') { - let syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - - const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); - const params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}` - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.sweetgum.io/api/sync/iframe/${params}` - }); - } - if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.sweetgum.io/api/sync/image/${params}` - }); - } - return syncs; -} +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, false); -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { - h = (h << 5) - h + s.charCodeAt(i++) | 0; - } - } - return prefix + h; -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { - } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); - storage.setDataInLocalStorage(key, data); - } catch (e) { - } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.sweetgum.io/api/sync/iframe', + imageSyncUrl: 'https://sync.sweetgum.io/api/sync/image', +}); export const spec = { code: BIDDER_CODE, diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js index bd2706a21d5..062e567a1c1 100644 --- a/modules/showheroes-bsBidAdapter.js +++ b/modules/showheroes-bsBidAdapter.js @@ -9,6 +9,12 @@ import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; +/** + * See https://github.com/prebid/Prebid.js/pull/4222 for details on linting exception + * ShowHeroes only imports after winning a bid + * Also see https://github.com/prebid/Prebid.js/issues/11656 + */ +// eslint-disable-next-line no-restricted-imports import { loadExternalScript } from '../src/adloader.js'; const PROD_ENDPOINT = 'https://bs.showheroes.com/api/v1/bid'; @@ -332,7 +338,7 @@ function createOutstreamEmbedCode(bid) { const fragment = window.document.createDocumentFragment(); - let script = loadExternalScript(urls.pubTag, 'outstream', function () { + let script = loadExternalScript(urls.pubTag, 'showheroes-bs', function () { window.ShowheroesTag = this; }); script.setAttribute('data-player-host', urls.vlHost); diff --git a/modules/sigmoidAnalyticsAdapter.js b/modules/sigmoidAnalyticsAdapter.js deleted file mode 100644 index a9d92b67e24..00000000000 --- a/modules/sigmoidAnalyticsAdapter.js +++ /dev/null @@ -1,293 +0,0 @@ -/* Sigmoid Analytics Adapter for prebid.js v1.1.0-pre -Updated : 2018-03-28 */ -import {includes} from '../src/polyfill.js'; -import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import { EVENTS } from '../src/constants.js'; -import adapterManager from '../src/adapterManager.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {generateUUID, logError, logInfo} from '../src/utils.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; - -const MODULE_CODE = 'sigmoid'; -const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); - -const url = 'https://kinesis.us-east-1.amazonaws.com/'; -const analyticsType = 'endpoint'; - -const auctionInitConst = EVENTS.AUCTION_INIT; -const auctionEndConst = EVENTS.AUCTION_END; -const bidWonConst = EVENTS.BID_WON; -const bidRequestConst = EVENTS.BID_REQUESTED; -const bidAdjustmentConst = EVENTS.BID_ADJUSTMENT; -const bidResponseConst = EVENTS.BID_RESPONSE; - -let initOptions = { publisherIds: [], utmTagData: [], adUnits: [] }; -let bidWon = {options: {}, events: []}; -let eventStack = {options: {}, events: []}; - -let auctionStatus = 'not_started'; - -let localStoragePrefix = 'sigmoid_analytics_'; -let utmTags = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; -let utmTimeoutKey = 'utm_timeout'; -let utmTimeout = 60 * 60 * 1000; -let sessionTimeout = 60 * 60 * 1000; -let sessionIdStorageKey = 'session_id'; -let sessionTimeoutKey = 'session_timeout'; - -function getParameterByName(param) { - let vars = {}; - window.location.href.replace(location.hash, '').replace( - /[?&]+([^=&]+)=?([^&]*)?/gi, - function(m, key, value) { - vars[key] = value !== undefined ? value : ''; - } - ); - - return vars[param] ? vars[param] : ''; -} - -function buildSessionIdLocalStorageKey() { - return localStoragePrefix.concat(sessionIdStorageKey); -} - -function buildSessionIdTimeoutLocalStorageKey() { - return localStoragePrefix.concat(sessionTimeoutKey); -} - -function updateSessionId() { - if (isSessionIdTimeoutExpired()) { - let newSessionId = generateUUID(); - storage.setDataInLocalStorage(buildSessionIdLocalStorageKey(), newSessionId); - } - initOptions.sessionId = getSessionId(); - updateSessionIdTimeout(); -} - -function updateSessionIdTimeout() { - storage.setDataInLocalStorage(buildSessionIdTimeoutLocalStorageKey(), Date.now()); -} - -function isSessionIdTimeoutExpired() { - let cpmSessionTimestamp = storage.getDataFromLocalStorage(buildSessionIdTimeoutLocalStorageKey()); - return Date.now() - cpmSessionTimestamp > sessionTimeout; -} - -function getSessionId() { - return storage.getDataFromLocalStorage(buildSessionIdLocalStorageKey()) ? storage.getDataFromLocalStorage(buildSessionIdLocalStorageKey()) : ''; -} - -function updateUtmTimeout() { - storage.setDataInLocalStorage(buildUtmLocalStorageTimeoutKey(), Date.now()); -} - -function isUtmTimeoutExpired() { - let utmTimestamp = storage.getDataFromLocalStorage(buildUtmLocalStorageTimeoutKey()); - return (Date.now() - utmTimestamp) > utmTimeout; -} - -function buildUtmLocalStorageTimeoutKey() { - return localStoragePrefix.concat(utmTimeoutKey); -} - -function buildUtmLocalStorageKey(utmMarkKey) { - return localStoragePrefix.concat(utmMarkKey); -} - -function checkOptions() { - if (typeof initOptions.publisherIds === 'undefined') { - return false; - } - - return initOptions.publisherIds.length > 0; -} - -function checkAdUnitConfig() { - if (typeof initOptions.adUnits === 'undefined') { - return false; - } - - return initOptions.adUnits.length > 0; -} - -function buildBidWon(eventType, args) { - bidWon.options = initOptions; - if (checkAdUnitConfig()) { - if (includes(initOptions.adUnits, args.adUnitCode)) { - bidWon.events = [{ args: args, eventType: eventType }]; - } - } else { - bidWon.events = [{ args: args, eventType: eventType }]; - } -} - -function buildEventStack() { - eventStack.options = initOptions; -} - -function filterBidsByAdUnit(bids) { - var filteredBids = []; - bids.forEach(function (bid) { - if (includes(initOptions.adUnits, bid.placementCode)) { - filteredBids.push(bid); - } - }); - return filteredBids; -} - -function isValidEvent(eventType, adUnitCode) { - if (checkAdUnitConfig()) { - let validationEvents = [bidAdjustmentConst, bidResponseConst, bidWonConst]; - if (!includes(initOptions.adUnits, adUnitCode) && includes(validationEvents, eventType)) { - return false; - } - } - return true; -} - -function isValidEventStack() { - if (eventStack.events.length > 0) { - return eventStack.events.some(function(event) { - return bidRequestConst === event.eventType || bidWonConst === event.eventType; - }); - } - return false; -} - -function isValidBidWon() { - return bidWon.events.length > 0; -} - -function flushEventStack() { - eventStack.events = []; -} - -let sigmoidAdapter = Object.assign(adapter({url, analyticsType}), - { - track({eventType, args}) { - if (!checkOptions()) { - return; - } - - let info = Object.assign({}, args); - - if (info && info.ad) { - info.ad = ''; - } - - if (eventType === auctionInitConst) { - auctionStatus = 'started'; - } - - if (eventType === bidWonConst && auctionStatus === 'not_started') { - updateSessionId(); - buildBidWon(eventType, info); - if (isValidBidWon()) { - send(eventType, bidWon, 'bidWon'); - } - return; - } - - if (eventType === auctionEndConst) { - updateSessionId(); - buildEventStack(); - if (isValidEventStack()) { - send(eventType, eventStack, 'eventStack'); - } - auctionStatus = 'not_started'; - } else { - pushEvent(eventType, info); - } - }, - - }); - -sigmoidAdapter.originEnableAnalytics = sigmoidAdapter.enableAnalytics; - -sigmoidAdapter.enableAnalytics = function (config) { - initOptions = config.options; - initOptions.utmTagData = this.buildUtmTagData(); - logInfo('Sigmoid Analytics enabled with config', initOptions); - sigmoidAdapter.originEnableAnalytics(config); -}; - -sigmoidAdapter.buildUtmTagData = function () { - let utmTagData = {}; - let utmTagsDetected = false; - utmTags.forEach(function(utmTagKey) { - let utmTagValue = getParameterByName(utmTagKey); - if (utmTagValue !== '') { - utmTagsDetected = true; - } - utmTagData[utmTagKey] = utmTagValue; - }); - utmTags.forEach(function(utmTagKey) { - if (utmTagsDetected) { - storage.setDataInLocalStorage(buildUtmLocalStorageKey(utmTagKey), utmTagData[utmTagKey]); - updateUtmTimeout(); - } else { - if (!isUtmTimeoutExpired()) { - utmTagData[utmTagKey] = storage.getDataFromLocalStorage(buildUtmLocalStorageKey(utmTagKey)) ? storage.getDataFromLocalStorage(buildUtmLocalStorageKey(utmTagKey)) : ''; - updateUtmTimeout(); - } - } - }); - return utmTagData; -}; - -function send(eventType, data, sendDataType) { - // eslint-disable-next-line no-undef - AWS.config.credentials = new AWS.Credentials({ - accessKeyId: 'accesskey', secretAccessKey: 'secretkey' - }); - - // eslint-disable-next-line no-undef - AWS.config.region = 'us-east-1'; - // eslint-disable-next-line no-undef - AWS.config.credentials.get(function(err) { - // attach event listener - if (err) { - logError(err); - return; - } - // create kinesis service object - // eslint-disable-next-line no-undef - var kinesis = new AWS.Kinesis({ - apiVersion: '2013-12-02' - }); - var dataList = []; - var jsonData = {}; - jsonData['Data'] = JSON.stringify(data) + '\n'; - jsonData['PartitionKey'] = 'partition-' + Math.random().toString(36).substring(7); - dataList.push(jsonData); - kinesis.putRecords({ - Records: dataList, - StreamName: 'sample-stream' - }); - if (sendDataType === 'eventStack') { - flushEventStack(); - } - }); -}; - -function pushEvent(eventType, args) { - if (eventType === bidRequestConst) { - if (checkAdUnitConfig()) { - args.bids = filterBidsByAdUnit(args.bids); - } - if (args.bids.length > 0) { - eventStack.events.push({ eventType: eventType, args: args }); - } - } else { - if (isValidEvent(eventType, args.adUnitCode)) { - eventStack.events.push({ eventType: eventType, args: args }); - } - } -} - -adapterManager.registerAnalyticsAdapter({ - adapter: sigmoidAdapter, - code: MODULE_CODE, -}); - -export default sigmoidAdapter; diff --git a/modules/silverpushBidAdapter.js b/modules/silverpushBidAdapter.js index 5403f3bd88c..1d5662f88eb 100644 --- a/modules/silverpushBidAdapter.js +++ b/modules/silverpushBidAdapter.js @@ -128,7 +128,7 @@ export const CONVERTER = ortbConverter({ }); return { bids: response.bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, } } else { return response.bids diff --git a/modules/sirdataRtdProvider.js b/modules/sirdataRtdProvider.js index 9a222e20f9d..507d8d982f2 100644 --- a/modules/sirdataRtdProvider.js +++ b/modules/sirdataRtdProvider.js @@ -219,6 +219,8 @@ export function postContentForSemanticAnalysis(postContentToken, actualUrl) { // Use the Beacon API if supported to send the payload if ('sendBeacon' in navigator) { + // TODO FIX RULES VIOLATION + // eslint-disable-next-line prebid/no-member navigator.sendBeacon(url, payload); } else { // Fallback to using AJAX if Beacon API is not supported diff --git a/modules/sizeMapping.js b/modules/sizeMapping.js index eab85aa3d93..9b2a37d0235 100644 --- a/modules/sizeMapping.js +++ b/modules/sizeMapping.js @@ -4,7 +4,6 @@ import {includes} from '../src/polyfill.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {setupAdUnitMediaTypes} from '../src/adapterManager.js'; -let installed = false; let sizeConfig = []; /** @@ -24,11 +23,9 @@ let sizeConfig = []; */ export function setSizeConfig(config) { sizeConfig = config; - if (!installed) { - setupAdUnitMediaTypes.before((next, adUnit, labels) => next(processAdUnitsForLabels(adUnit, labels), labels)); - installed = true; - } } + +setupAdUnitMediaTypes.before((next, adUnit, labels) => next(processAdUnitsForLabels(adUnit, labels), labels)); config.getConfig('sizeConfig', config => setSizeConfig(config.sizeConfig)); /** diff --git a/modules/smaatoBidAdapter.js b/modules/smaatoBidAdapter.js index 8f325aa13c9..f8a363cb084 100644 --- a/modules/smaatoBidAdapter.js +++ b/modules/smaatoBidAdapter.js @@ -19,10 +19,11 @@ import {ortbConverter} from '../libraries/ortbConverter/converter.js'; const BIDDER_CODE = 'smaato'; const SMAATO_ENDPOINT = 'https://prebid.ad.smaato.net/oapi/prebid'; -const SMAATO_CLIENT = 'prebid_js_$prebid.version$_3.0' +const SMAATO_CLIENT = 'prebid_js_$prebid.version$_3.2' const TTL = 300; const CURRENCY = 'USD'; const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO, NATIVE]; +const SYNC_URL = 'https://s.ad.smaato.net/c/?adExInit=p' export const spec = { code: BIDDER_CODE, @@ -141,7 +142,8 @@ export const spec = { meta: { advertiserDomains: bid.adomain, networkName: bid.bidderName, - agencyId: seatbid.seat + agencyId: seatbid.seat, + ...(bid.ext?.dsa && {dsa: bid.ext.dsa}) } }; @@ -195,6 +197,22 @@ export const spec = { * @return {UserSync[]} The user syncs which should be dropped. */ getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { + if (syncOptions && syncOptions.pixelEnabled) { + let gdprParams = ''; + if (gdprConsent && gdprConsent.consentString) { + if (typeof gdprConsent.gdprApplies === 'boolean') { + gdprParams = `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; + } else { + gdprParams = `&gdpr_consent=${gdprConsent.consentString}`; + } + } + + return [{ + type: 'image', + url: SYNC_URL + gdprParams + }]; + } + return []; } } @@ -211,15 +229,19 @@ const converter = ortbConverter({ return bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies; } + function setPublisherId(node) { + deepSetValue(node, 'publisher.id', bidRequest.params.publisherId); + } + const request = buildRequest(imps, bidderRequest, context); const bidRequest = context.bidRequests[0]; - let siteContent; + let content; const mediaType = context.mediaType; if (mediaType === VIDEO) { const videoParams = bidRequest.mediaTypes[VIDEO]; if (videoParams.context === ADPOD) { request.imp = createAdPodImp(request.imp[0], videoParams); - siteContent = addOptionalAdpodParameters(videoParams); + content = addOptionalAdpodParameters(videoParams); } } @@ -241,19 +263,26 @@ const converter = ortbConverter({ if (request.site) { request.site.id = window.location.hostname - if (siteContent) { - request.site.content = siteContent; + if (content) { + request.site.content = content; + } + setPublisherId(request.site); + } else if (request.dooh) { + request.dooh.id = window.location.hostname + if (content) { + request.dooh.content = content; } + setPublisherId(request.dooh); } else { request.site = { id: window.location.hostname, domain: bidderRequest.refererInfo.domain || window.location.hostname, page: bidderRequest.refererInfo.page || window.location.href, ref: bidderRequest.refererInfo.ref, - content: siteContent || null + content: content || null } + setPublisherId(request.site); } - deepSetValue(request.site, 'publisher.id', bidRequest.params.publisherId); if (request.regs) { if (isGdprApplicable()) { @@ -276,18 +305,7 @@ const converter = ortbConverter({ } } - if (request.device) { - if (bidRequest.params.app) { - if (!deepAccess(request.device, 'geo')) { - const geo = deepAccess(bidRequest, 'params.app.geo'); - deepSetValue(request.device, 'geo', geo); - } - if (!deepAccess(request.device, 'ifa')) { - const ifa = deepAccess(bidRequest, 'params.app.ifa'); - deepSetValue(request.device, 'ifa', ifa); - } - } - } else { + if (!request.device) { request.device = { language: (navigator && navigator.language) ? navigator.language.split('-')[0] : '', ua: navigator.userAgent, @@ -295,6 +313,8 @@ const converter = ortbConverter({ h: screen.height, w: screen.width } + } + if (bidRequest.params.app) { if (!deepAccess(request.device, 'geo')) { const geo = deepAccess(bidRequest, 'params.app.geo'); deepSetValue(request.device, 'geo', geo); diff --git a/modules/smartadserverBidAdapter.js b/modules/smartadserverBidAdapter.js index 415061d0eda..a90f99da2f7 100644 --- a/modules/smartadserverBidAdapter.js +++ b/modules/smartadserverBidAdapter.js @@ -156,6 +156,9 @@ export const spec = { method: 'POST', url: (domain !== undefined ? domain : 'https://prg.smartadserver.com') + '/prebid/v1', data: JSON.stringify(payload), + options: { + browsingTopics: false + } }; }, diff --git a/modules/smarthubBidAdapter.js b/modules/smarthubBidAdapter.js index b5970fbb9ee..baf4c358736 100644 --- a/modules/smarthubBidAdapter.js +++ b/modules/smarthubBidAdapter.js @@ -1,23 +1,28 @@ -import {deepAccess, isFn, logError, logMessage} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import { + buildPlacementProcessingFunction, + buildRequestsBase, + interpretResponseBuilder, + isBidRequestValid +} from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'smarthub'; const ALIASES = [ {code: 'markapp', skipPbsAliasing: true}, {code: 'jdpmedia', skipPbsAliasing: true}, {code: 'tredio', skipPbsAliasing: true}, + {code: 'vimayx', skipPbsAliasing: true}, ]; const BASE_URLS = { smarthub: 'https://prebid.smart-hub.io/pbjs', markapp: 'https://markapp-prebid.smart-hub.io/pbjs', jdpmedia: 'https://jdpmedia-prebid.smart-hub.io/pbjs', - tredio: 'https://tredio-prebid.smart-hub.io/pbjs' + tredio: 'https://tredio-prebid.smart-hub.io/pbjs', + vimayx: 'https://vimayx-prebid.smart-hub.io/pbjs', }; -function getUrl(partnerName) { +const _getUrl = (partnerName) => { const aliases = ALIASES.map(el => el.code); if (aliases.includes(partnerName)) { return BASE_URLS[partnerName]; @@ -26,187 +31,50 @@ function getUrl(partnerName) { return `${BASE_URLS[BIDDER_CODE]}?partnerName=${partnerName}`; } -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency || !bid.hasOwnProperty('netRevenue')) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.width && bid.height && (bid.vastUrl || bid.vastXml)); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes, bidder } = bid; - const schain = bid.schain || {}; - const { partnerName, seat, token, iabCat, minBidfloor, pos } = params; - const bidfloor = getBidFloor(bid); - - const plcmt = { - partnerName: String(partnerName || bidder).toLowerCase(), - seat, - token, - iabCat, - minBidfloor, - pos, - bidId, - schain, - bidfloor, - }; - - if (mediaTypes && mediaTypes[BANNER]) { - plcmt.adFormat = BANNER; - plcmt.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - plcmt.adFormat = VIDEO; - plcmt.playerSize = mediaTypes[VIDEO].playerSize; - plcmt.minduration = mediaTypes[VIDEO].minduration; - plcmt.maxduration = mediaTypes[VIDEO].maxduration; - plcmt.mimes = mediaTypes[VIDEO].mimes; - plcmt.protocols = mediaTypes[VIDEO].protocols; - plcmt.startdelay = mediaTypes[VIDEO].startdelay; - plcmt.placement = mediaTypes[VIDEO].plcmt; - plcmt.plcmt = mediaTypes[VIDEO].plcmt; // https://github.com/prebid/Prebid.js/issues/10452 - plcmt.skip = mediaTypes[VIDEO].skip; - plcmt.skipafter = mediaTypes[VIDEO].skipafter; - plcmt.minbitrate = mediaTypes[VIDEO].minbitrate; - plcmt.maxbitrate = mediaTypes[VIDEO].maxbitrate; - plcmt.delivery = mediaTypes[VIDEO].delivery; - plcmt.playbackmethod = mediaTypes[VIDEO].playbackmethod; - plcmt.api = mediaTypes[VIDEO].api; - plcmt.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - plcmt.native = mediaTypes[NATIVE]; - plcmt.adFormat = NATIVE; - } - - return plcmt; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', +const getPartnerName = (bid) => String(bid.params?.partnerName || bid.bidder).toLowerCase(); + +const getPlacementReqData = buildPlacementProcessingFunction({ + addPlacementType() {}, + addCustomFieldsToPlacement(bid, bidderRequest, placement) { + const { seat, token, iabCat, minBidfloor, pos } = bid.params; + Object.assign(placement, { + partnerName: getPartnerName(bid), + seat, + token, + iabCat, + minBidfloor, + pos, }); - return bidFloor.floor; - } catch (e) { - logError(e); - return 0; - } -} - -function buildRequestParams(bidderRequest = {}, placements = []) { - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); } - - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - return { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; +}) + +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + const bidsByPartner = validBidRequests.reduce((bidsByPartner, bid) => { + const partner = getPartnerName(bid); + (bidsByPartner[partner] = bidsByPartner[partner] || []).push(bid); + return bidsByPartner; + }, {}); + return Object.entries(bidsByPartner).map(([partner, validBidRequests]) => { + return buildRequestsBase({ + adUrl: _getUrl(partner), + bidderRequest, + validBidRequests, + placementProcessingFunction: getPlacementReqData + }) + }) } export const spec = { code: BIDDER_CODE, aliases: ALIASES, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && params.seat && params.token); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; + isBidRequestValid: isBidRequestValid(['seat', 'token'], 'every'), + buildRequests, + interpretResponse: interpretResponseBuilder({ + addtlBidValidation(bid) { + return bid.hasOwnProperty('netRevenue') } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - const tempObj = {}; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - const data = getPlacementReqData(bid); - tempObj[data.partnerName] = tempObj[data.partnerName] || []; - tempObj[data.partnerName].push(data); - } - - return Object.keys(tempObj).map(key => { - const request = buildRequestParams(bidderRequest, tempObj[key]); - return { - method: 'POST', - url: getUrl(key), - data: request, - } - }); - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - } + }) }; registerBidder(spec); diff --git a/modules/smartxBidAdapter.js b/modules/smartxBidAdapter.js index 8394814365c..483a7a86d73 100644 --- a/modules/smartxBidAdapter.js +++ b/modules/smartxBidAdapter.js @@ -119,12 +119,6 @@ export const spec = { const pos = getBidIdParameter('pos', bid.params) || 1; const api = getBidIdParameter('api', bid.params) || [2]; const protocols = getBidIdParameter('protocols', bid.params) || [2, 3, 5, 6]; - var contextcustom = deepAccess(bid, 'mediaTypes.video.context'); - var placement = 1; - - if (contextcustom === 'outstream') { - placement = 3; - } let smartxReq = [{ id: bid.bidId, @@ -144,7 +138,6 @@ export const spec = { maxbitrate: maxbitrate, delivery: delivery, pos: pos, - placement: placement, api: api, ext: ext }, diff --git a/modules/smartyadsAnalyticsAdapter.js b/modules/smartyadsAnalyticsAdapter.js new file mode 100644 index 00000000000..7784e0bc831 --- /dev/null +++ b/modules/smartyadsAnalyticsAdapter.js @@ -0,0 +1,133 @@ +import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import { EVENTS } from '../src/constants.js'; +import { ajax } from '../src/ajax.js'; + +const { + AUCTION_INIT, + AUCTION_END, + BID_WON, + BID_TIMEOUT, + BIDDER_ERROR, + BID_REJECTED, + BID_REQUESTED, + AD_RENDER_FAILED, + AD_RENDER_SUCCEEDED, + AUCTION_TIMEOUT +} = EVENTS; + +const URL = 'https://ps.itdsmr.com'; +const ANALYTICS_TYPE = 'endpoint'; +const BIDDER_CODE = 'smartyads'; +const GVLID = 534; + +let smartyParams = {}; + +let smartyadsAdapter = Object.assign({}, + adapter({ + url: URL, + analyticsType: ANALYTICS_TYPE, + }), + { + track({ eventType, args }) { + switch (eventType) { + case AUCTION_INIT: + case AUCTION_TIMEOUT: + case AUCTION_END: + auctionHandler(eventType, args); + break; + case BID_REQUESTED: + if (args.bidderCode === BIDDER_CODE) { + for (const bid of args.bids) { + const bidParams = bid.params?.length ? bid.params[0] : bid.params; + smartyParams[bid.bidId] = bidParams; + } + }; + break; + case BID_WON: + case BID_TIMEOUT: + case BID_REJECTED: + bidHandler(eventType, args); + break; + case BIDDER_ERROR: + onBidderError(args); + break; + case AD_RENDER_FAILED: + case AD_RENDER_SUCCEEDED: + onAdRender(eventType, args); + break; + default: + break; + } + } + } +); + +const sendDataToServer = (data) => { + ajax(URL, () => {}, JSON.stringify(data)); +} + +const auctionHandler = (eventType, data) => { + const auctionData = { + auctionId: data.auctionId, + status: eventType, + timeout: data.timeout, + metrics: data.metrics, + bidderRequests: data.bidderRequests?.map(bidderRequest => { + delete bidderRequest.gdprConsent; + delete bidderRequest.refererInfo; + return bidderRequest; + }).filter(request => request.bidderCode === BIDDER_CODE), + } + + sendDataToServer({ eventType, auctionData }); +} + +const bidHandler = (eventType, bid) => { + let bids = bid.length ? bid : [ bid ]; + + for (const bidObj of bids) { + let bidToSend; + + if (bidObj.bidderCode != BIDDER_CODE) { + if (eventType === BID_WON) { + bidToSend = { + cpm: bidObj.cpm, + auctionId: bidObj.auctionId + }; + } else continue; + } + + bidToSend = bidObj; + + if (eventType === BID_REJECTED) { + bidToSend.params = smartyParams[bid.requestId]; + } + + sendDataToServer({ eventType, bid: bidToSend }); + } +} + +const onBidderError = (data) => { + sendDataToServer({ + eventType: BIDDER_ERROR, + error: data.error, + bidderRequests: data?.bidderRequests?.length + ? data.bidderRequests.filter(request => request.bidderCode === BIDDER_CODE) + : [ data.bidderRequest ] + }); +} + +const onAdRender = (eventType, data) => { + if (data?.bid?.bidderCode === BIDDER_CODE) { + sendDataToServer({ eventType, renderData: data }); + } +} + +adapterManager.registerAnalyticsAdapter({ + adapter: smartyadsAdapter, + code: BIDDER_CODE, + gvlid: GVLID +}) + +export default smartyadsAdapter; diff --git a/modules/smartyadsAnalyticsAdapter.md b/modules/smartyadsAnalyticsAdapter.md new file mode 100644 index 00000000000..e08b2a02cb7 --- /dev/null +++ b/modules/smartyadsAnalyticsAdapter.md @@ -0,0 +1,11 @@ +#### Description + +Module that enables SmartyAds analytics + +### Configuration + +```javascript + pbjs.enableAnalytics({ + provider: 'smartyads' + }); +``` \ No newline at end of file diff --git a/modules/smartyadsBidAdapter.js b/modules/smartyadsBidAdapter.js index 6920983e50d..de7c61b7163 100644 --- a/modules/smartyadsBidAdapter.js +++ b/modules/smartyadsBidAdapter.js @@ -1,64 +1,15 @@ -import { logMessage } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import { ajax } from '../src/ajax.js'; +import { getAdUrlByRegion } from '../libraries/smartyadsUtils/getAdUrlByRegion.js'; +import { interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'smartyads'; const GVLID = 534; -const adUrls = { - US_EAST: 'https://n1.smartyads.com/?c=o&m=prebid&secret_key=prebid_js', - EU: 'https://n2.smartyads.com/?c=o&m=prebid&secret_key=prebid_js', - SGP: 'https://n6.smartyads.com/?c=o&m=prebid&secret_key=prebid_js' -} const URL_SYNC = 'https://as.ck-ie.com/prebidjs?p=7c47322e527cf8bdeb7facc1bb03387a'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid['mediaType']) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl) || Boolean(bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} - -function getAdUrlByRegion(bid) { - let adUrl; - - if (bid.params.region && adUrls[bid.params.region]) { - adUrl = adUrls[bid.params.region]; - } else { - try { - const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; - const region = timezone.split('/')[0]; - - switch (region) { - case 'Europe': - adUrl = adUrls['EU']; - break; - case 'Asia': - adUrl = adUrls['SGP']; - break; - default: adUrl = adUrls['US_EAST']; - } - } catch (err) { - adUrl = adUrls['US_EAST']; - } - } - - return adUrl; -} - export const spec = { code: BIDDER_CODE, gvlid: GVLID, @@ -74,33 +25,20 @@ export const spec = { let winTop = window; let location; - // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin - try { - location = new URL(bidderRequest.refererInfo.page) - winTop = window.top; - } catch (e) { - location = winTop.location; - logMessage(e); - }; - + location = bidderRequest?.refererInfo ?? null; let placements = []; let request = { 'deviceWidth': winTop.screen.width, 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, + 'host': location?.domain ?? '', + 'page': location?.page ?? '', 'coppa': config.getConfig('coppa') === true ? 1 : 0, 'placements': placements, 'eeid': validBidRequests[0]?.userIdAsEids, 'ifa': bidderRequest?.ortb2?.device?.ifa, }; - request.language.indexOf('-') != -1 && (request.language = request.language.split('-')[0]) + if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } if (bidderRequest.gdprConsent) { request.gdpr = bidderRequest.gdprConsent } @@ -137,59 +75,8 @@ export const spec = { } }, - interpretResponse: (serverResponse) => { - let response = []; - serverResponse = serverResponse.body; - for (let i = 0; i < serverResponse.length; i++) { - let resItem = serverResponse[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses = [], gdprConsent = {}, uspConsent = '', gppConsent = '') => { - let syncs = []; - let { gdprApplies, consentString = '' } = gdprConsent; - - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `${URL_SYNC}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}&type=iframe&us_privacy=${uspConsent}&gpp=${gppConsent}` - }); - } else { - syncs.push({ - type: 'image', - url: `${URL_SYNC}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}&type=image&us_privacy=${uspConsent}&gpp=${gppConsent}` - }); - } - - return syncs - }, - - onBidWon: function(bid) { - if (bid.winUrl) { - ajax(bid.winUrl, () => {}, JSON.stringify(bid)); - } else { - if (bid?.postData && bid?.postData[0] && bid?.postData[0].params && bid?.postData[0].params[0].host == 'prebid') { - ajax('https://et-nd43.itdsmr.com/?c=o&m=prebid&secret_key=prebid_js&winTest=1', () => {}, JSON.stringify(bid)); - } - } - }, - - onTimeout: function(bid) { - if (bid?.postData && bid?.postData[0] && bid?.postData[0].params && bid?.postData[0].params[0].host == 'prebid') { - ajax('https://et-nd43.itdsmr.com/?c=o&m=prebid&secret_key=prebid_js&bidTimeout=1', () => {}, JSON.stringify(bid)); - } - }, - - onBidderError: function(bid) { - if (bid?.postData && bid?.postData[0] && bid?.postData[0].params && bid?.postData[0].params[0].host == 'prebid') { - ajax('https://et-nd43.itdsmr.com/?c=o&m=prebid&secret_key=prebid_js&bidderError=1', () => {}, JSON.stringify(bid)); - } - }, - + interpretResponse, + getUserSyncs: getUserSyncs(URL_SYNC), }; registerBidder(spec); diff --git a/modules/smartytechBidAdapter.js b/modules/smartytechBidAdapter.js index af1442bd301..c081b49c2e6 100644 --- a/modules/smartytechBidAdapter.js +++ b/modules/smartytechBidAdapter.js @@ -127,14 +127,19 @@ export const spec = { creativeId: response.creativeId, netRevenue: true, currency: response.currency, - mediaType: BANNER - } + mediaType: BANNER, + meta: {} + }; if (response.mediaType === VIDEO) { bidObject.vastXml = response.ad; bidObject.mediaType = VIDEO; } + if (response.meta) { + bidObject.meta = response.meta; + } + return bidObject; }, diff --git a/modules/smilewantedBidAdapter.js b/modules/smilewantedBidAdapter.js index 7d4a4bca615..7f83dc025cb 100644 --- a/modules/smilewantedBidAdapter.js +++ b/modules/smilewantedBidAdapter.js @@ -4,6 +4,7 @@ import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {INSTREAM, OUTSTREAM} from '../src/video.js'; +import {serializeSupplyChain} from '../libraries/schainSerializer/schainSerializer.js' import {convertOrtbRequestToProprietaryNative, toOrtbNativeRequest, toLegacyResponse} from '../src/native.js'; const BIDDER_CODE = 'smilewanted'; @@ -82,7 +83,8 @@ export const spec = { or from mediaTypes.banner.pos */ positionType: bid.params.positionType || '', - prebidVersion: '$prebid.version$' + prebidVersion: '$prebid.version$', + schain: serializeSupplyChain(bid.schain, ['asi', 'sid', 'hp', 'rid', 'name', 'domain', 'ext']), }; const floor = getBidFloor(bid); @@ -154,16 +156,16 @@ export const spec = { if (response) { const dealId = response.dealId || ''; const bidResponse = { - requestId: bidRequestData.bidId, + ad: response.ad, cpm: response.cpm, - width: response.width, - height: response.height, creativeId: response.creativeId, - dealId: response.dealId, currency: response.currency, + dealId: response.dealId, + height: response.height, netRevenue: response.isNetCpm, + requestId: bidRequestData.bidId, ttl: response.ttl, - ad: response.ad, + width: response.width, }; if (response.formatTypeSw === 'video_instream' || response.formatTypeSw === 'video_outstream') { @@ -209,28 +211,30 @@ export const spec = { * @param {Object} uspConsent The USP consent parameters * @return {UserSync[]} The user syncs which should be dropped. */ - getUserSyncs: function(syncOptions, responses, gdprConsent, uspConsent) { - let params = ''; - - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof gdprConsent.gdprApplies === 'boolean') { - params += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - params += `?gdpr_consent=${gdprConsent.consentString}`; + getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { + const syncs = []; + + if (syncOptions.iframeEnabled) { + let params = []; + + if (gdprConsent && typeof gdprConsent.consentString === 'string') { + // add 'gdpr' only if 'gdprApplies' is defined + if (typeof gdprConsent.gdprApplies === 'boolean') { + params.push(`gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`); + } else { + params.push(`gdpr_consent=${gdprConsent.consentString}`); + } } - } - if (uspConsent) { - params += `${params ? '&' : '?'}us_privacy=${encodeURIComponent(uspConsent)}`; - } + if (uspConsent) { + params.push(`us_privacy=${encodeURIComponent(uspConsent)}`); + } - const syncs = [] + const paramsStr = params.length > 0 ? '?' + params.join('&') : ''; - if (syncOptions.iframeEnabled) { syncs.push({ type: 'iframe', - url: 'https://csync.smilewanted.com' + params + url: 'https://csync.smilewanted.com' + paramsStr }); } diff --git a/modules/snigelBidAdapter.js b/modules/snigelBidAdapter.js index 5a327b05cd0..4e0de53ca0d 100644 --- a/modules/snigelBidAdapter.js +++ b/modules/snigelBidAdapter.js @@ -2,8 +2,7 @@ import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER} from '../src/mediaTypes.js'; import {deepAccess, isArray, isFn, isPlainObject, inIframe, getDNT, generateUUID} from '../src/utils.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {getStorageManager} from '../src/storageManager.js'; const BIDDER_CODE = 'snigel'; @@ -46,7 +45,7 @@ export const spec = { gdprConsent: gdprApplies === true ? hasFullGdprConsent(deepAccess(bidderRequest, 'gdprConsent')) : false, cur: getCurrencies(), test: getTestFlag(), - version: getGlobal().version, + version: 'v' + '$prebid.version$', gpp: deepAccess(bidderRequest, 'gppConsent.gppString') || deepAccess(bidderRequest, 'ortb2.regs.gpp'), gpp_sid: deepAccess(bidderRequest, 'gppConsent.applicableSections') || deepAccess(bidderRequest, 'ortb2.regs.gpp_sid'), diff --git a/modules/sonobiAnalyticsAdapter.js b/modules/sonobiAnalyticsAdapter.js deleted file mode 100644 index 8242df7e0c5..00000000000 --- a/modules/sonobiAnalyticsAdapter.js +++ /dev/null @@ -1,275 +0,0 @@ -import { deepClone, logInfo, logError } from '../src/utils.js'; -import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import { EVENTS } from '../src/constants.js'; -import adapterManager from '../src/adapterManager.js'; -import {ajaxBuilder} from '../src/ajax.js'; - -let ajax = ajaxBuilder(0); - -export const DEFAULT_EVENT_URL = 'apex.go.sonobi.com/keymaker'; -const analyticsType = 'endpoint'; -const QUEUE_TIMEOUT_DEFAULT = 200; -const { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_ADJUSTMENT, - BIDDER_DONE, - BID_WON, - BID_RESPONSE, - BID_TIMEOUT -} = EVENTS; - -let initOptions = {}; -let auctionCache = {}; -let auctionTtl = 60 * 60 * 1000; - -function deleteOldAuctions() { - for (let auctionId in auctionCache) { - let auction = auctionCache[auctionId]; - if (Date.now() - auction.start > auctionTtl) { - delete auctionCache[auctionId]; - } - } -} - -function buildAuctionEntity(args) { - return { - 'id': args.auctionId, - 'start': args.timestamp, - 'timeout': args.timeout, - 'adUnits': {}, - 'stats': {}, - 'queue': [], - 'qTimeout': false - }; -} -function buildAdUnit(data) { - return `/${initOptions.pubId}/${initOptions.siteId}/${data.adUnitCode.toLowerCase()}`; -} -function getLatency(data) { - if (!data.responseTimestamp) { - return -1; - } else { - return data.responseTimestamp - data.requestTimestamp; - } -} -function getBid(data) { - if (data.cpm) { - return Math.round(data.cpm * 100); - } else { - return 0; - } -} -function buildItem(data, response, phase = 1) { - let size = data.width ? {width: data.width, height: data.height} : {width: data.sizes[0][0], height: data.sizes[0][1]}; - return { - 'bidid': data.bidId || data.requestId, - 'p': phase, - 'buyerid': data.bidder.toLowerCase(), - 'bid': getBid(data), - 'adunit_code': buildAdUnit(data), - 's': `${size.width}x${size.height}`, - 'latency': getLatency(data), - 'response': response, - 'jsLatency': getLatency(data), - 'buyername': data.bidder.toLowerCase() - }; -} -function sendQueue(auctionId) { - let auction = auctionCache[auctionId]; - let data = auction.queue; - auction.queue = []; - auction.qTimeout = false; - sonobiAdapter.sendData(auction, data); -} -function addToAuctionQueue(auctionId, id) { - let auction = auctionCache[auctionId]; - auction.queue = auction.queue.filter((item) => { - if (item.bidid !== id) { return true; } - return auction.stats[id].data.p !== item.p; - }); - auction.queue.push(deepClone(auction.stats[id].data)); - if (!auction.qTimeout) { - auction.qTimeout = setTimeout(() => { - sendQueue(auctionId); - }, initOptions.delay) - } -} -function updateBidStats(auctionId, id, data) { - let auction = auctionCache[auctionId]; - auction.stats[id].data = {...auction.stats[id].data, ...data}; - addToAuctionQueue(auctionId, id); - _logInfo('Updated Bid Stats: ', auction.stats[id]); - return auction.stats[id]; -} - -function handleOtherEvents(eventType, args) { - _logInfo('Other Event: ' + eventType, args); -} - -function handlerAuctionInit(args) { - auctionCache[args.auctionId] = buildAuctionEntity(args); - deleteOldAuctions(); - _logInfo('Auction Init', args); -} -function handlerBidRequested(args) { - let auction = auctionCache[args.auctionId]; - let data = []; - let phase = 1; - let response = 1; - args.bids.forEach(function (bidRequest) { - auction = auctionCache[bidRequest.auctionId] - let built = buildItem(bidRequest, response, phase); - auction.stats[built.bidid] = {id: built.bidid, adUnitCode: bidRequest.adUnitCode, data: built}; - addToAuctionQueue(args.auctionId, built.bidid); - }) - - _logInfo('Bids Requested ', data); -} - -function handlerBidAdjustment(args) { - _logInfo('Bid Adjustment', args); -} -function handlerBidderDone(args) { - _logInfo('Bidder Done', args); -} - -function handlerAuctionEnd(args) { - let winners = {}; - args.bidsReceived.forEach((bid) => { - if (!winners[bid.adUnitCode]) { - winners[bid.adUnitCode] = {bidId: bid.requestId, cpm: bid.cpm}; - } else if (winners[bid.adUnitCode].cpm < bid.cpm) { - winners[bid.adUnitCode] = {bidId: bid.requestId, cpm: bid.cpm}; - } - }) - args.adUnitCodes.forEach((adUnitCode) => { - if (winners[adUnitCode]) { - let bidId = winners[adUnitCode].bidId; - updateBidStats(args.auctionId, bidId, {response: 4}); - } - }) - _logInfo('Auction End', args); - _logInfo('Auction Cache', auctionCache[args.auctionId].stats); -} -function handlerBidWon(args) { - let {auctionId, requestId} = args; - let res = updateBidStats(auctionId, requestId, {p: 3, response: 6}); - _logInfo('Bid Won ', args); - _logInfo('Bid Update Result: ', res); -} -function handlerBidResponse(args) { - let {auctionId, requestId, cpm, size, timeToRespond} = args; - updateBidStats(auctionId, requestId, {bid: cpm, s: size, jsLatency: timeToRespond, latency: timeToRespond, p: 2, response: 9}); - - _logInfo('Bid Response ', args); -} -function handlerBidTimeout(args) { - let {auctionId, bidId} = args; - _logInfo('Bid Timeout ', args); - updateBidStats(auctionId, bidId, {p: 2, response: 0, latency: args.timeout, jsLatency: args.timeout}); -} -let sonobiAdapter = Object.assign(adapter({url: DEFAULT_EVENT_URL, analyticsType}), { - track({eventType, args}) { - switch (eventType) { - case AUCTION_INIT: - handlerAuctionInit(args); - break; - case BID_REQUESTED: - handlerBidRequested(args); - break; - case BID_ADJUSTMENT: - handlerBidAdjustment(args); - break; - case BIDDER_DONE: - handlerBidderDone(args); - break; - case AUCTION_END: - handlerAuctionEnd(args); - break; - case BID_WON: - handlerBidWon(args); - break; - case BID_RESPONSE: - handlerBidResponse(args); - break; - case BID_TIMEOUT: - handlerBidTimeout(args); - break; - default: - handleOtherEvents(eventType, args); - break; - } - }, - -}); - -sonobiAdapter.originEnableAnalytics = sonobiAdapter.enableAnalytics; - -sonobiAdapter.enableAnalytics = function (config) { - if (this.initConfig(config)) { - _logInfo('Analytics adapter enabled', initOptions); - sonobiAdapter.originEnableAnalytics(config); - } -}; - -sonobiAdapter.initConfig = function (config) { - let isCorrectConfig = true; - initOptions = {}; - initOptions.options = deepClone(config.options); - - initOptions.pubId = initOptions.options.pubId || null; - initOptions.siteId = initOptions.options.siteId || null; - initOptions.delay = initOptions.options.delay || QUEUE_TIMEOUT_DEFAULT; - if (!initOptions.pubId) { - _logError('"options.pubId" is empty'); - isCorrectConfig = false; - } - if (!initOptions.siteId) { - _logError('"options.siteId" is empty'); - isCorrectConfig = false; - } - - initOptions.server = DEFAULT_EVENT_URL; - initOptions.host = initOptions.options.host || window.location.hostname; - this.initOptions = initOptions; - return isCorrectConfig; -}; - -sonobiAdapter.getOptions = function () { - return initOptions; -}; - -sonobiAdapter.sendData = function (auction, data) { - let url = 'https://' + initOptions.server + '?pageviewid=' + auction.id + '&corscred=1&pubId=' + initOptions.pubId + '&siteId=' + initOptions.siteId; - ajax( - url, - function () { _logInfo('Auction [' + auction.id + '] sent ', data); }, - JSON.stringify(data), - { - method: 'POST', - // withCredentials: true, - contentType: 'text/plain' - } - ); -}; - -function _logInfo(message, meta) { - logInfo(buildLogMessage(message), meta); -} - -function _logError(message) { - logError(buildLogMessage(message)); -} - -function buildLogMessage(message) { - return 'Sonobi Prebid Analytics: ' + message; -} - -adapterManager.registerAnalyticsAdapter({ - adapter: sonobiAdapter, - code: 'sonobi' -}); - -export default sonobiAdapter; diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js index edc4f255d18..720ce8ee269 100644 --- a/modules/sonobiBidAdapter.js +++ b/modules/sonobiBidAdapter.js @@ -414,8 +414,6 @@ export function _getPlatform(context = window) { * @return {object} firstPartyData - Data object containing first party information */ function loadOrCreateFirstPartyData() { - var localStorageEnabled; - var FIRST_PARTY_KEY = '_iiq_fdata'; var tryParse = function (data) { try { @@ -426,19 +424,14 @@ function loadOrCreateFirstPartyData() { }; var readData = function (key) { if (hasLocalStorage()) { + // TODO FIX RULES VIOLATION + // eslint-disable-next-line prebid/no-global return window.localStorage.getItem(key); } return null; }; + // TODO FIX RULES VIOLATION - USE STORAGE MANAGER var hasLocalStorage = function () { - if (typeof localStorageEnabled != 'undefined') { return localStorageEnabled; } else { - try { - localStorageEnabled = !!window.localStorage; - return localStorageEnabled; - } catch (e) { - localStorageEnabled = false; - } - } return false; }; var generateGUID = function () { @@ -452,6 +445,8 @@ function loadOrCreateFirstPartyData() { var storeData = function (key, value) { try { if (hasLocalStorage()) { + // TODO FIX RULES VIOLATION + // eslint-disable-next-line prebid/no-global window.localStorage.setItem(key, value); } } catch (error) { diff --git a/modules/sovrnAnalyticsAdapter.js b/modules/sovrnAnalyticsAdapter.js deleted file mode 100644 index a89b365e074..00000000000 --- a/modules/sovrnAnalyticsAdapter.js +++ /dev/null @@ -1,287 +0,0 @@ -import {logError, timestamp} from '../src/utils.js'; -import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import adaptermanager from '../src/adapterManager.js'; -import { EVENTS } from '../src/constants.js'; -import {ajaxBuilder} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {find, includes} from '../src/polyfill.js'; -import {getRefererInfo} from '../src/refererDetection.js'; - -const ajax = ajaxBuilder(0) - -const { - AUCTION_END, - BID_REQUESTED, - BID_ADJUSTMENT, - BID_RESPONSE, - BID_WON -} = EVENTS; - -let pbaUrl = 'https://pba.aws.lijit.com/analytics' -let currentAuctions = {}; -const analyticsType = 'endpoint' - -const rootURL = (() => { - const ref = getRefererInfo(); - // TODO: does the fallback make sense here? - return ref.page || ref.topmostLocation; -})(); - -let sovrnAnalyticsAdapter = Object.assign(adapter({url: pbaUrl, analyticsType}), { - track({ eventType, args }) { - try { - if (eventType === BID_WON) { - new BidWinner(this.sovrnId, args).send(); - return - } - if (args && args.auctionId && currentAuctions[args.auctionId] && currentAuctions[args.auctionId].status === 'complete') { - throw new Error('Event Received after Auction Close Auction Id ' + args.auctionId) - } - if (args && args.auctionId && currentAuctions[args.auctionId] === undefined) { - currentAuctions[args.auctionId] = new AuctionData(this.sovrnId, args.auctionId) - } - switch (eventType) { - case BID_REQUESTED: - currentAuctions[args.auctionId].bidRequested(args) - break - case BID_ADJUSTMENT: - currentAuctions[args.auctionId].originalBid(args) - break - case BID_RESPONSE: - currentAuctions[args.auctionId].adjustedBid(args) - break - case AUCTION_END: - currentAuctions[args.auctionId].send(); - break - } - } catch (e) { - new LogError(e, this.sovrnId, {eventType, args}).send() - } - }, -}) - -sovrnAnalyticsAdapter.getAuctions = function () { - return currentAuctions; -}; - -sovrnAnalyticsAdapter.originEnableAnalytics = sovrnAnalyticsAdapter.enableAnalytics; - -// override enableAnalytics so we can get access to the config passed in from the page -sovrnAnalyticsAdapter.enableAnalytics = function (config) { - let sovrnId = '' - if (config && config.options && (config.options.sovrnId || config.options.affiliateId)) { - sovrnId = config.options.sovrnId || config.options.affiliateId; - } else { - logError('Need Sovrn Id to log auction results. Please contact a Sovrn representative if you do not know your Sovrn Id.') - return - } - sovrnAnalyticsAdapter.sovrnId = sovrnId; - if (config.options.pbaUrl) { - pbaUrl = config.options.pbaUrl; - } - sovrnAnalyticsAdapter.originEnableAnalytics(config) // call the base class function -}; - -adaptermanager.registerAnalyticsAdapter({ - adapter: sovrnAnalyticsAdapter, - code: 'sovrn' -}); - -/** Class Representing a Winning Bid */ -class BidWinner { - /** - * Creates a new bid winner - * @param {string} sovrnId - the affiliate id from the analytics config - * @param {*} event - the args object from the auction event - */ - constructor(sovrnId, event) { - this.body = {} - // eslint-disable-next-line no-undef - this.body.prebidVersion = $$REPO_AND_VERSION$$ - this.body.sovrnId = sovrnId - this.body.winningBid = JSON.parse(JSON.stringify(event)) - this.body.url = rootURL - this.body.payload = 'winner' - delete this.body.winningBid.ad - } - - /** - * Sends the auction to the the ingest server - */ - send() { - this.body.ts = timestamp() - ajax( - pbaUrl, - null, - JSON.stringify(this.body), - { - contentType: 'application/json', - method: 'POST', - } - ) - } -} - -/** Class representing an Auction */ -class AuctionData { - /** - * Create a new auction data collector - * @param {string} sovrnId - the affiliate id from the analytics config - * @param {string} auctionId - the auction id from the auction event - */ - constructor(sovrnId, auctionId) { - this.auction = {} - // eslint-disable-next-line no-undef - this.auction.prebidVersion = $$REPO_AND_VERSION$$ - this.auction.sovrnId = sovrnId - this.auction.auctionId = auctionId - this.auction.payload = 'auction' - this.auction.timeouts = { - buffer: config.getConfig('timeoutBuffer'), - bidder: config.getConfig('bidderTimeout'), - } - this.auction.priceGranularity = config.getConfig('priceGranularity') - this.auction.url = rootURL - this.auction.requests = [] - this.auction.unsynced = [] - this.dropBidFields = ['auctionId', 'ad', 'requestId', 'bidderCode'] - - setTimeout(function(id) { - delete currentAuctions[id] - }, 300000, this.auction.auctionId) - } - - /** - * Record a bid request event - * @param {*} event - the args object from the auction event - */ - bidRequested(event) { - const eventCopy = JSON.parse(JSON.stringify(event)) - delete eventCopy.doneCbCallCount - delete eventCopy.auctionId - this.auction.requests.push(eventCopy) - } - - /** - * Finds the bid from the auction that the event is associated with - * @param {*} event - the args object from the auction event - * @return {*} - the bid - */ - findBid(event) { - const bidder = find(this.auction.requests, r => (r.bidderCode === event.bidderCode)) - if (!bidder) { - this.auction.unsynced.push(JSON.parse(JSON.stringify(event))) - } - let bid = find(bidder.bids, b => (b.bidId === event.requestId)) - - if (!bid) { - event.unmatched = true - bidder.bids.push(JSON.parse(JSON.stringify(event))) - } - return bid - } - - /** - * Records the original bid before any adjustments have been made - * @param {*} event - the args object from the auction event - * NOTE: the bid adjustment occurs before the bid response - * the bid adjustment seems to be the bid ready to be adjusted - */ - originalBid(event) { - let bid = this.findBid(event) - if (bid) { - Object.assign(bid, JSON.parse(JSON.stringify(event))) - this.dropBidFields.forEach((f) => delete bid[f]) - } - } - - /** - * Replaces original values with adjusted values and records the original values for changed values - * in bid.originalValues - * @param {*} event - the args object from the auction event - */ - adjustedBid(event) { - let bid = this.findBid(event) - if (bid) { - bid.originalValues = Object.keys(event).reduce((o, k) => { - if (JSON.stringify(bid[k]) !== JSON.stringify(event[k]) && !includes(this.dropBidFields, k)) { - o[k] = bid[k] - bid[k] = event[k] - } - return o - }, {}) - } - } - - /** - * Sends the auction to the the ingest server - */ - send() { - let maxBids = {} - this.auction.requests.forEach(request => { - request.bids.forEach(bid => { - maxBids[bid.adUnitCode] = maxBids[bid.adUnitCode] || {cpm: 0} - if (bid.cpm > maxBids[bid.adUnitCode].cpm) { - maxBids[bid.adUnitCode] = bid - } - }) - }) - Object.keys(maxBids).forEach(unit => { - maxBids[unit].isAuctionWinner = true - }) - this.auction.ts = timestamp() - ajax( - pbaUrl, - () => { - currentAuctions[this.auction.auctionId] = {status: 'complete', auctionId: this.auction.auctionId} - }, - JSON.stringify(this.auction), - { - contentType: 'application/json', - method: 'POST', - } - ) - } -} -class LogError { - constructor(e, sovrnId, data) { - this.error = {} - this.error.payload = 'error' - this.error.message = e.message - this.error.stack = e.stack - this.error.data = data - // eslint-disable-next-line no-undef - this.error.prebidVersion = $$REPO_AND_VERSION$$ - this.error.sovrnId = sovrnId - this.error.url = rootURL - this.error.userAgent = navigator.userAgent - } - send() { - if (this.error.data && this.error.data.requests) { - this.error.data.requests.forEach(request => { - if (request.bids) { - request.bids.forEach(bid => { - if (bid.ad) { - delete bid.ad - } - }) - } - }) - } - if (ErrorEvent.data && this.error.data.ad) { - delete this.error.data.ad - } - this.error.ts = timestamp() - ajax( - pbaUrl, - null, - JSON.stringify(this.error), - { - contentType: 'application/json', - method: 'POST', - } - ) - } -} - -export default sovrnAnalyticsAdapter; diff --git a/modules/sovrnAnalyticsAdapter.md b/modules/sovrnAnalyticsAdapter.md deleted file mode 100644 index b4fe7c971a2..00000000000 --- a/modules/sovrnAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview - -``` -Module Name: Sovrn Analytics Adapter -Module Type: Analytics Adapter -Maintainer: exchange@sovrn.com -``` - -# Description - -Sovrn's analytics adaptor allows you to view detailed auction information in Meridian. - -For more information, visit Sovrn.com. - -# Test Parameters -``` -{ - provider: 'sovrn', - options: { - sovrnId: 'xxxxx', // Sovrn ID (required) you can get this by contacting Sovrn support. - } -} -``` diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index b6563cac4c5..53f6fb2f40d 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -28,6 +28,7 @@ const ORTB_VIDEO_PARAMS = { 'h': (value) => isInteger(value), 'startdelay': (value) => isInteger(value), 'placement': (value) => isInteger(value) && value >= 1 && value <= 5, + 'plcmt': (value) => isInteger(value) && value >= 1 && value <= 4, 'linearity': (value) => [1, 2].indexOf(value) !== -1, 'skip': (value) => [0, 1].indexOf(value) !== -1, 'skipmin': (value) => isInteger(value), @@ -139,7 +140,7 @@ export const spec = { } const auctionEnvironment = bid?.ortb2Imp?.ext?.ae - if (bidderRequest.fledgeEnabled && isInteger(auctionEnvironment)) { + if (bidderRequest.paapi?.enabled && isInteger(auctionEnvironment)) { imp.ext = imp.ext || {} imp.ext.ae = auctionEnvironment } else { @@ -288,7 +289,7 @@ export const spec = { }) return { bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, } } return bids diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js deleted file mode 100644 index c1f1c5159fc..00000000000 --- a/modules/spotxBidAdapter.js +++ /dev/null @@ -1,528 +0,0 @@ -import { - logError, - deepAccess, - isArray, - getDNT, - deepSetValue, - isEmpty, - _each, - logMessage, - logWarn, - isBoolean, - isNumber, - isPlainObject, - isFn, - setScriptAttributes, - getBidIdParameter -} from '../src/utils.js'; -import { config } from '../src/config.js'; -import { Renderer } from '../src/Renderer.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO } from '../src/mediaTypes.js'; -import { loadExternalScript } from '../src/adloader.js'; - -/** - * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest - * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid - * @typedef {import('../src/adapters/bidderFactory.js').ServerRequest} ServerRequest - */ - -const BIDDER_CODE = 'spotx'; -const URL = 'https://search.spotxchange.com/openrtb/2.3/dados/'; -const ORTB_VERSION = '2.3'; -export const GOOGLE_CONSENT = { consented_providers: ['3', '7', '11', '12', '15', '20', '22', '35', '43', '46', '48', '55', '57', '61', '62', '66', '70', '80', '83', '85', '86', '89', '93', '108', '122', '124', '125', '126', '131', '134', '135', '136', '143', '144', '147', '149', '153', '154', '159', '161', '162', '165', '167', '171', '178', '184', '188', '192', '195', '196', '202', '209', '211', '218', '221', '228', '229', '230', '236', '239', '241', '253', '255', '259', '266', '271', '272', '274', '286', '291', '294', '303', '308', '310', '311', '313', '314', '316', '317', '322', '323', '327', '336', '338', '340', '348', '350', '358', '359', '363', '367', '370', '371', '384', '385', '389', '393', '394', '397', '398', '407', '414', '415', '424', '429', '430', '432', '436', '438', '440', '442', '443', '445', '448', '449', '453', '459', '479', '482', '486', '491', '492', '494', '495', '503', '505', '510', '522', '523', '528', '537', '540', '550', '559', '560', '568', '571', '574', '575', '576', '584', '585', '587', '588', '590', '591', '592', '595', '609', '621', '624', '723', '725', '733', '737', '776', '780', '782', '787', '797', '798', '802', '803', '814', '817', '820', '821', '827', '829', '839', '853', '864', '867', '874', '899', '904', '922', '926', '931', '932', '933', '938', '955', '973', '976', '979', '981', '985', '987', '991', '1003', '1024', '1025', '1027', '1028', '1029', '1033', '1034', '1040', '1047', '1048', '1051', '1052', '1053', '1054', '1062', '1063', '1067', '1072', '1085', '1092', '1095', '1097', '1099', '1100', '1107', '1126', '1127', '1143', '1149', '1152', '1162', '1166', '1167', '1170', '1171', '1172', '1188', '1192', '1199', '1201', '1204', '1205', '1211', '1212', '1215', '1220', '1225', '1226', '1227', '1230', '1232', '1236', '1241', '1248', '1250', '1252', '1268', '1275', '1276', '1284', '1286', '1298', '1301', '1307', '1312', '1313', '1317', '1329', '1336', '1344', '1345', '1356', '1362', '1365', '1375', '1403', '1409', '1411', '1415', '1416', '1419', '1423', '1440', '1442', '1449', '1451', '1455', '1456', '1468', '1496', '1503', '1509', '1512', '1514', '1517', '1520', '1525', '1540', '1547', '1548', '1555', '1558', '1570', '1575', '1577', '1579', '1583', '1584', '1591', '1598', '1603', '1608', '1613', '1616', '1626', '1631', '1633', '1638', '1642', '1648', '1651', '1652', '1653', '1660', '1665', '1667', '1669', '1671', '1674', '1677', '1678', '1682', '1684', '1697', '1703', '1705', '1716', '1720', '1721', '1722', '1725', '1732', '1733', '1735', '1739', '1741', '1745', '1750', '1753', '1760', '1765', '1769', '1776', '1780', '1782', '1786', '1791', '1794', '1799', '1800', '1801', '1810', '1827', '1831', '1832', '1834', '1837', '1840', '1843', '1844', '1845', '1858', '1859', '1863', '1866', '1870', '1872', '1875', '1878', '1880', '1882', '1883', '1889', '1892', '1896', '1898', '1899', '1902', '1905', '1911', '1922', '1928', '1929', '1934', '1942', '1943', '1944', '1945', '1958', '1960', '1962', '1963', '1964', '1967', '1968', '1978', '1985', '1986', '1987', '1998', '2003', '2007', '2012', '2013', '2027', '2035', '2038', '2039', '2044', '2047', '2052', '2056', '2059', '2062', '2064', '2068', '2070', '2072', '2078', '2079', '2084', '2088', '2090', '2095', '2100', '2103', '2107', '2109', '2113', '2115', '2121', '2127', '2130', '2133', '2137', '2140', '2141', '2145', '2147', '2150', '2156', '2166', '2170', '2171', '2176', '2177', '2179', '2183', '2186', '2192', '2198', '2202', '2205', '2214', '2216', '2219', '2220', '2222', '2223', '2224', '2225', '2227', '2228', '2234', '2238', '2247', '2251', '2253', '2262', '2264', '2271', '2276', '2278', '2279', '2282', '2290', '2292', '2295', '2299', '2305', '2306', '2310', '2311', '2312', '2315', '2320', '2325', '2328', '2331', '2334', '2335', '2336', '2337', '2343', '2346', '2354', '2357', '2358', '2359', '2366', '2370', '2373', '2376', '2377', '2380', '2382', '2387', '2389', '2392', '2394', '2400', '2403', '2405', '2406', '2407', '2410', '2411', '2413', '2414', '2415', '2416', '2418', '2422', '2425', '2427', '2435', '2437', '2440', '2441', '2447', '2453', '2459', '2461', '2462', '2464', '2467', '2468', '2472', '2477', '2481', '2484', '2486', '2492', '2493', '2496', '2497', '2498', '2499', '2504', '2506', '2510', '2511', '2512', '2517', '2526', '2527', '2531', '2532', '2534', '2542', '2544', '2552', '2555', '2559', '2563', '2564', '2567', '2568', '2569', '2571', '2572', '2573', '2575', '2577', '2579', '2583', '2584', '2586', '2589', '2595', '2596', '2597', '2601', '2604', '2605', '2609', '2610', '2612', '2614', '2621', '2622', '2624', '2628', '2629', '2632', '2634', '2636', '2639', '2643', '2645', '2646', '2647', '2649', '2650', '2651', '2652', '2656', '2657', '2658', '2660', '2661', '2662', '2663', '2664', '2669', '2670', '2673', '2676', '2677', '2678', '2681', '2682', '2684', '2685', '2686', '2689', '2690', '2691', '2695', '2698', '2699', '2702', '2704', '2705', '2706', '2707', '2709', '2710', '2713', '2714', '2727', '2729', '2739', '2758', '2765', '2766', '2767', '2768', '2770', '2771', '2772', '2776', '2777', '2778', '2779', '2780', '2783', '2784', '2786', '2787', '2791', '2792', '2793', '2797', '2798', '2801', '2802', '2803', '2805', '2808', '2809', '2810', '2811', '2812', '2813', '2814', '2817', '2818', '2824', '2826', '2827', '2829', '2830', '2831', '2832', '2834', '2836', '2838', '2840', '2842', '2843', '2844', '2850', '2851', '2852', '2854', '2858', '2860', '2862', '2864', '2865', '2866', '2867', '2868', '2869', '2871'] }; - -export const spec = { - code: BIDDER_CODE, - gvlid: 165, - supportedMediaTypes: [VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * From Prebid.js: isBidRequestValid - Verify the the AdUnits.bids, respond with true (valid) or false (invalid). - * - * @param {object} bid The bid to validate. - * @return {boolean} True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - if (bid && typeof bid.params !== 'object') { - logError(BIDDER_CODE + ': params is not defined or is incorrect in the bidder settings.'); - return false; - } - - if (!deepAccess(bid, 'mediaTypes.video')) { - logError(BIDDER_CODE + ': mediaTypes.video is not present in the bidder settings.'); - return false; - } - - const playerSize = deepAccess(bid, 'mediaTypes.video.playerSize'); - if (!playerSize || !isArray(playerSize)) { - logError(BIDDER_CODE + ': mediaTypes.video.playerSize is not defined in the bidder settings.'); - return false; - } - - if (!getBidIdParameter('channel_id', bid.params)) { - logError(BIDDER_CODE + ': channel_id is not present in bidder params'); - return false; - } - - if (deepAccess(bid, 'mediaTypes.video.context') == 'outstream' || deepAccess(bid, 'params.ad_unit') == 'outstream') { - if (!getBidIdParameter('outstream_function', bid.params)) { - if (!getBidIdParameter('outstream_options', bid.params)) { - logError(BIDDER_CODE + ': please define outstream_options parameter or override the default SpotX outstream rendering by defining your own Outstream function using field outstream_function.'); - return false; - } - if (!getBidIdParameter('slot', bid.params.outstream_options)) { - logError(BIDDER_CODE + ': please define parameter slot in outstream_options object in the configuration.'); - return false; - } - } - } - - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * from Prebid.js: buildRequests - Takes an array of valid bid requests, all of which are guaranteed to have passed the isBidRequestValid() test. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @param {object} bidderRequest - The master bidRequest object. - * @return {ServerRequest} Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - // TODO: does the fallback make sense here? - const referer = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const isPageSecure = !!referer.match(/^https:/); - - const siteId = ''; - const spotxRequests = bidRequests.map(function(bid) { - let page; - if (getBidIdParameter('page', bid.params)) { - page = getBidIdParameter('page', bid.params); - } else { - page = referer; - } - - const channelId = getBidIdParameter('channel_id', bid.params); - let pubcid = null; - - const playerSize = deepAccess(bid, 'mediaTypes.video.playerSize'); - const contentWidth = playerSize[0][0]; - const contentHeight = playerSize[0][1]; - - const secure = isPageSecure || (getBidIdParameter('secure', bid.params) ? 1 : 0); - - const ext = { - sdk_name: 'Prebid 1+', - versionOrtb: ORTB_VERSION - }; - - if (getBidIdParameter('hide_skin', bid.params) != '') { - ext.hide_skin = +!!getBidIdParameter('hide_skin', bid.params); - } - - if (getBidIdParameter('ad_volume', bid.params) != '') { - ext.ad_volume = getBidIdParameter('ad_volume', bid.params); - } - - if (getBidIdParameter('ad_unit', bid.params) != '') { - ext.ad_unit = getBidIdParameter('ad_unit', bid.params); - } - - if (getBidIdParameter('outstream_options', bid.params) != '') { - ext.outstream_options = getBidIdParameter('outstream_options', bid.params); - } - - if (getBidIdParameter('outstream_function', bid.params) != '') { - ext.outstream_function = getBidIdParameter('outstream_function', bid.params); - } - - if (getBidIdParameter('custom', bid.params) != '') { - ext.custom = getBidIdParameter('custom', bid.params); - } - - if (getBidIdParameter('pre_market_bids', bid.params) != '' && isArray(getBidIdParameter('pre_market_bids', bid.params))) { - const preMarketBids = getBidIdParameter('pre_market_bids', bid.params); - ext.pre_market_bids = []; - for (let i in preMarketBids) { - const preMarketBid = preMarketBids[i]; - let vastStr = ''; - if (preMarketBid['vast_url']) { - vastStr = '' + preMarketBid['vast_url'] + ''; - } else if (preMarketBid['vast_string']) { - vastStr = preMarketBid['vast_string']; - } - ext.pre_market_bids.push({ - id: preMarketBid['deal_id'], - seatbid: [{ - bid: [{ - impid: Date.now(), - dealid: preMarketBid['deal_id'], - price: preMarketBid['price'], - adm: vastStr - }] - }], - cur: preMarketBid['currency'], - ext: { - event_log: [{}] - } - }); - } - } - - const mimes = getBidIdParameter('mimes', bid.params) || deepAccess(bid, 'mediaTypes.video.mimes') || ['application/javascript', 'video/mp4', 'video/webm']; - - const spotxReq = { - id: bid.bidId, - secure: secure, - video: { - w: contentWidth, - h: contentHeight, - ext: ext, - mimes: mimes - } - }; - - if (isFn(bid.getFloor)) { - let floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: 'video', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - spotxReq.bidfloor = floorInfo.floor; - } - } else if (getBidIdParameter('price_floor', bid.params) != '') { - spotxReq.bidfloor = getBidIdParameter('price_floor', bid.params); - } - - const startdelay = getBidIdParameter('start_delay', bid.params) || deepAccess(bid, 'mediaTypes.video.startdelay'); - if (startdelay) { - spotxReq.video.startdelay = 0 + Boolean(startdelay); - } - - const minduration = getBidIdParameter('min_duration', bid.params) || deepAccess(bid, 'mediaTypes.video.minduration'); - if (minduration) { - spotxReq.video.minduration = minduration; - } - - const maxduration = getBidIdParameter('max_duration', bid.params) || deepAccess(bid, 'mediaTypes.video.maxduration'); - if (maxduration) { - spotxReq.video.maxduration = maxduration; - } - - const placement = getBidIdParameter('placement_type', bid.params) || deepAccess(bid, 'mediaTypes.video.placement'); - if (placement) { - spotxReq.video.ext.placement = placement; - } - - const position = getBidIdParameter('position', bid.params) || deepAccess(bid, 'mediaTypes.video.pos'); - if (position) { - spotxReq.video.ext.pos = position; - } - - if (bid.crumbs && bid.crumbs.pubcid) { - pubcid = bid.crumbs.pubcid; - } - - const language = navigator.language ? 'language' : 'userLanguage'; - const device = { - h: screen.height, - w: screen.width, - dnt: getDNT() ? 1 : 0, - language: navigator[language].split('-')[0], - make: navigator.vendor ? navigator.vendor : '', - ua: navigator.userAgent - }; - - const requestPayload = { - id: channelId, - imp: spotxReq, - site: { - id: siteId, - page: page, - content: 'content', - }, - device: device, - ext: { - wrap_response: 1 - } - }; - - // If the publisher asks to ignore the bidder cache key we need to return the full vast xml - // so that it can be cached on the publishes specified server. - if (!!config.getConfig('cache') && !!config.getConfig('cache.url') && (config.getConfig('cache.ignoreBidderCacheKey') === true)) { - requestPayload['ext']['wrap_response'] = 0; - } - - if (getBidIdParameter('number_of_ads', bid.params)) { - requestPayload['ext']['number_of_ads'] = getBidIdParameter('number_of_ads', bid.params); - } - - const userExt = {}; - - if (getBidIdParameter('spotx_all_google_consent', bid.params) == 1) { - userExt['consented_providers_settings'] = GOOGLE_CONSENT; - } - - // Add GDPR flag and consent string - if (bidderRequest && bidderRequest.gdprConsent) { - userExt.consent = bidderRequest.gdprConsent.consentString; - - if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { - deepSetValue(requestPayload, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); - } - } - - if (bidderRequest && bidderRequest.uspConsent) { - deepSetValue(requestPayload, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (bid.userIdAsEids) { - userExt.eids = bid.userIdAsEids; - - userExt.eids.forEach(eid => { - if (eid.source === 'uidapi.com') { - eid.uids.forEach(uid => { - uid.ext = uid.ext || {}; - uid.ext.rtiPartner = 'UID2' - }); - } - }); - } - - // Add common id if available - if (pubcid) { - userExt.fpc = pubcid; - } - - // Add schain object if it is present - if (bid && bid.schain) { - requestPayload['source'] = { - ext: { - schain: bid.schain - } - }; - } - - // Only add the user object if it's not empty - if (!isEmpty(userExt)) { - requestPayload.user = { ext: userExt }; - } - const urlQueryParams = 'src_sys=prebid'; - return { - method: 'POST', - url: URL + channelId + '?' + urlQueryParams, - data: requestPayload, - bidRequest: bidderRequest - }; - }); - - return spotxRequests; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidderRequest) { - const bidResponses = []; - const serverResponseBody = serverResponse.body; - - if (serverResponseBody && isArray(serverResponseBody.seatbid)) { - _each(serverResponseBody.seatbid, function(bids) { - _each(bids.bid, function(spotxBid) { - let currentBidRequest = {}; - for (let i in bidderRequest.bidRequest.bids) { - if (spotxBid.impid == bidderRequest.bidRequest.bids[i].bidId) { - currentBidRequest = bidderRequest.bidRequest.bids[i]; - } - } - - /** - * Make sure currency and price are the right ones - * TODO: what about the pre_market_bid partners sizes? - */ - _each(currentBidRequest.params.pre_market_bids, function(pmb) { - if (pmb.deal_id == spotxBid.id) { - spotxBid.price = pmb.price; - serverResponseBody.cur = pmb.currency; - } - }); - - const bid = { - requestId: currentBidRequest.bidId, - currency: serverResponseBody.cur || 'USD', - cpm: spotxBid.price, - creativeId: spotxBid.crid || '', - dealId: spotxBid.dealid || '', - ttl: 360, - netRevenue: true, - channel_id: serverResponseBody.id, - mediaType: VIDEO, - width: spotxBid.w, - height: spotxBid.h - }; - - if (!!config.getConfig('cache') && !!config.getConfig('cache.url') && (config.getConfig('cache.ignoreBidderCacheKey') === true)) { - bid.vastXml = spotxBid.adm; - } else { - bid.cache_key = spotxBid.ext.cache_key; - bid.vastUrl = 'https://search.spotxchange.com/ad/vast.html?key=' + spotxBid.ext.cache_key; - bid.videoCacheKey = spotxBid.ext.cache_key; - } - - bid.meta = bid.meta || {}; - if (spotxBid && spotxBid.adomain && spotxBid.adomain.length > 0) { - bid.meta.advertiserDomains = spotxBid.adomain; - } - - const context1 = deepAccess(currentBidRequest, 'mediaTypes.video.context'); - const context2 = deepAccess(currentBidRequest, 'params.ad_unit'); - if (context1 == 'outstream' || context2 == 'outstream') { - const playersize = deepAccess(currentBidRequest, 'mediaTypes.video.playerSize'); - const renderer = Renderer.install({ - id: 0, - renderNow: true, - url: '/', - config: { - adText: 'SpotX Outstream Video Ad via Prebid.js', - player_width: playersize[0][0], - player_height: playersize[0][1], - content_page_url: deepAccess(bidderRequest, 'data.site.page'), - ad_mute: +!!deepAccess(currentBidRequest, 'params.ad_mute'), - hide_skin: +!!deepAccess(currentBidRequest, 'params.hide_skin'), - outstream_options: deepAccess(currentBidRequest, 'params.outstream_options'), - outstream_function: deepAccess(currentBidRequest, 'params.outstream_function') - } - }); - - try { - renderer.setRender(outstreamRender); - renderer.setEventHandlers({ - impression: function impression() { - return logMessage('SpotX outstream video impression event'); - }, - loaded: function loaded() { - return logMessage('SpotX outstream video loaded event'); - }, - ended: function ended() { - logMessage('SpotX outstream renderer video event'); - } - }); - } catch (err) { - logWarn('Prebid Error calling setRender or setEventHandlers on renderer', err); - } - bid.renderer = renderer; - } - - bidResponses.push(bid); - }) - }); - } - - return bidResponses; - } -} - -function createOutstreamScript(bid) { - const script = window.document.createElement('script'); - let dataSpotXParams = createScriptAttributeMap(bid); - - script.type = 'text/javascript'; - script.src = 'https://js.spotx.tv/easi/v1/' + bid.channel_id + '.js'; - - setScriptAttributes(script, dataSpotXParams); - - return script; -} - -function outstreamRender(bid) { - if (bid.renderer.config.outstream_function != null && typeof bid.renderer.config.outstream_function === 'function') { - const script = createOutstreamScript(bid); - bid.renderer.config.outstream_function(bid, script); - } else { - try { - const inIframe = getBidIdParameter('in_iframe', bid.renderer.config.outstream_options); - const easiUrl = 'https://js.spotx.tv/easi/v1/' + bid.channel_id + '.js'; - let attributes = createScriptAttributeMap(bid); - if (inIframe && window.document.getElementById(inIframe).nodeName == 'IFRAME') { - const rawframe = window.document.getElementById(inIframe); - let framedoc = rawframe.contentDocument; - if (!framedoc && rawframe.contentWindow) { - framedoc = rawframe.contentWindow.document; - } - loadExternalScript(easiUrl, BIDDER_CODE, undefined, framedoc, attributes); - } else { - loadExternalScript(easiUrl, BIDDER_CODE, undefined, undefined, attributes); - } - } catch (err) { - logError('[SPOTX][renderer] Error:' + err.message); - } - } -} - -function createScriptAttributeMap(bid) { - const slot = getBidIdParameter('slot', bid.renderer.config.outstream_options); - logMessage('[SPOTX][renderer] Handle SpotX outstream renderer'); - let dataSpotXParams = {}; - dataSpotXParams['data-spotx_channel_id'] = '' + bid.channel_id; - dataSpotXParams['data-spotx_vast_url'] = '' + bid.vastUrl; - dataSpotXParams['data-spotx_content_page_url'] = bid.renderer.config.content_page_url; - dataSpotXParams['data-spotx_ad_unit'] = 'incontent'; - - logMessage('[SPOTX][renderer] Default behavior'); - if (getBidIdParameter('ad_mute', bid.renderer.config.outstream_options)) { - dataSpotXParams['data-spotx_ad_mute'] = '1'; - } - dataSpotXParams['data-spotx_collapse'] = '0'; - dataSpotXParams['data-spotx_autoplay'] = '1'; - dataSpotXParams['data-spotx_blocked_autoplay_override_mode'] = '1'; - dataSpotXParams['data-spotx_video_slot_can_autoplay'] = '1'; - dataSpotXParams['data-spotx_content_container_id'] = slot; - - const playersizeAutoAdapt = getBidIdParameter('playersize_auto_adapt', bid.renderer.config.outstream_options); - if (playersizeAutoAdapt && isBoolean(playersizeAutoAdapt) && playersizeAutoAdapt === true) { - const ratio = bid.width && isNumber(bid.width) && bid.height && isNumber(bid.height) ? bid.width / bid.height : 4 / 3; - const slotClientWidth = window.document.getElementById(slot).clientWidth; - let playerWidth = bid.renderer.config.player_width; - let playerHeight = bid.renderer.config.player_height; - let contentWidth = 0; - let contentHeight = 0; - if (slotClientWidth < playerWidth) { - playerWidth = slotClientWidth; - playerHeight = playerWidth / ratio; - } - if (ratio <= 1) { - contentWidth = Math.round(playerHeight * ratio); - contentHeight = playerHeight; - } else { - contentWidth = playerWidth; - contentHeight = Math.round(playerWidth / ratio); - } - - dataSpotXParams['data-spotx_content_width'] = '' + contentWidth; - dataSpotXParams['data-spotx_content_height'] = '' + contentHeight; - } - - const customOverride = getBidIdParameter('custom_override', bid.renderer.config.outstream_options); - if (customOverride && isPlainObject(customOverride)) { - logMessage('[SPOTX][renderer] Custom behavior.'); - for (let name in customOverride) { - if (customOverride.hasOwnProperty(name)) { - if (name === 'channel_id' || name === 'vast_url' || name === 'content_page_url' || name === 'ad_unit') { - logWarn('[SPOTX][renderer] Custom behavior: following option cannot be overridden: ' + name); - } else { - dataSpotXParams['data-spotx_' + name] = customOverride[name]; - } - } - } - } - return dataSpotXParams; -} - -registerBidder(spec); diff --git a/modules/spotxBidAdapter.md b/modules/spotxBidAdapter.md deleted file mode 100644 index 0bd1cf71aa1..00000000000 --- a/modules/spotxBidAdapter.md +++ /dev/null @@ -1,136 +0,0 @@ -# Overview - -``` -Module Name: SpotX Bidder Adapter -Module Type: Bidder Adapter -Maintainer: teameighties@spotx.tv -``` - -# Description - -Connect to SpotX for bids. - -This adapter requires setup and approval from the SpotX team. - -# Test Parameters - Use case #1 - outstream with default rendering options -``` - var adUnits = [{ - code: 'something', - mediaTypes: { - video: { - context: 'outstream', // 'instream' or 'outstream' - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'spotx', - params: { - channel_id: 85394, - ad_unit: 'outstream', - outstream_options: { // Needed for the default outstream renderer - fields video_slot/content_width/content_height are mandatory - slot: 'adSlot1', - content_width: 300, - content_height: 250 - } - } - }] - }]; -``` - -# Test Parameters - Use case #2 - outstream with default rendering options + some other options -``` - var adUnits = [{ - code: 'something', - mediaTypes: { - video: { - context: 'outstream', // 'instream' or 'outstream' - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'spotx', - params: { - channel_id: 85394, - ad_unit: 'outstream', - outstream_options: { - slot: 'adSlot1', - custom_override: { // This option is not mandatory though used to override default renderer parameters using EASI player options in here: https://developer.spotxchange.com/content/local/docs/sdkDocs/EASI/README.md - content_width: 300, - content_height: 250, - collapse: '1', - hide_fullscreen: '1', - unmute_on_mouse: '1', - continue_out_of_view: '1', - ad_volume: '100', - content_container_id: 'video1', - hide_skin: '1', - spotx_all_google_consent: '1' - } - } - } - }] - }]; -``` - -# Test Parameters - Use case #3 - outstream with your own outstream redering function -``` - var adUnits = [{ - code: 'something', - mediaTypes: { - video: { - context: 'outstream', // 'instream' or 'outstream' - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'spotx', - params: { - channel_id: 79391, - ad_unit: 'outstream', - outstream_function: myOutstreamFunction // Override the default outstream renderer by this referenced function - } - }] - }]; -``` - -# Sample of a custom outstream rendering function -``` -function myOutstreamFunction(bid) { - const videoDiv = 'video1'; - const playerWidth = 300; - const playerHeight = 250; - - window.console.log('[SPOTX][renderer] Handle SpotX custom outstream renderer'); - let script = window.document.createElement('script'); - script.type = 'text/javascript'; - script.src = '//js.spotx.tv/easi/v1/' + bid.channel_id + '.js'; - script.setAttribute('data-spotx_channel_id', '' + bid.channel_id); - script.setAttribute('data-spotx_vast_url', '' + bid.vastUrl); - script.setAttribute('data-spotx_content_width', playerWidth); - script.setAttribute('data-spotx_content_height', playerHeight); - script.setAttribute('data-spotx_content_page_url', bid.renderer.config.content_page_url); - if (bid.renderer.config.ad_mute) { - script.setAttribute('data-spotx_ad_mute', '0'); - } - script.setAttribute('data-spotx_ad_unit', 'incontent'); - script.setAttribute('data-spotx_collapse', '0'); - script.setAttribute('data-spotx_hide_fullscreen', '1'); - script.setAttribute('data-spotx_autoplay', '1'); - script.setAttribute('data-spotx_blocked_autoplay_override_mode', '1'); - script.setAttribute('data-spotx_video_slot_can_autoplay', '1'); - script.setAttribute('data-spotx_unmute_on_mouse', '1'); - script.setAttribute('data-spotx_click_to_replay', '1'); - script.setAttribute('data-spotx_continue_out_of_view', '1'); - script.setAttribute('data-spotx_ad_volume', '100'); - if (bid.renderer.config.inIframe && window.document.getElementById(bid.renderer.config.inIframe).nodeName == 'IFRAME') { - let rawframe = window.document.getElementById(bid.renderer.config.inIframe); - let framedoc = rawframe.contentDocument; - if (!framedoc && rawframe.contentWindow) { - framedoc = rawframe.contentWindow.document; - } - framedoc.body.appendChild(script); - } else { - window.document.getElementById(videoDiv).appendChild(script); - } -}; -``` diff --git a/modules/staqAnalyticsAdapter.js b/modules/staqAnalyticsAdapter.js deleted file mode 100644 index ac5e86db19d..00000000000 --- a/modules/staqAnalyticsAdapter.js +++ /dev/null @@ -1,433 +0,0 @@ -import { logInfo, logError, parseUrl, _each } from '../src/utils.js'; -import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import { EVENTS } from '../src/constants.js'; -import adapterManager from '../src/adapterManager.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import { ajax } from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; - -const MODULE_CODE = 'staq'; -const storageObj = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); - -const ANALYTICS_VERSION = '1.0.0'; -const DEFAULT_QUEUE_TIMEOUT = 4000; -const DEFAULT_HOST = 'tag.staq.com'; - -let staqAdapterRefWin; - -const STAQ_EVENTS = { - AUCTION_INIT: 'auctionInit', - BID_REQUEST: 'bidRequested', - BID_RESPONSE: 'bidResponse', - BID_WON: 'bidWon', - AUCTION_END: 'auctionEnd', - TIMEOUT: 'adapterTimedOut' -}; - -function buildRequestTemplate(connId) { - // TODO: what should these pick from refererInfo? - const url = staqAdapterRefWin.topmostLocation; - const ref = staqAdapterRefWin.topmostLocation; - const topLocation = staqAdapterRefWin.topmostLocation; - - return { - ver: ANALYTICS_VERSION, - domain: topLocation.hostname, - path: topLocation.pathname, - userAgent: navigator.userAgent, - connId: connId, - env: { - screen: { - w: window.screen.width, - h: window.screen.height - }, - lang: navigator.language - }, - src: getUmtSource(url, ref) - } -} - -let analyticsAdapter = Object.assign(adapter({ analyticsType: 'endpoint' }), { - track({ eventType, args }) { - if (!analyticsAdapter.context) { - return; - } - let handler = null; - switch (eventType) { - case EVENTS.AUCTION_INIT: - if (analyticsAdapter.context.queue) { - analyticsAdapter.context.queue.init(); - } - handler = trackAuctionInit; - break; - case EVENTS.BID_REQUESTED: - handler = trackBidRequest; - break; - case EVENTS.BID_RESPONSE: - handler = trackBidResponse; - break; - case EVENTS.BID_WON: - handler = trackBidWon; - break; - case EVENTS.BID_TIMEOUT: - handler = trackBidTimeout; - break; - case EVENTS.AUCTION_END: - handler = trackAuctionEnd; - break; - } - if (handler) { - let events = handler(args); - if (analyticsAdapter.context.queue) { - analyticsAdapter.context.queue.push(events); - if (eventType === EVENTS.BID_WON) { - analyticsAdapter.context.queue.updateWithWins(events); - } - } - if (eventType === EVENTS.AUCTION_END) { - sendAll(); - } - } - } -}); - -analyticsAdapter.context = {}; - -analyticsAdapter.originEnableAnalytics = analyticsAdapter.enableAnalytics; - -analyticsAdapter.enableAnalytics = (config) => { - logInfo('Enabling STAQ Adapter'); - staqAdapterRefWin = getRefererInfo(window); - if (!config.options.connId) { - logError('ConnId is not defined. STAQ Analytics won\'t work'); - return; - } - if (!config.options.url) { - logError('URL is not defined. STAQ Analytics won\'t work'); - return; - } - analyticsAdapter.context = { - host: config.options.host || DEFAULT_HOST, - url: config.options.url, - connectionId: config.options.connId, - requestTemplate: buildRequestTemplate(config.options.connId), - queue: new ExpiringQueue(sendAll, config.options.queueTimeout || DEFAULT_QUEUE_TIMEOUT) - }; - analyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: analyticsAdapter, - code: MODULE_CODE, -}); - -export default analyticsAdapter; - -function sendAll() { - let events = analyticsAdapter.context.queue.popAll(); - if (events.length !== 0) { - let req = analyticsAdapter.context.requestTemplate; - req.auctionId = analyticsAdapter.context.auctionId; - req.events = events - - analyticsAdapter.ajaxCall(JSON.stringify(req)); - } -} - -analyticsAdapter.ajaxCall = function ajaxCall(data) { - logInfo('SENDING DATA: ' + data); - ajax(`https://${analyticsAdapter.context.url}/prebid/${analyticsAdapter.context.connectionId}`, () => {}, data, { contentType: 'text/plain' }); -}; - -function trackAuctionInit(args) { - analyticsAdapter.context.auctionTimeStart = Date.now(); - analyticsAdapter.context.auctionId = args.auctionId; - const event = createHbEvent(args.auctionId, undefined, STAQ_EVENTS.AUCTION_INIT); - return [event]; -} - -function trackBidRequest(args) { - return args.bids.map(bid => - createHbEvent(args.auctionId, args.bidderCode, STAQ_EVENTS.BID_REQUEST, bid.adUnitCode)); -} - -function trackBidResponse(args) { - const event = createHbEvent(args.auctionId, args.bidderCode, STAQ_EVENTS.BID_RESPONSE, - args.adUnitCode, args.cpm, args.timeToRespond / 1000, false, args); - return [event]; -} - -function trackBidWon(args) { - const event = createHbEvent(args.auctionId, args.bidderCode, STAQ_EVENTS.BID_WON, args.adUnitCode, args.cpm, undefined, true, args); - return [event]; -} - -function trackAuctionEnd(args) { - const event = createHbEvent(args.auctionId, undefined, STAQ_EVENTS.AUCTION_END, undefined, - undefined, (Date.now() - analyticsAdapter.context.auctionTimeStart) / 1000); - return [event]; -} - -function trackBidTimeout(args) { - return args.map(arg => createHbEvent(arg.auctionId, arg.bidderCode, STAQ_EVENTS.TIMEOUT)); -} - -function createHbEvent(auctionId, adapter, event, adUnitCode = undefined, value = 0, time = 0, bidWon = undefined, eventArgs) { - let ev = { event: event }; - if (adapter) { - ev.adapter = adapter; - ev.bidderName = adapter; - } - if (adUnitCode) { - ev.adUnitCode = adUnitCode; - } - if (value) { - ev.cpm = value; - } - if (time) { - ev.timeToRespond = time; - } - if (typeof bidWon !== 'undefined') { - ev.bidWon = bidWon; - } else if (event === 'bidResponse') { - ev.bidWon = false; - } - ev.auctionId = auctionId; - - if (eventArgs) { - if (STAQ_EVENTS.BID_RESPONSE == event || STAQ_EVENTS.BID_WON == event) { - ev.width = eventArgs.width; - ev.height = eventArgs.height; - - ev.adId = eventArgs.adId; - } - } - - return ev; -} - -const UTM_TAGS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', - 'utm_c1', 'utm_c2', 'utm_c3', 'utm_c4', 'utm_c5' -]; -const STAQ_PREBID_KEY = 'staq_analytics'; -const DIRECT = '(direct)'; -const REFERRAL = '(referral)'; -const ORGANIC = '(organic)'; - -export let storage = { - getItem: (name) => { - return storageObj.getDataFromLocalStorage(name); - }, - setItem: (name, value) => { - storageObj.setDataInLocalStorage(name, value); - } -}; - -export function getUmtSource(pageUrl, referrer) { - let prevUtm = getPreviousTrafficSource(); - let currUtm = getCurrentTrafficSource(pageUrl, referrer); - let [updated, actual] = chooseActualUtm(prevUtm, currUtm); - if (updated) { - storeUtm(actual); - } - return actual; - - function getPreviousTrafficSource() { - let val = storage.getItem(STAQ_PREBID_KEY); - if (!val) { - return getDirect(); - } - return JSON.parse(val); - } - - function getCurrentTrafficSource(pageUrl, referrer) { - var source = getUTM(pageUrl); - if (source) { - return source; - } - if (referrer) { - let se = getSearchEngine(referrer); - if (se) { - return asUtm(se, ORGANIC, ORGANIC); - } - let parsedUrl = parseUrl(pageUrl); - let [refHost, refPath] = getReferrer(referrer); - if (refHost && refHost !== parsedUrl.hostname) { - return asUtm(refHost, REFERRAL, REFERRAL, '', refPath); - } - } - return getDirect(); - } - - function getSearchEngine(pageUrl) { - let engines = { - 'google': /^https?\:\/\/(?:www\.)?(?:google\.(?:com?\.)?(?:com|cat|[a-z]{2})|g.cn)\//i, - 'yandex': /^https?\:\/\/(?:www\.)?ya(?:ndex\.(?:com|net)?\.?(?:asia|mobi|org|[a-z]{2})?|\.ru)\//i, - 'bing': /^https?\:\/\/(?:www\.)?bing\.com\//i, - 'duckduckgo': /^https?\:\/\/(?:www\.)?duckduckgo\.com\//i, - 'ask': /^https?\:\/\/(?:www\.)?ask\.com\//i, - 'yahoo': /^https?\:\/\/(?:[-a-z]+\.)?(?:search\.)?yahoo\.com\//i - }; - - for (let engine in engines) { - if (engines.hasOwnProperty(engine) && engines[engine].test(pageUrl)) { - return engine; - } - } - } - - function getReferrer(referrer) { - let ref = parseUrl(referrer); - return [ref.hostname, ref.pathname]; - } - - function getUTM(pageUrl) { - let urlParameters = parseUrl(pageUrl).search; - if (!urlParameters['utm_campaign'] || !urlParameters['utm_source']) { - return; - } - let utmArgs = []; - _each(UTM_TAGS, (utmTagName) => { - let utmValue = urlParameters[utmTagName] || ''; - utmArgs.push(utmValue); - }); - return asUtm.apply(this, utmArgs); - } - - function getDirect() { - return asUtm(DIRECT, DIRECT, DIRECT); - } - - function storeUtm(utm) { - let val = JSON.stringify(utm); - storage.setItem(STAQ_PREBID_KEY, val); - } - - function asUtm(source, medium, campaign, term = '', content = '', c1 = '', c2 = '', c3 = '', c4 = '', c5 = '') { - let result = { - source: source, - medium: medium, - campaign: campaign - }; - if (term) { - result.term = term; - } - if (content) { - result.content = content; - } - if (c1) { - result.c1 = c1; - } - if (c2) { - result.c2 = c2; - } - if (c3) { - result.c3 = c3; - } - if (c4) { - result.c4 = c4; - } - if (c5) { - result.c5 = c5; - } - return result; - } - - function chooseActualUtm(prev, curr) { - if (ord(prev) < ord(curr)) { - return [true, curr]; - } - if (ord(prev) > ord(curr)) { - return [false, prev]; - } else { - if (prev.campaign === REFERRAL && prev.content !== curr.content) { - return [true, curr]; - } else if (prev.campaign === ORGANIC && prev.source !== curr.source) { - return [true, curr]; - } else if (isCampaignTraffic(prev) && (prev.campaign !== curr.campaign || prev.source !== curr.source)) { - return [true, curr]; - } - } - return [false, prev]; - } - - function ord(utm) { - switch (utm.campaign) { - case DIRECT: - return 0; - case ORGANIC: - return 1; - case REFERRAL: - return 2; - default: - return 3; - } - } - - function isCampaignTraffic(utm) { - return [DIRECT, REFERRAL, ORGANIC].indexOf(utm.campaign) === -1; - } -} - -/** - * Expiring queue implementation. Fires callback on elapsed timeout since last last update or creation. - * @param callback - * @param ttl - * @constructor - */ -export function ExpiringQueue(callback, ttl) { - let queue = []; - let timeoutId; - - this.push = (event) => { - if (event instanceof Array) { - queue.push.apply(queue, event); - } else { - queue.push(event); - } - reset(); - }; - - this.updateWithWins = (winEvents) => { - winEvents.forEach(winEvent => { - queue.forEach(prevEvent => { - if (prevEvent.event === 'bidResponse' && - prevEvent.auctionId == winEvent.auctionId && - prevEvent.adUnitCode == winEvent.adUnitCode && - prevEvent.adId == winEvent.adId && - prevEvent.adapter == winEvent.adapter) { - prevEvent.bidWon = true; - } - }); - }); - } - - this.popAll = () => { - let result = queue; - queue = []; - reset(); - return result; - }; - - /** - * For test/debug purposes only - * @return {Array} - */ - this.peekAll = () => { - return queue; - }; - - this.init = reset; - - function reset() { - if (timeoutId) { - clearTimeout(timeoutId); - } - timeoutId = setTimeout(() => { - if (queue.length) { - callback(); - } - }, ttl); - } -} diff --git a/modules/stnBidAdapter.js b/modules/stnBidAdapter.js index af4f4c45d38..ba922c0fd57 100644 --- a/modules/stnBidAdapter.js +++ b/modules/stnBidAdapter.js @@ -2,33 +2,32 @@ import { logWarn, logInfo, isArray, - isFn, deepAccess, - isEmpty, - contains, - timestamp, triggerPixel, - isInteger, - getBidIdParameter } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; - -const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; -const BIDDER_CODE = 'stn'; -const ADAPTER_VERSION = '6.0.0'; -const TTL = 360; -const DEFAULT_CURRENCY = 'USD'; -const SELLER_ENDPOINT = 'https://hb.stngo.com/'; -const MODES = { +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { + getEndpoint, + generateBidsParams, + generateGeneralParams, + buildBidResponse, +} from '../libraries/riseUtils/index.js'; + +export const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; +export const BIDDER_CODE = 'stn'; +export const ADAPTER_VERSION = '6.1.0'; +export const TTL = 360; +export const DEFAULT_CURRENCY = 'USD'; +export const SELLER_ENDPOINT = 'https://hb.stngo.com/'; +export const MODES = { PRODUCTION: 'hb-multi', TEST: 'hb-multi-test' -} -const SUPPORTED_SYNC_METHODS = { +}; +export const SUPPORTED_SYNC_METHODS = { IFRAME: 'iframe', PIXEL: 'pixel' -} +}; export const spec = { code: BIDDER_CODE, @@ -50,7 +49,6 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { const combinedRequestsObject = {}; - // use data from the first bid, to create the general params for all bids const generalObject = validBidRequests[0]; const testMode = generalObject.params.testMode; @@ -59,41 +57,16 @@ export const spec = { return { method: 'POST', - url: getEndpoint(testMode), + url: getEndpoint(testMode, SELLER_ENDPOINT, MODES), data: combinedRequestsObject } }, - interpretResponse: function ({body}) { + interpretResponse: function ({ body }) { const bidResponses = []; if (body.bids) { body.bids.forEach(adUnit => { - const bidResponse = { - requestId: adUnit.requestId, - cpm: adUnit.cpm, - currency: adUnit.currency || DEFAULT_CURRENCY, - width: adUnit.width, - height: adUnit.height, - ttl: adUnit.ttl || TTL, - creativeId: adUnit.creativeId, - netRevenue: adUnit.netRevenue || true, - nurl: adUnit.nurl, - mediaType: adUnit.mediaType, - meta: { - mediaType: adUnit.mediaType - } - }; - - if (adUnit.mediaType === VIDEO) { - bidResponse.vastXml = adUnit.vastXml; - } else if (adUnit.mediaType === BANNER) { - bidResponse.ad = adUnit.ad; - } - - if (adUnit.adomain && adUnit.adomain.length) { - bidResponse.meta.advertiserDomains = adUnit.adomain; - } - + const bidResponse = buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER); bidResponses.push(bidResponse); }); } @@ -134,352 +107,3 @@ export const spec = { }; registerBidder(spec); - -/** - * Get floor price - * @param bid {bid} - * @param mediaType {String} - * @returns {Number} - */ -function getFloor(bid, mediaType) { - if (!isFn(bid.getFloor)) { - return 0; - } - let floorResult = bid.getFloor({ - currency: DEFAULT_CURRENCY, - mediaType: mediaType, - size: '*' - }); - return floorResult.currency === DEFAULT_CURRENCY && floorResult.floor ? floorResult.floor : 0; -} - -/** - * Get the ad sizes array from the bid - * @param bid {bid} - * @param mediaType {String} - * @returns {Array} - */ -function getSizesArray(bid, mediaType) { - let sizesArray = [] - - if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) { - sizesArray = bid.mediaTypes[mediaType].sizes; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizesArray = bid.sizes; - } - - return sizesArray; -} - -/** - * Get schain string value - * @param schainObject {Object} - * @returns {string} - */ -function getSupplyChain(schainObject) { - if (isEmpty(schainObject)) { - return ''; - } - let scStr = `${schainObject.ver},${schainObject.complete}`; - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${getEncodedValIfNotEmpty(node.hp)},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - return scStr; -} - -/** - * Get encoded node value - * @param val {string} - * @returns {string} - */ -function getEncodedValIfNotEmpty(val) { - return (val !== '' && val !== undefined) ? encodeURIComponent(val) : ''; -} - -/** - * Get preferred user-sync method based on publisher configuration - * @param filterSettings {Object} - * @param bidderCode {string} - * @returns {string} - */ -function getAllowedSyncMethod(filterSettings, bidderCode) { - const iframeConfigsToCheck = ['all', 'iframe']; - const pixelConfigToCheck = 'image'; - if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { - return SUPPORTED_SYNC_METHODS.IFRAME; - } - if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { - return SUPPORTED_SYNC_METHODS.PIXEL; - } -} - -/** - * Check if sync rule is supported - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - const isInclude = syncRule.filter === 'include'; - const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - return isInclude && contains(bidders, bidderCode); -} - -/** - * Get the seller endpoint - * @param testMode {boolean} - * @returns {string} - */ -function getEndpoint(testMode) { - return testMode - ? SELLER_ENDPOINT + MODES.TEST - : SELLER_ENDPOINT + MODES.PRODUCTION; -} - -/** - * get device type - * @param ua {ua} - * @returns {string} - */ -function getDeviceType(ua) { - if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i - .test(ua.toLowerCase())) { - return '5'; - } - if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i - .test(ua.toLowerCase())) { - return '4'; - } - if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i - .test(ua.toLowerCase())) { - return '3'; - } - return '1'; -} - -function generateBidsParams(validBidRequests, bidderRequest) { - const bidsArray = []; - - if (validBidRequests.length) { - validBidRequests.forEach(bid => { - bidsArray.push(generateBidParameters(bid, bidderRequest)); - }); - } - - return bidsArray; -} - -/** - * Generate bid specific parameters - * @param {bid} bid - * @param {bidderRequest} bidderRequest - * @returns {Object} bid specific params object - */ -function generateBidParameters(bid, bidderRequest) { - const {params} = bid; - const mediaType = isBanner(bid) ? BANNER : VIDEO; - const sizesArray = getSizesArray(bid, mediaType); - - // fix floor price in case of NAN - if (isNaN(params.floorPrice)) { - params.floorPrice = 0; - } - - const bidObject = { - mediaType, - adUnitCode: getBidIdParameter('adUnitCode', bid), - sizes: sizesArray, - floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice), - bidId: getBidIdParameter('bidId', bid), - loop: getBidIdParameter('bidderRequestsCount', bid), - bidderRequestId: getBidIdParameter('bidderRequestId', bid), - transactionId: bid.ortb2Imp?.ext?.tid || '', - coppa: 0, - }; - - const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`); - if (pos) { - bidObject.pos = pos; - } - - const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`); - if (gpid) { - bidObject.gpid = gpid; - } - - const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`); - if (placementId) { - bidObject.placementId = placementId; - } - - const mimes = deepAccess(bid, `mediaTypes.${mediaType}.mimes`); - if (mimes) { - bidObject.mimes = mimes; - } - const api = deepAccess(bid, `mediaTypes.${mediaType}.api`); - if (api) { - bidObject.api = api; - } - - const sua = deepAccess(bid, `ortb2.device.sua`); - if (sua) { - bidObject.sua = sua; - } - - const coppa = deepAccess(bid, `ortb2.regs.coppa`) - if (coppa) { - bidObject.coppa = 1; - } - - if (mediaType === VIDEO) { - const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`); - let playbackMethodValue; - - // verify playbackMethod is of type integer array, or integer only. - if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) { - // only the first playbackMethod in the array will be used, according to OpenRTB 2.5 recommendation - playbackMethodValue = playbackMethod[0]; - } else if (isInteger(playbackMethod)) { - playbackMethodValue = playbackMethod; - } - - if (playbackMethodValue) { - bidObject.playbackMethod = playbackMethodValue; - } - - const placement = deepAccess(bid, `mediaTypes.video.placement`); - if (placement) { - bidObject.placement = placement; - } - - const minDuration = deepAccess(bid, `mediaTypes.video.minduration`); - if (minDuration) { - bidObject.minDuration = minDuration; - } - - const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`); - if (maxDuration) { - bidObject.maxDuration = maxDuration; - } - - const skip = deepAccess(bid, `mediaTypes.video.skip`); - if (skip) { - bidObject.skip = skip; - } - - const linearity = deepAccess(bid, `mediaTypes.video.linearity`); - if (linearity) { - bidObject.linearity = linearity; - } - - const protocols = deepAccess(bid, `mediaTypes.video.protocols`); - if (protocols) { - bidObject.protocols = protocols; - } - - const plcmt = deepAccess(bid, `mediaTypes.video.plcmt`); - if (plcmt) { - bidObject.plcmt = plcmt; - } - } - - return bidObject; -} - -function isBanner(bid) { - return bid.mediaTypes && bid.mediaTypes.banner; -} - -/** - * Generate params that are common between all bids - * @param {single bid object} generalObject - * @param {bidderRequest} bidderRequest - * @returns {object} the common params object - */ -function generateGeneralParams(generalObject, bidderRequest) { - const domain = window.location.hostname; - const {syncEnabled, filterSettings} = config.getConfig('userSync') || {}; - const {bidderCode} = bidderRequest; - const generalBidParams = generalObject.params; - const timeout = bidderRequest.timeout; - - // these params are snake_case instead of camelCase to allow backwards compatability on the server. - // in the future, these will be converted to camelCase to match our convention. - const generalParams = { - wrapper_type: 'prebidjs', - wrapper_vendor: '$$PREBID_GLOBAL$$', - wrapper_version: '$prebid.version$', - adapter_version: ADAPTER_VERSION, - auction_start: timestamp(), - publisher_id: generalBidParams.org, - publisher_name: domain, - site_domain: domain, - dnt: (navigator.doNotTrack === 'yes' || navigator.doNotTrack === '1' || navigator.msDoNotTrack === '1') ? 1 : 0, - device_type: getDeviceType(navigator.userAgent), - ua: navigator.userAgent, - is_wrapper: !!generalBidParams.isWrapper, - session_id: generalBidParams.sessionId || getBidIdParameter('bidderRequestId', generalObject), - tmax: timeout - } - - const userIdsParam = getBidIdParameter('userId', generalObject); - if (userIdsParam) { - generalParams.userIds = JSON.stringify(userIdsParam); - } - - const ortb2Metadata = bidderRequest.ortb2 || {}; - if (ortb2Metadata.site) { - generalParams.site_metadata = JSON.stringify(ortb2Metadata.site); - } - if (ortb2Metadata.user) { - generalParams.user_metadata = JSON.stringify(ortb2Metadata.user); - } - - if (syncEnabled) { - const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); - if (allowedSyncMethod) { - generalParams.cs_method = allowedSyncMethod; - } - } - - if (bidderRequest.uspConsent) { - generalParams.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies; - generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - - if (bidderRequest.gppConsent) { - generalParams.gpp = bidderRequest.gppConsent.gppString; - generalParams.gpp_sid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - generalParams.gpp = bidderRequest.ortb2.regs.gpp; - generalParams.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; - } - - if (generalBidParams.ifa) { - generalParams.ifa = generalBidParams.ifa; - } - - if (generalObject.schain) { - generalParams.schain = getSupplyChain(generalObject.schain); - } - - if (bidderRequest && bidderRequest.refererInfo) { - generalParams.referrer = deepAccess(bidderRequest, 'refererInfo.ref'); - generalParams.page_url = deepAccess(bidderRequest, 'refererInfo.page') || deepAccess(window, 'location.href'); - } - - return generalParams -} diff --git a/modules/symitriDapRtdProvider.js b/modules/symitriDapRtdProvider.js new file mode 100644 index 00000000000..1921bbddf4c --- /dev/null +++ b/modules/symitriDapRtdProvider.js @@ -0,0 +1,812 @@ +/** + * This module adds the Symitri DAP RTD provider to the real time data module + * The {@link module:modules/realTimeData} module is required + * The module will fetch real-time data from DAP + * @module modules/symitriDapRtdProvider + * @requires module:modules/realTimeData + */ +import {ajax} from '../src/ajax.js'; +import {getStorageManager} from '../src/storageManager.js'; +import {submodule} from '../src/hook.js'; +import {isPlainObject, mergeDeep, logMessage, logInfo, logError} from '../src/utils.js'; +import { loadExternalScript } from '../src/adloader.js'; +import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; + +/** + * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule + */ +export function createRtdProvider(moduleName, moduleCode, headerPrefix) { + const MODULE_NAME = 'realTimeData'; + const SUBMODULE_NAME = moduleName; + const MODULE_CODE = moduleCode; + + const DAP_TOKEN = 'async_dap_token'; + const DAP_MEMBERSHIP = 'async_dap_membership'; + const DAP_ENCRYPTED_MEMBERSHIP = 'encrypted_dap_membership'; + const DAP_SS_ID = 'dap_ss_id'; + const DAP_DEFAULT_TOKEN_TTL = 3600; // in seconds + const DAP_MAX_RETRY_TOKENIZE = 1; + const DAP_CLIENT_ENTROPY = 'dap_client_entropy' + + const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME}); + let dapRetryTokenize = 0; + + /** + * Lazy merge objects. + * @param {String} target + * @param {String} source + */ + function mergeLazy(target, source) { + if (!isPlainObject(target)) { + target = {}; + } + if (!isPlainObject(source)) { + source = {}; + } + return mergeDeep(target, source); + } + + /** + * Add real-time data & merge segments. + * @param {Object} ortb2 destination object to merge RTD into + * @param {Object} rtd + */ + function addRealTimeData(ortb2, rtd) { + logInfo('DEBUG(addRealTimeData) - ENTER'); + if (isPlainObject(rtd.ortb2)) { + logMessage('DEBUG(addRealTimeData): merging original: ', ortb2); + logMessage('DEBUG(addRealTimeData): merging in: ', rtd.ortb2); + mergeLazy(ortb2, rtd.ortb2); + } + logInfo('DEBUG(addRealTimeData) - EXIT'); + } + + /** + * Real-time data retrieval from Audigent + * @param {Object} bidConfig + * @param {function} onDone + * @param {Object} rtdConfig + * @param {Object} userConsent + */ + function getRealTimeData(bidConfig, onDone, rtdConfig, userConsent) { + let entropyDict = JSON.parse(storage.getDataFromLocalStorage(DAP_CLIENT_ENTROPY)); + let loadScriptPromise = new Promise((resolve, reject) => { + if (rtdConfig && rtdConfig.params && rtdConfig.params.dapEntropyTimeout && Number.isInteger(rtdConfig.params.dapEntropyTimeout)) { + setTimeout(reject, rtdConfig.params.dapEntropyTimeout, Error('DapEntropy script could not be loaded')); + } + if (entropyDict && entropyDict.expires_at > Math.round(Date.now() / 1000.0)) { + logMessage('Using cached entropy'); + resolve(); + } else { + if (typeof window.dapCalculateEntropy === 'function') { + window.dapCalculateEntropy(resolve, reject); + } else { + if (rtdConfig && rtdConfig.params && dapUtils.isValidHttpsUrl(rtdConfig.params.dapEntropyUrl)) { + loadExternalScript(rtdConfig.params.dapEntropyUrl, MODULE_CODE, () => { dapUtils.dapGetEntropy(resolve, reject) }); + } else { + reject(Error('Please check if dapEntropyUrl is specified and is valid under config.params')); + } + } + } + }); + loadScriptPromise + .catch((error) => { + logError('Entropy could not be calculated due to: ', error.message); + }) + .finally(() => { + generateRealTimeData(bidConfig, onDone, rtdConfig, userConsent); + }); + } + + function generateRealTimeData(bidConfig, onDone, rtdConfig, userConsent) { + logInfo('DEBUG(generateRealTimeData) - ENTER'); + logMessage(' - apiHostname: ' + rtdConfig.params.apiHostname); + logMessage(' - apiVersion: ' + rtdConfig.params.apiVersion); + dapRetryTokenize = 0; + var jsonData = null; + if (rtdConfig && isPlainObject(rtdConfig.params)) { + if (rtdConfig.params.segtax == 504) { + let encMembership = dapUtils.dapGetEncryptedMembershipFromLocalStorage(); + if (encMembership) { + jsonData = dapUtils.dapGetEncryptedRtdObj(encMembership, rtdConfig.params.segtax) + } + } else { + let membership = dapUtils.dapGetMembershipFromLocalStorage(); + if (membership) { + jsonData = dapUtils.dapGetRtdObj(membership, rtdConfig.params.segtax) + } + } + } + if (jsonData) { + if (jsonData.rtd) { + addRealTimeData(bidConfig.ortb2Fragments?.global, jsonData.rtd); + onDone(); + logInfo('DEBUG(generateRealTimeData) - 1'); + // Don't return - ensure the data is always fresh. + } + } + // Calling setTimeout to release the main thread so that the bid request could be sent. + setTimeout(dapUtils.callDapAPIs, 0, bidConfig, onDone, rtdConfig, userConsent); + } + + /** + * Module init + * @param {Object} provider + * @param {Object} userConsent + * @return {boolean} + */ + function init(provider, userConsent) { + if (dapUtils.checkConsent(userConsent) === false) { + return false; + } + return true; + } + + /** @type {RtdSubmodule} */ + const rtdSubmodule = { + name: SUBMODULE_NAME, + getBidRequestData: getRealTimeData, + init: init + }; + + submodule(MODULE_NAME, rtdSubmodule); + const dapUtils = { + + callDapAPIs: function(bidConfig, onDone, rtdConfig, userConsent) { + if (rtdConfig && isPlainObject(rtdConfig.params)) { + let config = { + api_hostname: rtdConfig.params.apiHostname, + api_version: rtdConfig.params.apiVersion, + domain: rtdConfig.params.domain, + segtax: rtdConfig.params.segtax, + identity: {type: rtdConfig.params.identityType} + }; + let refreshMembership = true; + let token = dapUtils.dapGetTokenFromLocalStorage(); + const ortb2 = bidConfig.ortb2Fragments.global; + logMessage('token is: ', token); + if (token !== null) { // If token is not null then check the membership in storage and add the RTD object + if (config.segtax == 504) { // Follow the encrypted membership path + dapUtils.dapRefreshEncryptedMembership(ortb2, config, token, onDone) // Get the encrypted membership from server + refreshMembership = false; + } else { + dapUtils.dapRefreshMembership(ortb2, config, token, onDone) // Get the membership from server + refreshMembership = false; + } + } + dapUtils.dapRefreshToken(ortb2, config, refreshMembership, onDone) // Refresh Token and membership in all the cases + } + }, + dapGetEntropy: function(resolve, reject) { + if (typeof window.dapCalculateEntropy === 'function') { + window.dapCalculateEntropy(resolve, reject); + } else { + reject(Error('window.dapCalculateEntropy function is not defined')) + } + }, + + dapGetTokenFromLocalStorage: function(ttl) { + let now = Math.round(Date.now() / 1000.0); // in seconds + let token = null; + let item = JSON.parse(storage.getDataFromLocalStorage(DAP_TOKEN)); + if (item) { + if (now < item.expires_at) { + token = item.token; + } + } + return token; + }, + + dapRefreshToken: function(ortb2, config, refreshMembership, onDone) { + dapUtils.dapLog('Token missing or expired, fetching a new one...'); + // Trigger a refresh + let now = Math.round(Date.now() / 1000.0); // in seconds + let item = {} + let configAsync = {...config}; + dapUtils.dapTokenize(configAsync, config.identity, onDone, + function(token, status, xhr, onDone) { + item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; + let exp = dapUtils.dapExtractExpiryFromToken(token); + if (typeof exp == 'number') { + item.expires_at = exp - 10; + } + item.token = token; + storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(item)); + dapUtils.dapLog('Successfully updated and stored token; expires at ' + item.expires_at); + let dapSSID = xhr.getResponseHeader(headerPrefix + '-DAP-SS-ID'); + if (dapSSID) { + storage.setDataInLocalStorage(DAP_SS_ID, JSON.stringify(dapSSID)); + } + let deviceId100 = xhr.getResponseHeader(headerPrefix + '-DAP-100'); + if (deviceId100 != null) { + storage.setDataInLocalStorage('dap_deviceId100', deviceId100); + dapUtils.dapLog('Successfully stored DAP 100 Device ID: ' + deviceId100); + } + if (refreshMembership) { + if (config.segtax == 504) { + dapUtils.dapRefreshEncryptedMembership(ortb2, config, token, onDone); + } else { + dapUtils.dapRefreshMembership(ortb2, config, token, onDone); + } + } + }, + function(xhr, status, error, onDone) { + logError('ERROR(' + error + '): failed to retrieve token! ' + status); + onDone() + } + ); + }, + + dapGetMembershipFromLocalStorage: function() { + let now = Math.round(Date.now() / 1000.0); // in seconds + let membership = null; + let item = JSON.parse(storage.getDataFromLocalStorage(DAP_MEMBERSHIP)); + if (item) { + if (now < item.expires_at) { + membership = { + said: item.said, + cohorts: item.cohorts, + attributes: null + }; + } + } + return membership; + }, + + dapRefreshMembership: function(ortb2, config, token, onDone) { + let now = Math.round(Date.now() / 1000.0); // in seconds + let item = {} + let configAsync = {...config}; + dapUtils.dapMembership(configAsync, token, onDone, + function(membership, status, xhr, onDone) { + item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; + let exp = dapUtils.dapExtractExpiryFromToken(membership.said) + if (typeof exp == 'number') { + item.expires_at = exp - 10; + } + item.said = membership.said; + item.cohorts = membership.cohorts; + storage.setDataInLocalStorage(DAP_MEMBERSHIP, JSON.stringify(item)); + dapUtils.dapLog('Successfully updated and stored membership:'); + dapUtils.dapLog(item); + + let data = dapUtils.dapGetRtdObj(item, config.segtax) + dapUtils.checkAndAddRealtimeData(ortb2, data, config.segtax); + onDone(); + }, + function(xhr, status, error, onDone) { + logError('ERROR(' + error + '): failed to retrieve membership! ' + status); + if (status == 403 && dapRetryTokenize < DAP_MAX_RETRY_TOKENIZE) { + dapRetryTokenize++; + dapUtils.dapRefreshToken(ortb2, config, true, onDone); + } else { + onDone(); + } + } + ); + }, + + dapGetEncryptedMembershipFromLocalStorage: function() { + let now = Math.round(Date.now() / 1000.0); // in seconds + let encMembership = null; + let item = JSON.parse(storage.getDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP)); + if (item) { + if (now < item.expires_at) { + encMembership = { + encryptedSegments: item.encryptedSegments + }; + } + } + return encMembership; + }, + + dapRefreshEncryptedMembership: function(ortb2, config, token, onDone) { + let now = Math.round(Date.now() / 1000.0); // in seconds + let item = {}; + let configAsync = {...config}; + dapUtils.dapEncryptedMembership(configAsync, token, onDone, + function(encToken, status, xhr, onDone) { + item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; + let exp = dapUtils.dapExtractExpiryFromToken(encToken); + if (typeof exp == 'number') { + item.expires_at = exp - 10; + } + item.encryptedSegments = encToken; + storage.setDataInLocalStorage(DAP_ENCRYPTED_MEMBERSHIP, JSON.stringify(item)); + dapUtils.dapLog('Successfully updated and stored encrypted membership:'); + dapUtils.dapLog(item); + + let encData = dapUtils.dapGetEncryptedRtdObj(item, config.segtax); + dapUtils.checkAndAddRealtimeData(ortb2, encData, config.segtax); + onDone(); + }, + function(xhr, status, error, onDone) { + logError('ERROR(' + error + '): failed to retrieve encrypted membership! ' + status); + if (status == 403 && dapRetryTokenize < DAP_MAX_RETRY_TOKENIZE) { + dapRetryTokenize++; + dapUtils.dapRefreshToken(ortb2, config, true, onDone); + } else { + onDone(); + } + } + ); + }, + + /** + * DESCRIPTION + * Extract expiry value from a token + */ + dapExtractExpiryFromToken: function(token) { + let exp = null; + if (token) { + const tokenArray = token.split('..'); + if (tokenArray && tokenArray.length > 0) { + let decode = atob(tokenArray[0]) + let header = JSON.parse(decode.replace(/"/g, '"')); + exp = header.exp; + } + } + return exp + }, + + /** + * DESCRIPTION + * + * Convert a DAP membership response to an OpenRTB2 segment object suitable + * for insertion into user.data.segment or site.data.segment and add it to the rtd obj. + */ + dapGetRtdObj: function(membership, segtax) { + let segment = { + name: 'dap.symitri.com', + ext: { + 'segtax': segtax + }, + segment: [] + }; + if (membership != null) { + for (const i of membership.cohorts) { + segment.segment.push({ id: i }); + } + } + let data = { + rtd: { + ortb2: { + user: { + data: [ + segment + ] + }, + site: { + ext: { + data: { + dapSAID: membership.said + } + } + } + } + } + }; + return data; + }, + + /** + * DESCRIPTION + * + * Convert a DAP membership response to an OpenRTB2 segment object suitable + * for insertion into user.data.segment or site.data.segment and add it to the rtd obj. + */ + dapGetEncryptedRtdObj: function(encToken, segtax) { + let segment = { + name: 'dap.symitri.com', + ext: { + 'segtax': segtax + }, + segment: [] + }; + if (encToken != null) { + segment.segment.push({ id: encToken.encryptedSegments }); + } + let encData = { + rtd: { + ortb2: { + user: { + data: [ + segment + ] + } + } + } + }; + return encData; + }, + + checkAndAddRealtimeData: function(ortb2, data, segtax) { + if (data.rtd) { + if (segtax == 504 && dapUtils.checkIfSegmentsAlreadyExist(ortb2, data.rtd, 504)) { + logMessage('DEBUG(handleInit): rtb Object already added'); + } else { + addRealTimeData(ortb2, data.rtd); + } + logInfo('DEBUG(checkAndAddRealtimeData) - 1'); + } + }, + + checkIfSegmentsAlreadyExist: function(ortb2, rtd, segtax) { + let segmentsExist = false + if (ortb2.user && ortb2.user.data && ortb2.user.data.length > 0) { + for (let i = 0; i < ortb2.user.data.length; i++) { + let element = ortb2.user.data[i] + if (element.ext && element.ext.segtax == segtax) { + segmentsExist = true + logMessage('DEBUG(checkIfSegmentsAlreadyExist): rtb Object already added: ', ortb2.user.data); + break; + } + } + } + return segmentsExist + }, + + dapLog: function(args) { + let css = ''; + css += 'display: inline-block;'; + css += 'color: #fff;'; + css += 'background: #F28B20;'; + css += 'padding: 1px 4px;'; + css += 'border-radius: 3px'; + + logInfo('%cDAP Client', css, args); + }, + + isValidHttpsUrl: function(urlString) { + let url; + try { + url = new URL(urlString); + } catch (_) { + return false; + } + return url.protocol === 'https:'; + }, + + checkConsent: function(userConsent) { + let consent = true; + + if (userConsent && userConsent.gdpr && userConsent.gdpr.gdprApplies) { + const gdpr = userConsent.gdpr; + const hasGdpr = (gdpr && typeof gdpr.gdprApplies === 'boolean' && gdpr.gdprApplies) ? 1 : 0; + const gdprConsentString = hasGdpr ? gdpr.consentString : ''; + if (hasGdpr && (!gdprConsentString || gdprConsentString === '')) { + logError('symitriDapRtd submodule requires consent string to call API'); + consent = false; + } + } else if (userConsent && userConsent.usp) { + const usp = userConsent.usp; + consent = usp[1] !== 'N' && usp[2] !== 'Y'; + } + + return consent; + }, + + /******************************************************************************* + * + * V2 (And Beyond) API + * + ******************************************************************************/ + + dapValidationHelper: function(config, onDone, token, onError) { + if (onError == null) { + onError = function(xhr, status, error, onDone) {}; + } + + if (config == null || typeof (config) == typeof (undefined)) { + onError(null, 'Invalid config object', 'ClientError', onDone); + return [ config, true ]; + } + + if (!('api_version' in config) || (typeof (config.api_version) == 'string' && config.api_version.length == 0)) { + config.api_version = 'x1'; + } + + if (typeof (config.api_version) != 'string') { + onError(null, "Invalid api_version: must be a string like 'x1', etc.", 'ClientError', onDone); + return [ config, true ]; + } + + if (!(('api_hostname') in config) || typeof (config.api_hostname) != 'string' || config.api_hostname.length == 0) { + onError(null, 'Invalid api_hostname: must be a non-empty string', 'ClientError', onDone); + return [ config, true ]; + } + + if (token) { + if (typeof (token) != 'string') { + onError(null, 'Invalid token: must be a non-null string', 'ClientError', onDone); + return [ config, true ]; + } + } + + return [ config, false ]; + }, + + /** + * SYNOPSIS + * + * dapTokenize( config, identity ); + * + * DESCRIPTION + * + * Tokenize an identity into a secure, privacy safe pseudonymiziation. + * + * PARAMETERS + * + * config: an array of system configuration parameters + * + * identity: an array of identity parameters passed to the tokenizing system + * + * EXAMPLE + * + * config = { + * api_hostname: "prebid.dap.akadns.net", // required + * domain: "prebid.org", // required + * api_version: "x1", // optional, default "x1" + * }; + * + * token = null; + * identity_email = { + * type: "email", + * identity: "obiwan@jedi.com" + * attributes: { cohorts: [ "100:1641013200", "101:1641013200", "102":3:1641013200" ] }, + * }; + * dap_x1_tokenize( config, identity_email, + * function( response, status, xhr ) { token = response; }, + * function( xhr, status, error ) { ; } // handle error + * + * token = null; + * identity_signature = { type: "signature:1.0.0" }; + * dap_x1_tokenize( config, identity_signature, + * function( response, status, xhr } { token = response; }, + * function( xhr, status, error ) { ; } // handle error + */ + dapTokenize: function(config, identity, onDone, onSuccess = null, onError = null) { + let hasTokenizeError; + [ config, hasTokenizeError ] = this.dapValidationHelper(config, onDone, null, onError); + if (hasTokenizeError) { return; } + + if (typeof (config.domain) != 'string') { + onError(null, 'Invalid config.domain: must be a string', 'ClientError', onDone); + return; + } + + if (config.domain.length <= 0) { + onError(null, 'Invalid config.domain: must have non-zero length', 'ClientError', onDone); + return; + } + + if (identity == null || typeof (identity) == typeof (undefined)) { + onError(null, 'Invalid identity object', 'ClientError', onDone); + return; + } + + if (!('type' in identity) || typeof (identity.type) != 'string' || identity.type.length <= 0) { + onError(null, "Identity must contain a valid 'type' field", 'ClientError', onDone); + return; + } + + let apiParams = { + 'type': identity.type, + }; + + if (typeof (identity.identity) != typeof (undefined)) { + apiParams.identity = identity.identity; + } + if (typeof (identity.attributes) != typeof (undefined)) { + apiParams.attributes = identity.attributes; + } + + let entropyDict = JSON.parse(storage.getDataFromLocalStorage(DAP_CLIENT_ENTROPY)); + if (entropyDict && entropyDict.entropy) { + apiParams.entropy = entropyDict.entropy; + } + + let method; + let body; + let path; + switch (config.api_version) { + case 'x1': + case 'x1-dev': + method = 'POST'; + path = '/data-activation/' + config.api_version + '/domain/' + config.domain + '/identity/tokenize'; + body = JSON.stringify(apiParams); + break; + default: + onError(null, 'Invalid api_version: ' + config.api_version, 'ClientError', onDone); + return; + } + + let customHeaders = {'Content-Type': 'application/json'}; + let dapSSID = JSON.parse(storage.getDataFromLocalStorage(DAP_SS_ID)); + if (dapSSID) { + customHeaders[headerPrefix + '-DAP-SS-ID'] = dapSSID; + } + + let url = 'https://' + config.api_hostname + path; + let cb = { + success: (response, request) => { + let token = null; + switch (config.api_version) { + case 'x1': + case 'x1-dev': + token = request.getResponseHeader(headerPrefix + '-DAP-Token'); + break; + } + onSuccess(token, request.status, request, onDone); + }, + error: (request, error) => { + onError(request, request.statusText, error, onDone); + } + }; + + ajax(url, cb, body, { + method: method, + customHeaders: customHeaders + }); + }, + + /** + * SYNOPSIS + * + * dapMembership( config, token, onSuccess, onError ); + * + * DESCRIPTION + * + * Return the audience segment membership along with a new Secure Advertising + * ID for this token. + * + * PARAMETERS + * + * config: an array of system configuration parameters + * + * token: the token previously returned from the tokenize API + * + * EXAMPLE + * + * config = { + * api_hostname: 'api.dap.akadns.net', + * }; + * + * // token from dap_tokenize + * + * dapMembership( config, token, + * function( membership, status, xhr ) { + * // Run auction with membership.segments and membership.said + * }, + * function( xhr, status, error ) { + * // error + * } ); + * + */ + dapMembership: function(config, token, onDone, onSuccess = null, onError = null) { + let hasMembershipError; + [ config, hasMembershipError ] = this.dapValidationHelper(config, onDone, token, onError); + if (hasMembershipError) { return; } + + if (typeof (config.domain) != 'string') { + onError(null, 'Invalid config.domain: must be a string', 'ClientError', onDone); + return; + } + + let path = '/data-activation/' + + config.api_version + + '/token/' + token + + '/membership'; + + let url = 'https://' + config.api_hostname + path; + + let cb = { + success: (response, request) => { + onSuccess(JSON.parse(response), request.status, request, onDone); + }, + error: (error, request) => { + onError(request, request.status, error, onDone); + } + }; + + ajax(url, cb, undefined, { + method: 'GET', + customHeaders: {} + }); + }, + + /** + * SYNOPSIS + * + * dapEncryptedMembership( config, token, onSuccess, onError ); + * + * DESCRIPTION + * + * Return the audience segment membership along with a new Secure Advertising + * ID for this token in encrypted format. + * + * PARAMETERS + * + * config: an array of system configuration parameters + * + * token: the token previously returned from the tokenize API + * + * EXAMPLE + * + * config = { + * api_hostname: 'api.dap.akadns.net', + * }; + * + * // token from dap_tokenize + * + * dapEncryptedMembership( config, token, + * function( membership, status, xhr ) { + * // Run auction with membership.segments and membership.said after decryption + * }, + * function( xhr, status, error ) { + * // error + * } ); + * + */ + dapEncryptedMembership: function(config, token, onDone, onSuccess = null, onError = null) { + let hasEncryptedMembershipError; + [ config, hasEncryptedMembershipError ] = this.dapValidationHelper(config, onDone, token, onError); + if (hasEncryptedMembershipError) { return; } + + let cb = { + success: (response, request) => { + let encToken = request.getResponseHeader(headerPrefix + '-DAP-Token'); + onSuccess(encToken, request.status, request, onDone); + }, + error: (error, request) => { onError(request, request.status, error, onDone); } + }; + + let path = '/data-activation/' + + config.api_version + + '/token/' + token + + '/membership/encrypt'; + + let url = 'https://' + config.api_hostname + path; + + ajax(url, cb, undefined, { + method: 'GET', + customHeaders: { + 'Content-Type': 'application/json', + 'Pragma': 'akamai-x-get-extracted-values' + } + }); + } + } + + return { + addRealTimeData, + getRealTimeData, + generateRealTimeData, + rtdSubmodule, + storage, + dapUtils, + DAP_TOKEN, + DAP_MEMBERSHIP, + DAP_ENCRYPTED_MEMBERSHIP, + DAP_SS_ID, + DAP_DEFAULT_TOKEN_TTL, + DAP_MAX_RETRY_TOKENIZE, + DAP_CLIENT_ENTROPY + }; +} + +export const { + addRealTimeData, + getRealTimeData, + generateRealTimeData, + rtdSubmodule: symitriDapRtdSubmodule, + storage, + dapUtils, + DAP_TOKEN, + DAP_MEMBERSHIP, + DAP_ENCRYPTED_MEMBERSHIP, + DAP_SS_ID, + DAP_DEFAULT_TOKEN_TTL, + DAP_MAX_RETRY_TOKENIZE, + DAP_CLIENT_ENTROPY +} = createRtdProvider('symitriDap', 'symitridap', 'Symitri'); diff --git a/modules/symitriDapRtdProvider.md b/modules/symitriDapRtdProvider.md new file mode 100644 index 00000000000..654f7b25bfd --- /dev/null +++ b/modules/symitriDapRtdProvider.md @@ -0,0 +1,49 @@ +### Overview + + Symitri DAP Real time data Provider automatically invokes the DAP APIs and submit audience segments and the SAID to the bid-stream. + +### Integration + + 1) Build the symitriDapRTD module into the Prebid.js package with: + + ``` + gulp build --modules=symitriDapRtdProvider,... + ``` + + 2) Use `setConfig` to instruct Prebid.js to initilaize the symitriDapRtdProvider module, as specified below. + +### Configuration + +``` + pbjs.setConfig({ + realTimeData: { + auctionDelay: 2000, + dataProviders: [ + { + name: "dap", + waitForIt: true, + params: { + apiHostname: '', + apiVersion: "x1", + domain: 'your-domain.com', + identityType: 'email' | 'mobile' | ... | 'dap-signature:1.3.0', + segtax: 504, + dapEntropyUrl: 'https://sym-dist.symitri.net/dapentropy.js', + dapEntropyTimeout: 1500 // Maximum time for dapentropy to run + } + } + ] + } + }); + ``` + +Please reach out to your Symitri account representative(Prebid@symitri.com) to get provisioned on the DAP platform. + + +### Testing +To view an example of available segments returned by dap: +``` +‘gulp serve --modules=rtdModule,symitriDapRtdProvider,appnexusBidAdapter,sovrnBidAdapter’ +``` +and then point your browser at: +"http://localhost:9999/integrationExamples/gpt/symitridap_segments_example.html" diff --git a/modules/taboolaBidAdapter.js b/modules/taboolaBidAdapter.js index ab5d5fef139..5fa7f2c8b8e 100644 --- a/modules/taboolaBidAdapter.js +++ b/modules/taboolaBidAdapter.js @@ -206,7 +206,7 @@ export const spec = { if (fledgeAuctionConfigs.length) { return { bids, - fledgeAuctionConfigs, + paapi: fledgeAuctionConfigs, }; } return bids; diff --git a/modules/tagorasBidAdapter.js b/modules/tagorasBidAdapter.js index 0138ba3daf9..6ce54a5a895 100644 --- a/modules/tagorasBidAdapter.js +++ b/modules/tagorasBidAdapter.js @@ -1,333 +1,30 @@ -import {_each, deepAccess, parseSizesInput, parseUrl, uniques, isFn} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {getStorageManager} from '../src/storageManager.js'; -import {config} from '../src/config.js'; +import { + createBuildRequestsFn, + createInterpretResponseFn, + createUserSyncGetter, + isBidRequestValid +} from '../libraries/vidazooUtils/bidderUtils.js'; const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'tagoras'; const BIDDER_VERSION = '1.0.0'; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getTopWindowQueryParams() { - try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.tagoras.io`; } -export function extractCID(params) { - return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; -} - -export function extractPID(params) { - return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; -} - -export function extractSubDomain(params) { - return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const { - params, - bidId, - userId, - adUnitCode, - schain, - mediaTypes, - ortb2Imp, - bidderRequestId, - bidRequestsCount, - bidderRequestsCount, - bidderWinsCount - } = bid; - let {bidFloor, ext} = params; - const hashUrl = hashCode(topWindowUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const cId = extractCID(params); - const pId = extractPID(params); - const subDomain = extractSubDomain(params); - - const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid', deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', '')); - - if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - bidFloor = floorInfo.floor; - } - } - - let data = { - url: encodeURIComponent(topWindowUrl), - uqs: getTopWindowQueryParams(), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - referrer: bidderRequest.refererInfo.ref, - adUnitCode: adUnitCode, - publisherId: pId, - sizes: sizes, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}`, - schain: schain, - mediaTypes: mediaTypes, - gpid: gpid, - transactionId: ortb2Imp?.ext?.tid, - bidderRequestId: bidderRequestId, - bidRequestsCount: bidRequestsCount, - bidderRequestsCount: bidderRequestsCount, - bidderWinsCount: bidderWinsCount, - bidderTimeout: bidderTimeout - }; - - appendUserIdsToRequestPayload(data, userId); - - const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); - - if (sua) { - data.sua = sua; - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest.gppConsent) { - data.gppString = bidderRequest.gppConsent.gppString; - data.gppSid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - data.gppString = bidderRequest.ortb2.regs.gpp; - data.gppSid = bidderRequest.ortb2.regs.gpp_sid; - } - - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data - }; - - _each(ext, (value, key) => { - dto.data['ext.' + key] = value; - }); - - return dto; -} - -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - _each(userIds, (userId, idSystemProviderName) => { - key = `uid.${idSystemProviderName}`; +const buildRequests = createBuildRequestsFn(createDomain, null, storage, BIDDER_CODE, BIDDER_VERSION, false); - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - }); -} +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, false); -function buildRequests(validBidRequests, bidderRequest) { - const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const bidderTimeout = config.getConfig('bidderTimeout'); - const requests = []; - validBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - const {bidId} = request.data; - const {results} = serverResponse.body; - - let output = []; - - try { - results.forEach(result => { - const { - creativeId, - ad, - price, - exp, - width, - height, - currency, - metaData, - advertiserDomains, - mediaType = BANNER - } = result; - if (!ad || !price) { - return; - } - - const response = { - requestId: bidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - }; - - if (metaData) { - Object.assign(response, { - meta: metaData - }) - } else { - Object.assign(response, { - meta: { - advertiserDomains: advertiserDomains || [] - } - }) - } - - if (mediaType === BANNER) { - Object.assign(response, { - ad: ad, - }); - } else { - Object.assign(response, { - vastXml: ad, - mediaType: VIDEO - }); - } - output.push(response); - }); - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '', gppConsent = {}) { - let syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - const {gppString, applicableSections} = gppConsent; - - const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); - let params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}` - - if (gppString && applicableSections?.length) { - params += '&gpp=' + encodeURIComponent(gppString); - params += '&gpp_sid=' + encodeURIComponent(applicableSections.join(',')); - } - - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.tagoras.io/api/sync/iframe/${params}` - }); - } else if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.tagoras.io/api/sync/image/${params}` - }); - } - return syncs; -} - -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { - h = (h << 5) - h + s.charCodeAt(i++) | 0; - } - } - return prefix + h; -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { - } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); - storage.setDataInLocalStorage(key, data); - } catch (e) { - } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.tagoras.io/api/sync/iframe', + imageSyncUrl: 'https://sync.tagoras.io/api/sync/image' +}); export const spec = { code: BIDDER_CODE, diff --git a/modules/tappxBidAdapter.js b/modules/tappxBidAdapter.js index b2939bffedf..0b618b3c124 100644 --- a/modules/tappxBidAdapter.js +++ b/modules/tappxBidAdapter.js @@ -6,7 +6,6 @@ import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; import { parseDomain } from '../src/refererDetection.js'; -import { getGlobal } from '../src/prebidGlobal.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -494,7 +493,7 @@ function buildOneRequest(validBidRequests, bidderRequest) { payload.regs = regs; // < Payload - let pbjsv = (getGlobal().version !== null) ? encodeURIComponent(getGlobal().version) : -1; + let pbjsv = 'v' + '$prebid.version$'; return { method: 'POST', diff --git a/modules/targetVideoBidAdapter.js b/modules/targetVideoBidAdapter.js index 282f322c36a..fd5d79d08b7 100644 --- a/modules/targetVideoBidAdapter.js +++ b/modules/targetVideoBidAdapter.js @@ -1,24 +1,19 @@ -import {find} from '../src/polyfill.js'; -import {getBidRequest} from '../src/utils.js'; +import {_each, getDefinedParams, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {formatRequest, getRtbBid, getSiteObj, videoBid, bannerBid, createVideoTag} from '../libraries/targetVideoUtils/bidderUtils.js'; +import {SOURCE, GVLID, BIDDER_CODE, VIDEO_PARAMS, BANNER_ENDPOINT_URL, VIDEO_ENDPOINT_URL, MARGIN, TIME_TO_LIVE} from '../libraries/targetVideoUtils/constants.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid */ -const SOURCE = 'pbjs'; -const BIDDER_CODE = 'targetVideo'; -const ENDPOINT_URL = 'https://ib.adnxs.com/ut/v3/prebid'; -const MARGIN = 1.35; -const GVLID = 786; - export const spec = { code: BIDDER_CODE, gvlid: GVLID, - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, VIDEO], /** * Determines whether or not the given bid request is valid. @@ -37,35 +32,114 @@ export const spec = { * @return ServerRequest Info describing the request to the server. */ buildRequests: function(bidRequests, bidderRequest) { - const tags = bidRequests.map(createVideoTag); - const schain = bidRequests[0].schain; - const payload = { - tags: tags, - sdk: { - source: SOURCE, - version: '$prebid.version$' - }, - schain: schain + const requests = []; + const sdk = { + source: SOURCE, + version: '$prebid.version$' }; - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - - if (bidderRequest.gdprConsent.addtlConsent && bidderRequest.gdprConsent.addtlConsent.indexOf('~') !== -1) { - let ac = bidderRequest.gdprConsent.addtlConsent; - let acStr = ac.substring(ac.indexOf('~') + 1); - payload.gdpr_consent.addtl_consent = acStr.split('.').map(id => parseInt(id, 10)); + for (let {params, bidId, sizes, mediaTypes} of bidRequests) { + for (const mediaType in mediaTypes) { + switch (mediaType) { + case VIDEO: { + const video = mediaTypes[VIDEO]; + const placementId = params.placementId; + const site = getSiteObj(); + + if (sizes && !Array.isArray(sizes[0])) sizes = [sizes]; + + const payload = { + sdk, + id: bidderRequest.bidderRequestId, + site, + imp: [] + } + + const imp = { + ext: { + prebid: { + storedrequest: { id: placementId } + } + }, + video: getDefinedParams(video, VIDEO_PARAMS) + } + + if (video.playerSize) { + imp.video = Object.assign( + imp.video, parseGPTSingleSizeArrayToRtbSize(video.playerSize[0]) || {} + ); + } else if (video.w && video.h) { + imp.video.w = video.w; + imp.video.h = video.h; + } + + payload.imp.push(imp); + + const gdprConsent = bidderRequest && bidderRequest.gdprConsent; + const uspConsent = bidderRequest && bidderRequest.uspConsent; + + if (gdprConsent || uspConsent) { + payload.regs = { ext: {} }; + + if (uspConsent) { + payload.regs.ext.us_privacy = uspConsent; + }; + + if (gdprConsent) { + if (typeof gdprConsent.gdprApplies !== 'undefined') { + payload.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0; + }; + + if (typeof gdprConsent.consentString !== 'undefined') { + payload.user = { + ext: { consent: gdprConsent.consentString } + }; + }; + }; + }; + + if (bidRequests[0].schain) { + payload.schain = bidRequests[0].schain; + } + + requests.push(formatRequest({ payload, url: VIDEO_ENDPOINT_URL, bidId })); + break; + } + + case BANNER: { + const tags = bidRequests.map(createVideoTag); + const schain = bidRequests[0].schain; + + const payload = { + tags, + sdk, + schain, + }; + + if (bidderRequest && bidderRequest.gdprConsent) { + payload.gdpr_consent = { + consent_string: bidderRequest.gdprConsent.consentString, + consent_required: bidderRequest.gdprConsent.gdprApplies + }; + + if (bidderRequest.gdprConsent.addtlConsent && bidderRequest.gdprConsent.addtlConsent.indexOf('~') !== -1) { + let ac = bidderRequest.gdprConsent.addtlConsent; + let acStr = ac.substring(ac.indexOf('~') + 1); + payload.gdpr_consent.addtl_consent = acStr.split('.').map(id => parseInt(id, 10)); + } + } + + if (bidderRequest && bidderRequest.uspConsent) { + payload.us_privacy = bidderRequest.uspConsent + } + + return formatRequest({ payload, url: BANNER_ENDPOINT_URL, bidderRequest }); + } + } } } - if (bidderRequest && bidderRequest.uspConsent) { - payload.us_privacy = bidderRequest.uspConsent - } - - return formatRequest(payload, bidderRequest); + return requests; }, /** @@ -74,139 +148,33 @@ export const spec = { * @param {*} serverResponse A successful response from the server. * @return {Bid[]} An array of bids which were nested inside the server. */ - interpretResponse: function(serverResponse, { bidderRequest }) { + interpretResponse: function(serverResponse, { bidderRequest, ...bidRequest }) { serverResponse = serverResponse.body; + const currency = serverResponse.cur; const bids = []; if (serverResponse.tags) { serverResponse.tags.forEach(serverBid => { const rtbBid = getRtbBid(serverBid); if (rtbBid && rtbBid.cpm !== 0 && rtbBid.ad_type == VIDEO) { - bids.push(newBid(serverBid, rtbBid, bidderRequest)); + bids.push(bannerBid(serverBid, rtbBid, bidderRequest, MARGIN)); } }); } - return bids; - } - -} - -function getSizes(request) { - let sizes = request.sizes; - if (!sizes && request.mediaTypes && request.mediaTypes.banner && request.mediaTypes.banner.sizes) { - sizes = request.mediaTypes.banner.sizes; - } - if (Array.isArray(sizes) && !Array.isArray(sizes[0])) { - sizes = [sizes[0], sizes[1]]; - } - if (!Array.isArray(sizes) || !Array.isArray(sizes[0])) { - sizes = [[0, 0]]; - } - - return sizes; -} + if (serverResponse.seatbid) { + _each(serverResponse.seatbid, (resp) => { + _each(resp.bid, (bid) => { + const requestId = bidRequest.bidId; + const params = bidRequest.params; -function formatRequest(payload, bidderRequest) { - const options = { - withCredentials: true - }; - const request = { - method: 'POST', - url: ENDPOINT_URL, - data: JSON.stringify(payload), - bidderRequest, - options - }; - - return request; -} - -/** - * Create video auction. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ -function createVideoTag(bid) { - const tag = {}; - tag.id = parseInt(bid.params.placementId, 10); - tag.gpid = 'targetVideo'; - tag.sizes = getSizes(bid); - tag.primary_size = tag.sizes[0]; - tag.ad_types = [VIDEO]; - tag.uuid = bid.bidId; - tag.allow_smaller_sizes = false; - tag.use_pmt_rule = false; - tag.prebid = true; - tag.disable_psa = true; - tag.hb_source = 1; - tag.require_asset_url = true; - tag.video = { - playback_method: 2, - skippable: true - }; - - return tag; -} - -/** - * Unpack the Server's Bid into a Prebid-compatible one. - * @param serverBid - * @param rtbBid - * @param bidderRequest - * @return Bid - */ -function newBid(serverBid, rtbBid, bidderRequest) { - const bidRequest = getBidRequest(serverBid.uuid, [bidderRequest]); - const sizes = getSizes(bidRequest); - const bid = { - requestId: serverBid.uuid, - cpm: rtbBid.cpm / MARGIN, - creativeId: rtbBid.creative_id, - dealId: rtbBid.deal_id, - currency: 'USD', - netRevenue: true, - width: sizes[0][0], - height: sizes[0][1], - ttl: 300, - adUnitCode: bidRequest.adUnitCode, - appnexus: { - buyerMemberId: rtbBid.buyer_member_id, - dealPriority: rtbBid.deal_priority, - dealCode: rtbBid.deal_code + bids.push(videoBid(bid, requestId, currency, params, TIME_TO_LIVE)); + }); + }); } - }; - - if (rtbBid.rtb.video) { - Object.assign(bid, { - vastImpUrl: rtbBid.notify_url, - ad: getBannerHtml(rtbBid.notify_url + '&redir=' + encodeURIComponent(rtbBid.rtb.video.asset_url)), - ttl: 3600 - }); - } - - return bid; -} -function getRtbBid(tag) { - return tag && tag.ads && tag.ads.length && find(tag.ads, ad => ad.rtb); -} - -function getBannerHtml(vastUrl) { - return ` - - - - - - - -
- - - - `; + return bids; + } } registerBidder(spec); diff --git a/modules/targetVideoBidAdapter.md b/modules/targetVideoBidAdapter.md index 557c9f94410..a34ad0aff27 100644 --- a/modules/targetVideoBidAdapter.md +++ b/modules/targetVideoBidAdapter.md @@ -3,17 +3,17 @@ ``` Module Name: Target Video Bid Adapter Module Type: Bidder Adapter -Maintainer: grajzer@gmail.com +Maintainers: grajzer@gmail.com, danijel.ristic@target-video.com ``` # Description Connects to Appnexus exchange for bids. -TargetVideo bid adapter supports Banner. +TargetVideo bid adapter supports Banner and Video. # Test Parameters -``` +```js var adUnits = [ // Banner adUnit { @@ -29,6 +29,23 @@ var adUnits = [ placementId: 13232361 } }] + }, + // Video adUnit + { + mediaTypes: { + video: { + playerSize: [[640, 360]], + context: 'instream', + playbackmethod: [1, 2, 3, 4] + } + }, + bids: [{ + bidder: 'targetVideo', + params: { + placementId: 12345, + reserve: 0, + } + }] } ]; ``` diff --git a/modules/gdprEnforcement.js b/modules/tcfControl.js similarity index 90% rename from modules/gdprEnforcement.js rename to modules/tcfControl.js index caa498c7364..603c91443a3 100644 --- a/modules/gdprEnforcement.js +++ b/modules/tcfControl.js @@ -6,8 +6,8 @@ import {deepAccess, logError, logWarn} from '../src/utils.js'; import {config} from '../src/config.js'; import adapterManager, {gdprDataHandler} from '../src/adapterManager.js'; import * as events from '../src/events.js'; -import { EVENTS } from '../src/constants.js'; -import {GDPR_GVLIDS, VENDORLESS_GVLID, FIRST_PARTY_GVLID} from '../src/consentHandler.js'; +import {EVENTS} from '../src/constants.js'; +import {GDPR_GVLIDS, VENDORLESS_GVLID} from '../src/consentHandler.js'; import { MODULE_TYPE_ANALYTICS, MODULE_TYPE_BIDDER, @@ -23,10 +23,14 @@ import { import {registerActivityControl} from '../src/activities/rules.js'; import { ACTIVITY_ACCESS_DEVICE, - ACTIVITY_ENRICH_EIDS, ACTIVITY_ENRICH_UFPD, + ACTIVITY_ENRICH_EIDS, + ACTIVITY_ENRICH_UFPD, ACTIVITY_FETCH_BIDS, ACTIVITY_REPORT_ANALYTICS, - ACTIVITY_SYNC_USER, ACTIVITY_TRANSMIT_EIDS, ACTIVITY_TRANSMIT_PRECISE_GEO, ACTIVITY_TRANSMIT_UFPD + ACTIVITY_SYNC_USER, + ACTIVITY_TRANSMIT_EIDS, + ACTIVITY_TRANSMIT_PRECISE_GEO, + ACTIVITY_TRANSMIT_UFPD } from '../src/activities/activities.js'; export const STRICT_STORAGE_ENFORCEMENT = 'strictStorageEnforcement'; @@ -37,7 +41,7 @@ export const ACTIVE_RULES = { }; const CONSENT_PATHS = { - purpose: 'purpose.consents', + purpose: false, feature: 'specialFeatureOptins' }; @@ -98,6 +102,7 @@ const RULE_HANDLES = []; // in JS we do not have access to the GVL; assume that everyone declares legitimate interest for basic ads const LI_PURPOSES = [2]; +const PUBLISHER_LI_PURPOSES = [2, 7, 9, 10]; /** * Retrieve a module's GVL ID. @@ -111,7 +116,7 @@ export function getGvlid(moduleType, moduleName, fallbackFn) { if (gvlMapping && gvlMapping[moduleName]) { return gvlMapping[moduleName]; } else if (moduleType === MODULE_TYPE_PREBID) { - return moduleName === 'cdep' ? FIRST_PARTY_GVLID : VENDORLESS_GVLID; + return VENDORLESS_GVLID; } else { let {gvlid, modules} = GDPR_GVLIDS.get(moduleName); if (gvlid == null && Object.keys(modules).length > 0) { @@ -163,15 +168,25 @@ export function shouldEnforce(consentData, purpose, name) { return consentData && consentData.gdprApplies; } -function getConsent(consentData, type, id, gvlId) { - let purpose = !!deepAccess(consentData, `vendorData.${CONSENT_PATHS[type]}.${id}`); - let vendor = !!deepAccess(consentData, `vendorData.vendor.consents.${gvlId}`); +function getConsentOrLI(consentData, path, id, acceptLI) { + const data = deepAccess(consentData, `vendorData.${path}`); + return !!data?.consents?.[id] || (acceptLI && !!data?.legitimateInterests?.[id]); +} - if (type === 'purpose' && LI_PURPOSES.includes(id)) { - purpose ||= !!deepAccess(consentData, `vendorData.purpose.legitimateInterests.${id}`); - vendor ||= !!deepAccess(consentData, `vendorData.vendor.legitimateInterests.${gvlId}`); +function getConsent(consentData, type, purposeNo, gvlId) { + let purpose; + if (CONSENT_PATHS[type] !== false) { + purpose = !!deepAccess(consentData, `vendorData.${CONSENT_PATHS[type]}.${purposeNo}`); + } else { + const [path, liPurposes] = gvlId === VENDORLESS_GVLID + ? ['publisher', PUBLISHER_LI_PURPOSES] + : ['purpose', LI_PURPOSES]; + purpose = getConsentOrLI(consentData, path, purposeNo, liPurposes.includes(purposeNo)); + } + return { + purpose, + vendor: getConsentOrLI(consentData, 'vendor', gvlId, LI_PURPOSES.includes(purposeNo)) } - return {purpose, vendor}; } /** @@ -192,14 +207,7 @@ export function validateRules(rule, consentData, currentModule, gvlId) { } const vendorConsentRequred = rule.enforceVendor && !((gvlId === VENDORLESS_GVLID || (rule.softVendorExceptions || []).includes(currentModule))); const {purpose, vendor} = getConsent(consentData, ruleOptions.type, ruleOptions.id, gvlId); - - let validation = (!rule.enforcePurpose || purpose) && (!vendorConsentRequred || vendor); - - if (gvlId === FIRST_PARTY_GVLID) { - validation = (!rule.enforcePurpose || !!deepAccess(consentData, `vendorData.publisher.consents.${ruleOptions.id}`)); - } - - return validation; + return (!rule.enforcePurpose || purpose) && (!vendorConsentRequred || vendor); } function gdprRule(purposeNo, checkConsent, blocked = null, gvlidFallback = () => null) { diff --git a/modules/telariaBidAdapter.js b/modules/telariaBidAdapter.js index 38eefd447a8..4ad544aaa50 100644 --- a/modules/telariaBidAdapter.js +++ b/modules/telariaBidAdapter.js @@ -1,6 +1,7 @@ import { logError, isEmpty, deepAccess, triggerPixel, logWarn, isArray } from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {VIDEO} from '../src/mediaTypes.js'; +import {getSupplyChain} from '../libraries/riseUtils/index.js'; const BIDDER_CODE = 'telaria'; const DOMAIN = 'tremorhub.com'; @@ -127,37 +128,6 @@ function getDefaultSrcPageUrl() { return encodeURIComponent(document.location.href); } -function getEncodedValIfNotEmpty(val) { - return (val !== '' && val !== undefined) ? encodeURIComponent(val) : ''; -} - -/** - * Converts the schain object to a url param value. Please refer to - * https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md - * (schain for non ORTB section) for more information - * @param schainObject - * @returns {string} - */ -function getSupplyChainAsUrlParam(schainObject) { - if (isEmpty(schainObject)) { - return ''; - } - - let scStr = `&schain=${schainObject.ver},${schainObject.complete}`; - - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${getEncodedValIfNotEmpty(node.hp)},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - - return scStr; -} - function getUrlParams(params, schainFromBidRequest) { let urlSuffix = ''; @@ -167,7 +137,7 @@ function getUrlParams(params, schainFromBidRequest) { urlSuffix += `&${key}=${params[key]}`; } } - urlSuffix += getSupplyChainAsUrlParam(!isEmpty(schainFromBidRequest) ? schainFromBidRequest : params['schain']); + urlSuffix += getSupplyChain(!isEmpty(schainFromBidRequest) ? schainFromBidRequest : params['schain']); } return urlSuffix; diff --git a/modules/terceptAnalyticsAdapter.js b/modules/terceptAnalyticsAdapter.js index 089f8d917d6..289a19beb53 100644 --- a/modules/terceptAnalyticsAdapter.js +++ b/modules/terceptAnalyticsAdapter.js @@ -3,7 +3,6 @@ import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; -import {getGlobal} from '../src/prebidGlobal.js'; const emptyUrl = ''; const analyticsType = 'endpoint'; @@ -124,7 +123,7 @@ function send(data, status) { search: { auctionTimestamp: auctionTimestamp, terceptAnalyticsVersion: terceptAnalyticsVersion, - prebidVersion: getGlobal().version + prebidVersion: 'v' + '$prebid.version$' } }); diff --git a/modules/theAdxBidAdapter.js b/modules/theAdxBidAdapter.js index f19f7cfe515..6d3c2e07b84 100644 --- a/modules/theAdxBidAdapter.js +++ b/modules/theAdxBidAdapter.js @@ -20,6 +20,7 @@ import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const BIDDER_CODE = 'theadx'; const ENDPOINT_URL = 'https://ssp.theadx.com/request'; +const ENDPOINT_TR_URL = 'https://ssptr.theadx.com/request'; const NATIVEASSETNAMES = { 0: 'title', @@ -125,7 +126,7 @@ const NATIVEPROBS = { export const spec = { code: BIDDER_CODE, - aliases: ['theadx'], // short code + aliases: ['theadx', 'theAdx'], // short code supportedMediaTypes: [BANNER, VIDEO, NATIVE], /** @@ -160,10 +161,11 @@ export const spec = { if (!isEmpty(validBidRequests)) { results = validBidRequests.map( bidRequest => { + let url = `${getRegionEndPoint(bidRequest)}?tagid=${bidRequest.params.tagId}`; return { method: requestType, type: requestType, - url: `${ENDPOINT_URL}?tagid=${bidRequest.params.tagId}`, + url: url, options: { withCredentials: true, }, @@ -500,6 +502,14 @@ let generateImpBody = (bidRequest, bidderRequest) => { return result; } +let getRegionEndPoint = (bidRequest) => { + if (bidRequest && bidRequest.params && bidRequest.params.region) { + if (bidRequest.params.region.toLowerCase() == 'tr') { + return ENDPOINT_TR_URL; + } + } + return ENDPOINT_URL; +}; let generatePayload = (bidRequest, bidderRequest) => { // Generate the expected OpenRTB payload @@ -511,7 +521,38 @@ let generatePayload = (bidRequest, bidderRequest) => { imp: [generateImpBody(bidRequest, bidderRequest)], }; // return payload; + let eids = getEids(bidRequest); + if (Object.keys(eids).length > 0) { + payload.ext = eids; + } return JSON.stringify(payload); }; +function getEids(bidRequest) { + let eids = {} + + let uId2 = deepAccess(bidRequest, 'userId.uid2.id'); + if (uId2) { + eids['uid2'] = uId2; + } + + let id5 = deepAccess(bidRequest, 'userId.id5id.uid'); + if (id5) { + eids['id5id'] = id5; + let id5Linktype = deepAccess(bidRequest, 'userId.id5id.ext.linkType'); + if (id5Linktype) { + eids['id5_linktype'] = id5Linktype; + } + } + let netId = deepAccess(bidRequest, 'userId.netId'); + if (netId) { + eids['netid'] = netId; + } + let sharedId = deepAccess(bidRequest, 'userId.sharedid.id'); + if (sharedId) { + eids['sharedid'] = sharedId; + } + return eids; +}; + registerBidder(spec); diff --git a/modules/topicsFpdModule.js b/modules/topicsFpdModule.js index be3e8444dae..8df01fcd599 100644 --- a/modules/topicsFpdModule.js +++ b/modules/topicsFpdModule.js @@ -21,38 +21,6 @@ export function reset() { iframeLoadedURL = []; } -const bidderIframeList = { - maxTopicCaller: 4, - bidders: [{ - bidder: 'pubmatic', - iframeURL: 'https://ads.pubmatic.com/AdServer/js/topics/topics_frame.html' - }, { - bidder: 'rtbhouse', - iframeURL: 'https://topics.authorizedvault.com/topicsapi.html' - }, { - bidder: 'openx', - iframeURL: 'https://pa.openx.net/topics_frame.html' - }, { - bidder: 'improvedigital', - iframeURL: 'https://hb.360yield.com/privacy-sandbox/topics.html' - }, { - bidder: 'onetag', - iframeURL: 'https://onetag-sys.com/static/topicsapi.html' - }, { - bidder: 'taboola', - iframeURL: 'https://cdn.taboola.com/libtrc/static/topics/taboola-prebid-browsing-topics.html' - }, { - bidder: 'discovery', - iframeURL: 'https://api.popin.cc/topic/prebid-topics-frame.html' - }, { - bidder: 'undertone', - iframeURL: 'https://creative-p.undertone.com/spk-public/topics_frame.html' - }, { - bidder: 'vidazoo', - iframeURL: 'https://static.vidazoo.com/topics_api/topics_frame.html' - }] -} - export const coreStorage = getCoreStorageManager(MODULE_NAME); export const topicStorageName = 'prebid:topics'; export const lastUpdated = 'lastUpdated'; @@ -161,8 +129,8 @@ export function processFpd(config, {global}, {data = topicsData} = {}) { */ export function getCachedTopics() { let cachedTopicData = []; - const topics = config.getConfig('userSync.topics') || bidderIframeList; - const bidderList = topics.bidders || []; + const topics = config.getConfig('userSync.topics'); + const bidderList = topics?.bidders || []; let storedSegments = new Map(safeJSONParse(coreStorage.getDataFromLocalStorage(topicStorageName))); storedSegments && storedSegments.forEach((value, cachedBidder) => { // Check bidder exist in config for cached bidder data and then only retrieve the cached data @@ -244,7 +212,7 @@ function listenMessagesFromTopicIframe() { */ export function loadTopicsForBidders(doc = document) { if (!isTopicsSupported(doc)) return; - const topics = config.getConfig('userSync.topics') || bidderIframeList; + const topics = config.getConfig('userSync.topics'); if (topics) { listenMessagesFromTopicIframe(); diff --git a/modules/trafficgateBidAdapter.js b/modules/trafficgateBidAdapter.js index fcd84306099..d30d79ef3a6 100644 --- a/modules/trafficgateBidAdapter.js +++ b/modules/trafficgateBidAdapter.js @@ -2,7 +2,6 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {ortbConverter} from '../libraries/ortbConverter/converter.js'; import {deepAccess, mergeDeep} from '../src/utils.js'; -import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; const BIDDER_CODE = 'trafficgate'; const URL = 'https://[HOST].bc-plugin.com/prebidjs' @@ -13,7 +12,6 @@ export const spec = { isBidRequestValid, buildRequests, interpretResponse, - transformBidParams, isBannerBid }; @@ -88,14 +86,6 @@ const converter = ortbConverter({ } }); -function transformBidParams(params, isOpenRtb) { - return convertTypes({ - 'customFloor': 'number', - 'placementId': 'number', - 'host': 'string' - }, params); -} - function isBidRequestValid(bidRequest) { const isValid = bidRequest.params.placementId && bidRequest.params.host; if (!isValid) { diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index 056ab2b9d19..a665de6140f 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -58,8 +58,8 @@ export const tripleliftAdapterSpec = { tlCall = tryAppendQueryString(tlCall, 'us_privacy', bidderRequest.uspConsent); } - if (bidderRequest && bidderRequest.fledgeEnabled) { - tlCall = tryAppendQueryString(tlCall, 'fledge', bidderRequest.fledgeEnabled); + if (bidderRequest?.paapi?.enabled) { + tlCall = tryAppendQueryString(tlCall, 'fledge', bidderRequest.paapi.enabled); } if (config.getConfig('coppa') === true) { @@ -96,7 +96,7 @@ export const tripleliftAdapterSpec = { logMessage('Response with FLEDGE:', { bids, fledgeAuctionConfigs }); return { bids, - fledgeAuctionConfigs + paapi: fledgeAuctionConfigs }; } else { return bids; diff --git a/modules/truereachBidAdapter.js b/modules/truereachBidAdapter.js index 8b1656ec7a2..9dda76f6518 100755 --- a/modules/truereachBidAdapter.js +++ b/modules/truereachBidAdapter.js @@ -11,7 +11,7 @@ export const spec = { supportedMediaTypes: SUPPORTED_AD_TYPES, isBidRequestValid: function (bidRequest) { - return (bidRequest.params.site_id && bidRequest.params.bidfloor && + return (bidRequest.params.site_id && deepAccess(bidRequest, 'mediaTypes.banner') && (deepAccess(bidRequest, 'mediaTypes.banner.sizes.length') > 0)); }, @@ -116,8 +116,6 @@ function buildCommonQueryParamsFromBids(validBidRequests, bidderRequest) { adH = adSizes[0][1]; } - let bidFloor = Number(0); - let domain = window.location.host; let page = window.location.host + window.location.pathname + location.search + location.hash; @@ -129,8 +127,7 @@ function buildCommonQueryParamsFromBids(validBidRequests, bidderRequest) { banner: { w: adW, h: adH - }, - bidfloor: bidFloor + } } ], site: { diff --git a/modules/twistDigitalBidAdapter.js b/modules/twistDigitalBidAdapter.js index f509e68f9a2..bed9e531a26 100644 --- a/modules/twistDigitalBidAdapter.js +++ b/modules/twistDigitalBidAdapter.js @@ -1,452 +1,28 @@ -import { - _each, - deepAccess, - isFn, - parseSizesInput, - parseUrl, - uniques, - isArray, - formatQS, - triggerPixel -} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {getStorageManager} from '../src/storageManager.js'; -import {bidderSettings} from '../src/bidderSettings.js'; -import {config} from '../src/config.js'; -import {chunk} from '../libraries/chunk/chunk.js'; +import { + isBidRequestValid, createInterpretResponseFn, createUserSyncGetter, createBuildRequestsFn, onBidWon +} from '../libraries/vidazooUtils/bidderUtils.js'; const GVLID = 1292; const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'twistdigital'; const BIDDER_VERSION = '1.0.0'; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 60; -export const webSessionId = 'wsid_' + parseInt(Date.now() * Math.random()); -const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getTopWindowQueryParams() { - try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.twist.win`; } -export function extractCID(params) { - return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; -} - -export function extractPID(params) { - return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; -} - -export function extractSubDomain(params) { - return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const { - params, - bidId, - userId, - adUnitCode, - schain, - mediaTypes, - ortb2Imp, - bidderRequestId, - bidRequestsCount, - bidderRequestsCount, - bidderWinsCount - } = bid; - const {ext} = params; - let {bidFloor} = params; - const hashUrl = hashCode(topWindowUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const pId = extractPID(params); - const isStorageAllowed = bidderSettings.get(BIDDER_CODE, 'storageAllowed'); - - const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid', deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', '')); - const cat = deepAccess(bidderRequest, 'ortb2.site.cat', []); - const pagecat = deepAccess(bidderRequest, 'ortb2.site.pagecat', []); - const contentData = deepAccess(bidderRequest, 'ortb2.site.content.data', []); - const userData = deepAccess(bidderRequest, 'ortb2.user.data', []); - - if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - bidFloor = floorInfo.floor; - } - } - - let data = { - url: encodeURIComponent(topWindowUrl), - uqs: getTopWindowQueryParams(), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - referrer: bidderRequest.refererInfo.ref, - adUnitCode: adUnitCode, - publisherId: pId, - sizes: sizes, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}`, - schain: schain, - mediaTypes: mediaTypes, - isStorageAllowed: isStorageAllowed, - gpid: gpid, - cat: cat, - contentData, - userData: userData, - pagecat: pagecat, - transactionId: ortb2Imp?.ext?.tid, - bidderRequestId: bidderRequestId, - bidRequestsCount: bidRequestsCount, - bidderRequestsCount: bidderRequestsCount, - bidderWinsCount: bidderWinsCount, - bidderTimeout: bidderTimeout, - webSessionId: webSessionId - }; - - appendUserIdsToRequestPayload(data, userId); - - const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); - - if (sua) { - data.sua = sua; - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest.gppConsent) { - data.gppString = bidderRequest.gppConsent.gppString; - data.gppSid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - data.gppString = bidderRequest.ortb2.regs.gpp; - data.gppSid = bidderRequest.ortb2.regs.gpp_sid; - } - - if (bidderRequest.fledgeEnabled) { - const fledge = deepAccess(bidderRequest, 'ortb2Imp.ext.ae'); - if (fledge) { - data.fledge = fledge; - } - } - - _each(ext, (value, key) => { - data['ext.' + key] = value; - }); - - return data; -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const {params} = bid; - const cId = extractCID(params); - const subDomain = extractSubDomain(params); - const data = buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout); - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data - }; - return dto; -} - -function buildSingleRequest(bidRequests, bidderRequest, topWindowUrl, bidderTimeout) { - const {params} = bidRequests[0]; - const cId = extractCID(params); - const subDomain = extractSubDomain(params); - const data = bidRequests.map(bid => { - const sizes = parseSizesInput(bid.sizes); - return buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) - }); - const chunkSize = Math.min(20, config.getConfig('twistdigital.chunkSize') || 10); - - const chunkedData = chunk(data, chunkSize); - return chunkedData.map(chunk => { - return { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: { - bids: chunk - } - }; - }); -} - -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - _each(userIds, (userId, idSystemProviderName) => { - key = `uid.${idSystemProviderName}`; - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - }); -} - -function buildRequests(validBidRequests, bidderRequest) { - const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const bidderTimeout = config.getConfig('bidderTimeout'); - - const singleRequestMode = config.getConfig('twistdigital.singleRequest'); +const buildRequests = createBuildRequestsFn(createDomain, null, storage, BIDDER_CODE, BIDDER_VERSION, true); - const requests = []; +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, true); - if (singleRequestMode) { - // banner bids are sent as a single request - const bannerBidRequests = validBidRequests.filter(bid => isArray(bid.mediaTypes) ? bid.mediaTypes.includes(BANNER) : bid.mediaTypes[BANNER] !== undefined); - if (bannerBidRequests.length > 0) { - const singleRequests = buildSingleRequest(bannerBidRequests, bidderRequest, topWindowUrl, bidderTimeout); - requests.push(...singleRequests); - } - - // video bids are sent as a single request for each bid - - const videoBidRequests = validBidRequests.filter(bid => bid.mediaTypes[VIDEO] !== undefined); - videoBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - } else { - validBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - } - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - - const singleRequestMode = config.getConfig('twistdigital.singleRequest'); - const reqBidId = deepAccess(request, 'data.bidId'); - const {results} = serverResponse.body; - - let output = []; - - try { - results.forEach((result, i) => { - const { - creativeId, - ad, - price, - exp, - width, - height, - currency, - bidId, - nurl, - advertiserDomains, - metaData, - mediaType = BANNER - } = result; - if (!ad || !price) { - return; - } - - const response = { - requestId: (singleRequestMode && bidId) ? bidId : reqBidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - }; - - if (nurl) { - response.nurl = nurl; - } - - if (metaData) { - Object.assign(response, { - meta: metaData - }) - } else { - Object.assign(response, { - meta: { - advertiserDomains: advertiserDomains || [] - } - }) - } - - if (mediaType === BANNER) { - Object.assign(response, { - ad: ad, - }); - } else { - Object.assign(response, { - vastXml: ad, - mediaType: VIDEO - }); - } - output.push(response); - }); - - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '', gppConsent = {}) { - let syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - const {gppString, applicableSections} = gppConsent; - - const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); - let params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}`; - - if (gppString && applicableSections?.length) { - params += '&gpp=' + encodeURIComponent(gppString); - params += '&gpp_sid=' + encodeURIComponent(applicableSections.join(',')); - } - - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.twist.win/api/sync/iframe/${params}` - }); - } - if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.twist.win/api/sync/image/${params}` - }); - } - return syncs; -} - -/** - * @param {Bid} bid - */ -function onBidWon(bid) { - if (!bid.nurl) { - return; - } - const wonBid = { - adId: bid.adId, - creativeId: bid.creativeId, - auctionId: bid.auctionId, - transactionId: bid.transactionId, - adUnitCode: bid.adUnitCode, - cpm: bid.cpm, - currency: bid.currency, - originalCpm: bid.originalCpm, - originalCurrency: bid.originalCurrency, - netRevenue: bid.netRevenue, - mediaType: bid.mediaType, - timeToRespond: bid.timeToRespond, - status: bid.status, - }; - const qs = formatQS(wonBid); - const url = bid.nurl + (bid.nurl.indexOf('?') === -1 ? '?' : '&') + qs; - triggerPixel(url); -} - -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { - h = (h << 5) - h + s.charCodeAt(i++) | 0; - } - } - return prefix + h; -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { - } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); - storage.setDataInLocalStorage(key, data); - } catch (e) { - } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.twist.win/api/sync/iframe', imageSyncUrl: 'https://sync.twist.win/api/sync/image' +}); export const spec = { code: BIDDER_CODE, diff --git a/modules/uid2IdSystem.js b/modules/uid2IdSystem.js index 1ce9b0f5a09..afdde5f0a7f 100644 --- a/modules/uid2IdSystem.js +++ b/modules/uid2IdSystem.js @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ /** * This module adds uid2 ID support to the User ID module * The {@link module:modules/userId} module is required. diff --git a/modules/uid2IdSystem_shared.js b/modules/uid2IdSystem_shared.js index 808a61cb388..a9acfd6291e 100644 --- a/modules/uid2IdSystem_shared.js +++ b/modules/uid2IdSystem_shared.js @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ import { ajax } from '../src/ajax.js'; import { cyrb53Hash } from '../src/utils.js'; @@ -8,12 +7,22 @@ function isValidIdentity(identity) { return !!(typeof identity === 'object' && identity !== null && identity.advertising_token && identity.identity_expires && identity.refresh_from && identity.refresh_token && identity.refresh_expires); } +// Helper function to prepend message +function prependMessage(message) { + return `UID2 shared library - ${message}`; +} + +// Wrapper function for logInfo +function logInfoWrapper(logInfo, ...args) { + logInfo(prependMessage(args[0]), ...args.slice(1)); +} + // This is extracted from an in-progress API client. Once it's available via NPM, this class should be replaced with the NPM package. export class Uid2ApiClient { constructor(opts, clientId, logInfo, logWarn) { this._baseUrl = opts.baseUrl; this._clientVersion = clientId; - this._logInfo = logInfo; + this._logInfo = (...args) => logInfoWrapper(logInfo, ...args); this._logWarn = logWarn; } @@ -36,7 +45,7 @@ export class Uid2ApiClient { if (this.isValidRefreshResponse(response)) { if (response.status === 'success') { return { status: response.status, identity: response.body }; } return response; - } else { return `Response didn't contain a valid status`; } + } else { return prependMessage(`Response didn't contain a valid status`); } } callRefreshApi(refreshDetails) { const url = this._baseUrl + '/v2/token/refresh'; @@ -54,7 +63,7 @@ export class Uid2ApiClient { this._logInfo('No response decryption key available, assuming unencrypted JSON'); const response = JSON.parse(responseText); const result = this.ResponseToRefreshResult(response); - if (typeof result === 'string') { rejectPromise(result); } else { resolvePromise(result); } + if (typeof result === 'string') { rejectPromise(prependMessage(result)); } else { resolvePromise(result); } } else { this._logInfo('Decrypting refresh API response'); const encodeResp = this.createArrayBuffer(atob(responseText)); @@ -70,12 +79,12 @@ export class Uid2ApiClient { this._logInfo('Decrypted to:', decryptedResponse); const response = JSON.parse(decryptedResponse); const result = this.ResponseToRefreshResult(response); - if (typeof result === 'string') { rejectPromise(result); } else { resolvePromise(result); } - }, (reason) => this._logWarn(`Call to UID2 API failed`, reason)); - }, (reason) => this._logWarn(`Call to UID2 API failed`, reason)); + if (typeof result === 'string') { rejectPromise(prependMessage(result)); } else { resolvePromise(result); } + }, (reason) => this._logWarn(prependMessage(`Call to UID2 API failed`), reason)); + }, (reason) => this._logWarn(prependMessage(`Call to UID2 API failed`), reason)); } } catch (_err) { - rejectPromise(responseText); + rejectPromise(prependMessage(responseText)); } }, error: (error, xhr) => { @@ -83,9 +92,9 @@ export class Uid2ApiClient { this._logInfo('Error status, assuming unencrypted JSON'); const response = JSON.parse(xhr.responseText); const result = this.ResponseToRefreshResult(response); - if (typeof result === 'string') { rejectPromise(result); } else { resolvePromise(result); } + if (typeof result === 'string') { rejectPromise(prependMessage(result)); } else { resolvePromise(result); } } catch (_e) { - rejectPromise(error) + rejectPromise(prependMessage(error)); } } }, refreshDetails.refresh_token, { method: 'POST', @@ -100,7 +109,7 @@ export class Uid2StorageManager { this._storage = storage; this._preferLocalStorage = preferLocalStorage; this._storageName = storageName; - this._logInfo = logInfo; + this._logInfo = (...args) => logInfoWrapper(logInfo, ...args); } readCookie(cookieName) { return this._storage.cookiesAreEnabled() ? this._storage.getCookie(cookieName) : null; @@ -393,8 +402,7 @@ if (FEATURES.UID2_CSTG) { this._baseUrl = opts.baseUrl; this._serverPublicKey = opts.cstg.serverPublicKey; this._subscriptionId = opts.cstg.subscriptionId; - this._optoutCheck = opts.cstg.optoutCheck; - this._logInfo = logInfo; + this._logInfo = (...args) => logInfoWrapper(logInfo, ...args); this._logWarn = logWarn; } @@ -451,8 +459,7 @@ if (FEATURES.UID2_CSTG) { } async generateToken(cstgIdentity) { - const requestIdentity = await this.generateCstgRequest(cstgIdentity); - const request = { optout_check: this._optoutCheck, ...requestIdentity }; + const request = await this.generateCstgRequest(cstgIdentity); this._logInfo('Building CSTG request for', request); const box = await UID2CstgBox.build( this.stripPublicKeyPrefix(this._serverPublicKey) @@ -515,11 +522,11 @@ if (FEATURES.UID2_CSTG) { // A 200 should always be a success response. // Something has gone wrong. rejectPromise( - `API error: Response body was invalid for HTTP status 200: ${decryptedResponse}` + prependMessage(`API error: Response body was invalid for HTTP status 200: ${decryptedResponse}`) ); } } catch (err) { - rejectPromise(err); + rejectPromise(prependMessage(err)); } }, error: (error, xhr) => { @@ -527,32 +534,32 @@ if (FEATURES.UID2_CSTG) { if (xhr.status === 400) { const response = JSON.parse(xhr.responseText); if (this.isCstgApiClientErrorResponse(response)) { - rejectPromise(`Client error: ${response.message}`); + rejectPromise(prependMessage(`Client error: ${response.message}`)); } else { // A 400 should always be a client error. // Something has gone wrong. rejectPromise( - `API error: Response body was invalid for HTTP status 400: ${xhr.responseText}` + prependMessage(`UID2 API error: Response body was invalid for HTTP status 400: ${xhr.responseText}`) ); } } else if (xhr.status === 403) { const response = JSON.parse(xhr.responseText); if (this.isCstgApiForbiddenResponse(xhr)) { - rejectPromise(`Forbidden: ${response.message}`); + rejectPromise(prependMessage(`Forbidden: ${response.message}`)); } else { // A 403 should always be a forbidden response. // Something has gone wrong. rejectPromise( - `API error: Response body was invalid for HTTP status 403: ${xhr.responseText}` + prependMessage(`UID2 API error: Response body was invalid for HTTP status 403: ${xhr.responseText}`) ); } } else { rejectPromise( - `API error: Unexpected HTTP status ${xhr.status}: ${error}` + prependMessage(`UID2 API error: Unexpected HTTP status ${xhr.status}: ${error}`) ); } } catch (_e) { - rejectPromise(error); + rejectPromise(prependMessage(error)); } }, }, @@ -681,43 +688,45 @@ if (FEATURES.UID2_CSTG) { } export function Uid2GetId(config, prebidStorageManager, _logInfo, _logWarn) { + const logInfo = (...args) => logInfoWrapper(_logInfo, ...args); + let suppliedToken = null; const preferLocalStorage = (config.storage !== 'cookie'); - const storageManager = new Uid2StorageManager(prebidStorageManager, preferLocalStorage, config.internalStorage, _logInfo); - _logInfo(`Module is using ${preferLocalStorage ? 'local storage' : 'cookies'} for internal storage.`); + const storageManager = new Uid2StorageManager(prebidStorageManager, preferLocalStorage, config.internalStorage, logInfo); + logInfo(`Module is using ${preferLocalStorage ? 'local storage' : 'cookies'} for internal storage.`); const isCstgEnabled = clientSideTokenGenerator && clientSideTokenGenerator.isCSTGOptionsValid(config.cstg, _logWarn); if (isCstgEnabled) { - _logInfo(`Module is using client-side token generation.`); + logInfo(`Module is using client-side token generation.`); // Ignores config.paramToken and config.serverCookieName if any is provided suppliedToken = null; } else if (config.paramToken) { suppliedToken = config.paramToken; - _logInfo('Read token from params', suppliedToken); + logInfo('Read token from params', suppliedToken); } else if (config.serverCookieName) { suppliedToken = storageManager.readProvidedCookie(config.serverCookieName); - _logInfo('Read token from server-supplied cookie', suppliedToken); + logInfo('Read token from server-supplied cookie', suppliedToken); } let storedTokens = storageManager.getStoredValueWithFallback(); - _logInfo('Loaded module-stored tokens:', storedTokens); + logInfo('Loaded module-stored tokens:', storedTokens); if (storedTokens && typeof storedTokens === 'string') { // Stored value is a plain token - if no token is supplied, just use the stored value. if (!suppliedToken && !isCstgEnabled) { - _logInfo('Returning legacy cookie value.'); + logInfo('Returning legacy cookie value.'); return { id: storedTokens }; } // Otherwise, ignore the legacy value - it should get over-written later anyway. - _logInfo('Discarding superseded legacy cookie.'); + logInfo('Discarding superseded legacy cookie.'); storedTokens = null; } if (suppliedToken && storedTokens) { if (storedTokens.originalToken?.advertising_token !== suppliedToken.advertising_token) { - _logInfo('Server supplied new token - ignoring stored value.', storedTokens.originalToken?.advertising_token, suppliedToken.advertising_token); + logInfo('Server supplied new token - ignoring stored value.', storedTokens.originalToken?.advertising_token, suppliedToken.advertising_token); // Stored token wasn't originally sourced from the provided token - ignore the stored value. A new user has logged in? storedTokens = null; } @@ -726,16 +735,16 @@ export function Uid2GetId(config, prebidStorageManager, _logInfo, _logWarn) { if (FEATURES.UID2_CSTG && isCstgEnabled) { const cstgIdentity = clientSideTokenGenerator.getValidIdentity(config.cstg, _logWarn); if (cstgIdentity) { - if (storedTokens && clientSideTokenGenerator.isStoredTokenInvalid(cstgIdentity, storedTokens, _logInfo, _logWarn)) { + if (storedTokens && clientSideTokenGenerator.isStoredTokenInvalid(cstgIdentity, storedTokens, logInfo, _logWarn)) { storedTokens = null; } if (!storedTokens || Date.now() > storedTokens.latestToken.refresh_expires) { - const promise = clientSideTokenGenerator.generateTokenAndStore(config.apiBaseUrl, config.cstg, cstgIdentity, storageManager, _logInfo, _logWarn); - _logInfo('Generate token using CSTG'); + const promise = clientSideTokenGenerator.generateTokenAndStore(config.apiBaseUrl, config.cstg, cstgIdentity, storageManager, logInfo, _logWarn); + logInfo('Generate token using CSTG'); return { callback: (cb) => { promise.then((result) => { - _logInfo('Token generation responded, passing the new token on.', result); + logInfo('Token generation responded, passing the new token on.', result); cb(result); }); } }; @@ -745,25 +754,25 @@ export function Uid2GetId(config, prebidStorageManager, _logInfo, _logWarn) { const useSuppliedToken = !(storedTokens?.latestToken) || (suppliedToken && suppliedToken.identity_expires > storedTokens.latestToken.identity_expires); const newestAvailableToken = useSuppliedToken ? suppliedToken : storedTokens.latestToken; - _logInfo('UID2 module selected latest token', useSuppliedToken, newestAvailableToken); + logInfo('UID2 module selected latest token', useSuppliedToken, newestAvailableToken); if ((!newestAvailableToken || Date.now() > newestAvailableToken.refresh_expires)) { - _logInfo('Newest available token is expired and not refreshable.'); + logInfo('Newest available token is expired and not refreshable.'); return { id: null }; } if (Date.now() > newestAvailableToken.identity_expires) { - const promise = refreshTokenAndStore(config.apiBaseUrl, newestAvailableToken, config.clientId, storageManager, _logInfo, _logWarn); - _logInfo('Token is expired but can be refreshed, attempting refresh.'); + const promise = refreshTokenAndStore(config.apiBaseUrl, newestAvailableToken, config.clientId, storageManager, logInfo, _logWarn); + logInfo('Token is expired but can be refreshed, attempting refresh.'); return { callback: (cb) => { promise.then((result) => { - _logInfo('Refresh reponded, passing the updated token on.', result); + logInfo('Refresh reponded, passing the updated token on.', result); cb(result); }); } }; } // If should refresh (but don't need to), refresh in the background. if (Date.now() > newestAvailableToken.refresh_from) { - _logInfo(`Refreshing token in background with low priority.`); - refreshTokenAndStore(config.apiBaseUrl, newestAvailableToken, config.clientId, storageManager, _logInfo, _logWarn); + logInfo(`Refreshing token in background with low priority.`); + refreshTokenAndStore(config.apiBaseUrl, newestAvailableToken, config.clientId, storageManager, logInfo, _logWarn); } const tokens = { originalToken: suppliedToken ?? storedTokens?.originalToken, diff --git a/modules/unrulyBidAdapter.js b/modules/unrulyBidAdapter.js index b825003f36f..39d77c81b57 100644 --- a/modules/unrulyBidAdapter.js +++ b/modules/unrulyBidAdapter.js @@ -226,7 +226,7 @@ export const adapter = { 'options': { 'contentType': 'application/json' }, - 'protectedAudienceEnabled': bidderRequest.fledgeEnabled + 'protectedAudienceEnabled': bidderRequest.paapi?.enabled }, validBidRequests, bidderRequest); }, @@ -261,7 +261,7 @@ export const adapter = { return { bids, - fledgeAuctionConfigs + paapi: fledgeAuctionConfigs }; } }; diff --git a/modules/userId/eids.js b/modules/userId/eids.js index e5f7e3b8fb2..930dd34b23d 100644 --- a/modules/userId/eids.js +++ b/modules/userId/eids.js @@ -1,4 +1,7 @@ import {deepAccess, deepClone, isFn, isPlainObject, isStr} from '../../src/utils.js'; +/* + * @typedef {import('../modules/userId/index.js').SubmoduleContainer} SubmoduleContainer + */ export const EID_CONFIG = new Map(); diff --git a/modules/userId/eids.md b/modules/userId/eids.md index aa1601e95e3..53567032175 100644 --- a/modules/userId/eids.md +++ b/modules/userId/eids.md @@ -81,14 +81,6 @@ userIdAsEids = [ }] }, - { - source: 'parrable.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - { source: 'liveramp.com', uids: [{ diff --git a/modules/userId/index.js b/modules/userId/index.js index c2d7a9af2d8..b8d013df1c6 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -131,7 +131,7 @@ import {config} from '../../src/config.js'; import * as events from '../../src/events.js'; import {getGlobal} from '../../src/prebidGlobal.js'; import adapterManager, {gdprDataHandler} from '../../src/adapterManager.js'; -import { EVENTS } from '../../src/constants.js'; +import {EVENTS} from '../../src/constants.js'; import {module, ready as hooksReady} from '../../src/hook.js'; import {buildEidPermissions, createEidsArray, EID_CONFIG} from './eids.js'; import { @@ -147,7 +147,6 @@ import { getPrebidInternal, isArray, isEmpty, - isEmptyStr, isFn, isGptPubadsDefined, isNumber, @@ -166,12 +165,11 @@ import {MODULE_TYPE_UID} from '../../src/activities/modules.js'; import {isActivityAllowed} from '../../src/activities/rules.js'; import {ACTIVITY_ENRICH_EIDS} from '../../src/activities/activities.js'; import {activityParams} from '../../src/activities/activityParams.js'; +import {USERSYNC_DEFAULT_CONFIG} from '../../src/userSync.js'; const MODULE_NAME = 'User ID'; const COOKIE = STORAGE_TYPE_COOKIES; const LOCAL_STORAGE = STORAGE_TYPE_LOCALSTORAGE; -const DEFAULT_SYNC_DELAY = 500; -const NO_AUCTION_DELAY = 0; export const PBJS_USER_ID_OPTOUT_NAME = '_pbjs_id_optout'; export const coreStorage = getCoreStorageManager('userId'); export const dep = { @@ -952,29 +950,40 @@ function hasValidStorageTypes(config) { * @param {SubmoduleConfig[]} configRegistry * @returns {SubmoduleConfig[]} */ -function getValidSubmoduleConfigs(configRegistry) { +export function getValidSubmoduleConfigs(configRegistry) { + function err(msg, ...args) { + logWarn(`Invalid userSync.userId config: ${msg}`, ...args) + } if (!Array.isArray(configRegistry)) { + if (configRegistry != null) { + err('must be an array', configRegistry); + } return []; } - return configRegistry.reduce((carry, config) => { - // every submodule config obj must contain a valid 'name' - if (!config || isEmptyStr(config.name)) { - return carry; - } - // Validate storage config contains 'type' and 'name' properties with non-empty string values - // 'type' must be one of html5, cookies - if (config.storage && - !isEmptyStr(config.storage.type) && - !isEmptyStr(config.storage.name) && - hasValidStorageTypes(config)) { - carry.push(config); - } else if (isPlainObject(config.value)) { - carry.push(config); - } else if (!config.storage && !config.value) { - carry.push(config); + return configRegistry.filter(config => { + if (!config?.name) { + return err('must specify "name"', config); + } else if (config.storage) { + if (!config.storage.name || !config.storage.type) { + return err('must specify "storage.name" and "storage.type"', config); + } else if (!hasValidStorageTypes(config)) { + return err('invalid "storage.type"', config) + } + ['expires', 'refreshInSeconds'].forEach(param => { + let value = config.storage[param]; + if (value != null && typeof value !== 'number') { + value = Number(value) + if (isNaN(value)) { + err(`storage.${param} must be a number and will be ignored`, config); + delete config.storage[param]; + } else { + config.storage[param] = value; + } + } + }); } - return carry; - }, []); + return true; + }) } const ALL_STORAGE_TYPES = new Set([LOCAL_STORAGE, COOKIE]); @@ -1160,8 +1169,8 @@ export function init(config, {delay = GreedyPromise.timeout} = {}) { ppidSource = userSync.ppid; if (userSync.userIds) { configRegistry = userSync.userIds; - syncDelay = isNumber(userSync.syncDelay) ? userSync.syncDelay : DEFAULT_SYNC_DELAY; - auctionDelay = isNumber(userSync.auctionDelay) ? userSync.auctionDelay : NO_AUCTION_DELAY; + syncDelay = isNumber(userSync.syncDelay) ? userSync.syncDelay : USERSYNC_DEFAULT_CONFIG.syncDelay + auctionDelay = isNumber(userSync.auctionDelay) ? userSync.auctionDelay : USERSYNC_DEFAULT_CONFIG.auctionDelay; updateSubmodules(); updateIdPriority(userSync.idPriority, submodules); initIdSystem({ready: true}); diff --git a/modules/userId/userId.md b/modules/userId/userId.md index 1ec109ff309..9fb53c2c7b3 100644 --- a/modules/userId/userId.md +++ b/modules/userId/userId.md @@ -70,12 +70,6 @@ pbjs.setConfig({ params: { url: 'https://d9.flashtalking.com/d9core', // required, if not populated ftrack will not run } - }, { - name: 'parrableId', - params: { - // Replace partner with comma-separated (if more than one) Parrable Partner Client ID(s) for Parrable-aware bid adapters in use - partner: "30182847-e426-4ff9-b2b5-9ca1324ea09b" - } },{ name: 'identityLink', params: { diff --git a/modules/utiqSystem.js b/modules/utiqIdSystem.js similarity index 90% rename from modules/utiqSystem.js rename to modules/utiqIdSystem.js index 473dc5854a9..d6b8aae44a3 100644 --- a/modules/utiqSystem.js +++ b/modules/utiqIdSystem.js @@ -1,7 +1,7 @@ /** * This module adds Utiq provided by Utiq SA/NV to the User ID module * The {@link module:modules/userId} module is required - * @module modules/utiqSystem + * @module modules/utiqIdSystem * @requires module:modules/userId */ import { logInfo } from '../src/utils.js'; @@ -9,7 +9,7 @@ import { submodule } from '../src/hook.js'; import { getStorageManager } from '../src/storageManager.js'; import { MODULE_TYPE_UID } from '../src/activities/modules.js'; -const MODULE_NAME = 'utiq'; +const MODULE_NAME = 'utiqId'; const LOG_PREFIX = 'Utiq module'; export const storage = getStorageManager({ @@ -27,11 +27,6 @@ function getUtiqFromStorage() { let utiqPassStorage = JSON.parse( storage.getDataFromLocalStorage('utiqPass') ); - logInfo( - `${LOG_PREFIX}: Local storage utiqPass: ${JSON.stringify( - utiqPassStorage - )}` - ); if ( utiqPassStorage && @@ -40,12 +35,19 @@ function getUtiqFromStorage() { utiqPassStorage.connectId.idGraph.length > 0 ) { utiqPass = utiqPassStorage.connectId.idGraph[0]; + + logInfo( + `${LOG_PREFIX}: Local storage utiqPass: ${JSON.stringify( + utiqPassStorage + )}` + ); + + logInfo( + `${LOG_PREFIX}: Graph of utiqPass: ${JSON.stringify( + utiqPass + )}` + ); } - logInfo( - `${LOG_PREFIX}: Graph of utiqPass: ${JSON.stringify( - utiqPass - )}` - ); return { utiq: @@ -56,7 +58,7 @@ function getUtiqFromStorage() { } /** @type {Submodule} */ -export const utiqSubmodule = { +export const utiqIdSubmodule = { /** * Used to link submodule with config * @type {string} @@ -135,4 +137,4 @@ export const utiqSubmodule = { } }; -submodule('userId', utiqSubmodule); +submodule('userId', utiqIdSubmodule); diff --git a/modules/utiqSystem.md b/modules/utiqIdSystem.md similarity index 54% rename from modules/utiqSystem.md rename to modules/utiqIdSystem.md index d2c53480383..c7f4f95827f 100644 --- a/modules/utiqSystem.md +++ b/modules/utiqIdSystem.md @@ -5,7 +5,7 @@ Utiq ID Module. First, make sure to add the utiq submodule to your Prebid.js package with: ``` -gulp build --modules=userId,adfBidAdapter,ixBidAdapter,prebidServerBidAdapter,utiqSystem +gulp build --modules=userId,adfBidAdapter,ixBidAdapter,prebidServerBidAdapter,utiqIdSystem ``` ## Parameter Descriptions @@ -15,8 +15,3 @@ gulp build --modules=userId,adfBidAdapter,ixBidAdapter,prebidServerBidAdapter,ut | name | String | The name of the module | `"utiq"` | | params | Object | Object with configuration parameters for utiq User Id submodule | - | | params.maxDelayTime | Integer | Max amount of time (in seconds) before looking into storage for data | 2500 | -| bidders | Array of Strings | An array of bidder codes to which this user ID may be sent. Currently required and supporting AdformOpenRTB | [`"adf"`, `"adformPBS"`, `"ix"`] | -| storage | Object | Local storage configuration object | - | -| storage.type | String | Type of the storage that would be used to store user ID. Must be `"html5"` to utilise HTML5 local storage. | `"html5"` | -| storage.name | String | The name of the key in local storage where the user ID will be stored. | `"utiq"` | -| storage.expires | Integer | How long (in days) the user ID information will be stored. For safety reasons, this information is required. | `1` | diff --git a/modules/validationFpdModule/index.js b/modules/validationFpdModule/index.js index 70af9d30ec3..2330c41099c 100644 --- a/modules/validationFpdModule/index.js +++ b/modules/validationFpdModule/index.js @@ -13,8 +13,8 @@ let optout; /** * Check if data passed is empty - * @param {*} value to test against - * @returns {Boolean} is value empty + * @param {*} data to test against + * @returns {Boolean} is data empty */ function isEmptyData(data) { let check = true; @@ -30,10 +30,10 @@ function isEmptyData(data) { /** * Check if required keys exist in data object - * @param {Object} data object - * @param {Array} array of required keys - * @param {String} object path (for printing warning) - * @param {Number} index of object value in the data array (for printing warning) + * @param {Object} obj data object + * @param {Array} required array of required keys + * @param {String} parent object path (for printing warning) + * @param {Number} i index of object value in the data array (for printing warning) * @returns {Boolean} is requirements fulfilled */ function getRequiredData(obj, required, parent, i) { @@ -51,8 +51,8 @@ function getRequiredData(obj, required, parent, i) { /** * Check if data type is valid - * @param {*} value to test against - * @param {Object} object containing type definition and if should be array bool + * @param {*} data value to test against + * @param {Object} mapping object containing type definition and if should be array bool * @returns {Boolean} is type fulfilled */ function typeValidation(data, mapping) { @@ -77,10 +77,10 @@ function typeValidation(data, mapping) { /** * Validates ortb2 data arrays and filters out invalid data - * @param {Array} ortb2 data array - * @param {Object} object defining child type and if array - * @param {String} config path of data array - * @param {String} parent path for logging warnings + * @param {Array} arr ortb2 data array + * @param {Object} child object defining child type and if array + * @param {String} path config path of data array + * @param {String} parent parent path for logging warnings * @returns {Array} validated/filtered data */ export function filterArrayData(arr, child, path, parent) { @@ -136,9 +136,9 @@ export function filterArrayData(arr, child, path, parent) { /** * Validates ortb2 object and filters out invalid data - * @param {Object} ortb2 object - * @param {String} config path of data array - * @param {String} parent path for logging warnings + * @param {Object} fpd ortb2 object + * @param {String} path config path of data array + * @param {String} parent parent path for logging warnings * @returns {Object} validated/filtered data */ export function validateFpd(fpd, path = '', parent = '') { @@ -190,6 +190,8 @@ export function validateFpd(fpd, path = '', parent = '') { /** * Run validation on global and bidder config data for ortb2 + * @param {Object} data global and bidder config data + * @returns {Object} validated data */ function runValidations(data) { return { @@ -200,6 +202,9 @@ function runValidations(data) { /** * Sets default values to ortb2 if exists and adds currency and ortb2 setConfig callbacks on init + * @param {Object} fpdConf configuration object + * @param {Object} data ortb2 data + * @returns {Object} processed data */ export function processFpd(fpdConf, data) { // Checks for existsnece of pubcid optout cookie/storage @@ -210,11 +215,11 @@ export function processFpd(fpdConf, data) { return (!fpdConf.skipValidations) ? runValidations(data) : data; } -/** @type {firstPartyDataSubmodule} */ +/** @type {{name: string, queue: number, processFpd: function}} */ export const validationSubmodule = { name: 'validation', queue: 1, processFpd } -submodule('firstPartyData', validationSubmodule) +submodule('firstPartyData', validationSubmodule); diff --git a/modules/vdoaiBidAdapter.js b/modules/vdoaiBidAdapter.js index ada843a6e45..f375e161f88 100644 --- a/modules/vdoaiBidAdapter.js +++ b/modules/vdoaiBidAdapter.js @@ -48,7 +48,6 @@ export const spec = { id: bidRequest.auctionId, mediaType: bidRequest.mediaTypes.video ? 'video' : 'banner' }; - bidRequest.params.bidFloor && (payload['bidFloor'] = bidRequest.params.bidFloor); return { method: 'POST', url: ENDPOINT_URL, diff --git a/modules/viantOrtbBidAdapter.js b/modules/viantOrtbBidAdapter.js index d056dfeb2eb..b4448715f7a 100644 --- a/modules/viantOrtbBidAdapter.js +++ b/modules/viantOrtbBidAdapter.js @@ -6,6 +6,7 @@ import {deepAccess, getBidIdParameter, logError} from '../src/utils.js'; const BIDDER_CODE = 'viant'; const ENDPOINT = 'https://bidders-us-east-1.adelphic.net/d/rtb/v25/prebid/bidder' +const ADAPTER_VERSION = '2.0.0'; const DEFAULT_BID_TTL = 300; const DEFAULT_CURRENCY = 'USD'; @@ -85,6 +86,25 @@ function createRequest(bidRequests, bidderRequest, mediaType) { if (!data.regs.ext) data.regs.ext = {}; data.regs.ext.us_privacy = bidderRequest.uspConsent; } + let imp = data.imp || []; + let dealsMap = new Map(); + if (bidderRequest.bids) { + bidderRequest.bids.forEach(bid => { + if (bid.ortb2Imp && bid.ortb2Imp.pmp) { + dealsMap.set(bid.bidId, bid.ortb2Imp.pmp); + } + }); + } + imp.forEach((element) => { + let deals = dealsMap.get(element.id); + if (deals) { + element.pmp = deals; + } + }); + data.ext = data.ext || {}; + data.ext.viant = { + adapterVersion: ADAPTER_VERSION + }; return { method: 'POST', url: ENDPOINT, diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index c5e35c6b138..ed732a4814a 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -1,494 +1,46 @@ -import { - _each, - deepAccess, - isFn, - parseSizesInput, - parseUrl, - uniques, - isArray, - formatQS, - triggerPixel -} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {getStorageManager} from '../src/storageManager.js'; -import {bidderSettings} from '../src/bidderSettings.js'; -import {config} from '../src/config.js'; -import {chunk} from '../libraries/chunk/chunk.js'; +import { + createSessionId, + isBidRequestValid, + getCacheOpt, + getNextDealId, + onBidWon, + createUserSyncGetter, + getVidazooSessionId, + createBuildRequestsFn, + createInterpretResponseFn +} from '../libraries/vidazooUtils/bidderUtils.js'; +import {OPT_CACHE_KEY, OPT_TIME_KEY} from '../libraries/vidazooUtils/constants.js'; const GVLID = 744; const DEFAULT_SUB_DOMAIN = 'prebid'; const BIDDER_CODE = 'vidazoo'; const BIDDER_VERSION = '1.0.0'; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const DEAL_ID_EXPIRY = 1000 * 60 * 15; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 60; -const SESSION_ID_KEY = 'vidSid'; -const OPT_CACHE_KEY = 'vdzwopt'; -export const webSessionId = 'wsid_' + parseInt(Date.now() * Math.random()); -const storage = getStorageManager({bidderCode: BIDDER_CODE}); - -function getTopWindowQueryParams() { - try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const webSessionId = createSessionId(); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.cootlogix.com`; } -export function extractCID(params) { - return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; -} - -export function extractPID(params) { - return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; -} - -export function extractSubDomain(params) { - return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const { - params, - bidId, - userId, - adUnitCode, - schain, - mediaTypes, - ortb2Imp, - bidderRequestId, - bidRequestsCount, - bidderRequestsCount, - bidderWinsCount - } = bid; - const {ext} = params; - let {bidFloor} = params; - const hashUrl = hashCode(topWindowUrl); - const dealId = getNextDealId(hashUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const sId = getVidazooSessionId(); - const pId = extractPID(params); - const ptrace = getCacheOpt(); - const isStorageAllowed = bidderSettings.get(BIDDER_CODE, 'storageAllowed'); - - const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', ''); - const cat = deepAccess(bidderRequest, 'ortb2.site.cat', []); - const pagecat = deepAccess(bidderRequest, 'ortb2.site.pagecat', []); - const contentData = deepAccess(bidderRequest, 'ortb2.site.content.data', []); - const userData = deepAccess(bidderRequest, 'ortb2.user.data', []); - - if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*' - }); - - if (floorInfo.currency === 'USD') { - bidFloor = floorInfo.floor; - } - } - - let data = { - url: encodeURIComponent(topWindowUrl), - uqs: getTopWindowQueryParams(), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - referrer: bidderRequest.refererInfo.ref, - adUnitCode: adUnitCode, - publisherId: pId, - sessionId: sId, - sizes: sizes, - dealId: dealId, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}`, - schain: schain, - mediaTypes: mediaTypes, - ptrace: ptrace, - isStorageAllowed: isStorageAllowed, - gpid: gpid, - cat: cat, - contentData, - userData: userData, - pagecat: pagecat, - transactionId: ortb2Imp?.ext?.tid, - bidderRequestId: bidderRequestId, - bidRequestsCount: bidRequestsCount, - bidderRequestsCount: bidderRequestsCount, - bidderWinsCount: bidderWinsCount, - bidderTimeout: bidderTimeout, - webSessionId: webSessionId - }; - - appendUserIdsToRequestPayload(data, userId); - - const sua = deepAccess(bidderRequest, 'ortb2.device.sua'); - - if (sua) { - data.sua = sua; - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest.gppConsent) { - data.gppString = bidderRequest.gppConsent.gppString; - data.gppSid = bidderRequest.gppConsent.applicableSections; - } else if (bidderRequest.ortb2?.regs?.gpp) { - data.gppString = bidderRequest.ortb2.regs.gpp; - data.gppSid = bidderRequest.ortb2.regs.gpp_sid; - } - - if (bidderRequest.fledgeEnabled) { - const fledge = deepAccess(bidderRequest, 'ortb2Imp.ext.ae'); - if (fledge) { - data.fledge = fledge; - } - } - - _each(ext, (value, key) => { - data['ext.' + key] = value; - }); - - return data; -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const {params} = bid; - const cId = extractCID(params); - const subDomain = extractSubDomain(params); - const data = buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout); - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data - }; - return dto; -} - -function buildSingleRequest(bidRequests, bidderRequest, topWindowUrl, bidderTimeout) { - const {params} = bidRequests[0]; - const cId = extractCID(params); - const subDomain = extractSubDomain(params); - const data = bidRequests.map(bid => { - const sizes = parseSizesInput(bid.sizes); - return buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) - }); - const chunkSize = Math.min(20, config.getConfig('vidazoo.chunkSize') || 10); - - const chunkedData = chunk(data, chunkSize); - return chunkedData.map(chunk => { - return { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: { - bids: chunk - } - }; - }); -} - -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - _each(userIds, (userId, idSystemProviderName) => { - key = `uid.${idSystemProviderName}`; - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - }); -} - -function buildRequests(validBidRequests, bidderRequest) { - // TODO: does the fallback make sense here? - const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation; - const bidderTimeout = config.getConfig('bidderTimeout'); - - const singleRequestMode = config.getConfig('vidazoo.singleRequest'); - - const requests = []; - - if (singleRequestMode) { - // banner bids are sent as a single request - const bannerBidRequests = validBidRequests.filter(bid => isArray(bid.mediaTypes) ? bid.mediaTypes.includes(BANNER) : bid.mediaTypes[BANNER] !== undefined); - if (bannerBidRequests.length > 0) { - const singleRequests = buildSingleRequest(bannerBidRequests, bidderRequest, topWindowUrl, bidderTimeout); - requests.push(...singleRequests); - } - - // video bids are sent as a single request for each bid - - const videoBidRequests = validBidRequests.filter(bid => bid.mediaTypes[VIDEO] !== undefined); - videoBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - } else { - validBidRequests.forEach(validBidRequest => { - const sizes = parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout); - requests.push(request); - }); - } - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - - const singleRequestMode = config.getConfig('vidazoo.singleRequest'); - const reqBidId = deepAccess(request, 'data.bidId'); - const {results} = serverResponse.body; - - let output = []; - - try { - results.forEach((result, i) => { - const { - creativeId, - ad, - price, - exp, - width, - height, - currency, - bidId, - nurl, - advertiserDomains, - metaData, - mediaType = BANNER - } = result; - if (!ad || !price) { - return; - } - - const response = { - requestId: (singleRequestMode && bidId) ? bidId : reqBidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - }; - - if (nurl) { - response.nurl = nurl; - } - - if (metaData) { - Object.assign(response, { - meta: metaData - }) - } else { - Object.assign(response, { - meta: { - advertiserDomains: advertiserDomains || [] - } - }) - } - - if (mediaType === BANNER) { - Object.assign(response, { - ad: ad, - }); - } else { - Object.assign(response, { - vastXml: ad, - mediaType: VIDEO - }); - } - output.push(response); - }); - - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '', gppConsent = {}) { - let syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - const {gppString, applicableSections} = gppConsent; - - const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques); - let params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}`; +function createUniqueRequestData(hashUrl) { + const dealId = getNextDealId(storage, hashUrl); + const sessionId = getVidazooSessionId(storage); + const ptrace = getCacheOpt(storage, OPT_CACHE_KEY); + const vdzhum = getCacheOpt(storage, OPT_TIME_KEY); - if (gppString && applicableSections?.length) { - params += '&gpp=' + encodeURIComponent(gppString); - params += '&gpp_sid=' + encodeURIComponent(applicableSections.join(',')); - } - - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.cootlogix.com/api/sync/iframe/${params}` - }); - } - if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.cootlogix.com/api/sync/image/${params}` - }); - } - return syncs; -} - -/** - * @param {Bid} bid - */ -function onBidWon(bid) { - if (!bid.nurl) { - return; - } - const wonBid = { - adId: bid.adId, - creativeId: bid.creativeId, - auctionId: bid.auctionId, - transactionId: bid.transactionId, - adUnitCode: bid.adUnitCode, - cpm: bid.cpm, - currency: bid.currency, - originalCpm: bid.originalCpm, - originalCurrency: bid.originalCurrency, - netRevenue: bid.netRevenue, - mediaType: bid.mediaType, - timeToRespond: bid.timeToRespond, - status: bid.status, + return { + dealId: dealId, sessionId: sessionId, ptrace: ptrace, vdzhum: vdzhum, webSessionId: webSessionId }; - const qs = formatQS(wonBid); - const url = bid.nurl + (bid.nurl.indexOf('?') === -1 ? '?' : '&') + qs; - triggerPixel(url); -} - -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { - h = (h << 5) - h + s.charCodeAt(i++) | 0; - } - } - return prefix + h; } -export function getNextDealId(key, expiry = DEAL_ID_EXPIRY) { - try { - const data = getStorageItem(key); - let currentValue = 0; - let timestamp; - - if (data && data.value && Date.now() - data.created < expiry) { - currentValue = data.value; - timestamp = data.created; - } - - const nextValue = currentValue + 1; - setStorageItem(key, nextValue, timestamp); - return nextValue; - } catch (e) { - return 0; - } -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getVidazooSessionId() { - return getStorageItem(SESSION_ID_KEY) || ''; -} - -export function getCacheOpt() { - let data = storage.getDataFromLocalStorage(OPT_CACHE_KEY); - if (!data) { - data = String(Date.now()); - storage.setDataInLocalStorage(OPT_CACHE_KEY, data); - } - - return data; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { - } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); - storage.setDataInLocalStorage(key, data); - } catch (e) { - } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} +const buildRequests = createBuildRequestsFn(createDomain, createUniqueRequestData, storage, BIDDER_CODE, BIDDER_VERSION, true); +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, true); +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.cootlogix.com/api/sync/iframe', imageSyncUrl: 'https://sync.cootlogix.com/api/sync/image' +}); export const spec = { code: BIDDER_CODE, diff --git a/modules/videobyteBidAdapter.js b/modules/videobyteBidAdapter.js index 8cedf9ac16a..b62474d0c25 100644 --- a/modules/videobyteBidAdapter.js +++ b/modules/videobyteBidAdapter.js @@ -19,6 +19,7 @@ const VIDEO_ORTB_PARAMS = [ 'minduration', 'maxduration', 'placement', + 'plcmt', 'protocols', 'startdelay', 'skip', @@ -191,16 +192,6 @@ function buildRequestData(bidRequest, bidderRequest) { } }); - // Placement Inference Rules: - // - If no placement is defined then default to 1 (In Stream) - video.placement = video.placement || 2; - - // - If product is instream (for instream context) then override placement to 1 - if (params.context === 'instream') { - video.startdelay = video.startdelay || 0; - video.placement = 1; - } - // bid floor const bidFloorRequest = { currency: bidRequest.params.cur || 'USD', diff --git a/modules/videojsVideoProvider.js b/modules/videojsVideoProvider.js index 7764e8af995..0be4c6feede 100644 --- a/modules/videojsVideoProvider.js +++ b/modules/videojsVideoProvider.js @@ -6,13 +6,16 @@ import { } from '../libraries/video/constants/events.js'; // missing events: , AD_BREAK_START, , AD_BREAK_END, VIEWABLE, BUFFER, CAST, PLAYLIST_COMPLETE, RENDITION_UPDATE, PLAY_ATTEMPT_FAILED, AUTOSTART_BLOCKED import { - PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLACEMENT, VPAID_MIME_TYPE, AD_POSITION, PLAYBACK_END + PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLCMT, VPAID_MIME_TYPE, AD_POSITION, PLAYBACK_END } from '../libraries/video/constants/ortb.js'; import { VIDEO_JS_VENDOR } from '../libraries/video/constants/vendorCodes.js'; import { submodule } from '../src/hook.js'; import stateFactory from '../libraries/video/shared/state.js'; import { PLAYBACK_MODE } from '../libraries/video/constants/constants.js'; import { getEventHandler } from '../libraries/video/shared/eventHandler.js'; +/** + * @typedef {import('../libraries/video/shared/state.js').State} State + */ /* Plugins of interest: @@ -146,8 +149,9 @@ export function VideojsProvider(providerConfig, vjs_, adState_, timeState_, call // ~ Sort of resolved check if the player has a source to tell if the placement is instream // Still cannot reliably check what type of placement the player is if its outstream // i.e. we can't tell if its interstitial, in article, etc. + // update: cannot infer instream ever, always need declarations if (player.src()) { - video.placement = PLACEMENT.INSTREAM; + video.plcmt = PLCMT.ACCOMPANYING_CONTENT; } // Placement according to IQG Guidelines 4.2.8 diff --git a/modules/visiblemeasuresBidAdapter.js b/modules/visiblemeasuresBidAdapter.js index e77477c812b..1c51944c538 100644 --- a/modules/visiblemeasuresBidAdapter.js +++ b/modules/visiblemeasuresBidAdapter.js @@ -1,212 +1,19 @@ -import { isFn, deepAccess, logMessage, logError } from '../src/utils.js'; -import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; - import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; const BIDDER_CODE = 'visiblemeasures'; const AD_URL = 'https://us-e.visiblemeasures.com/pbjs'; const SYNC_URL = 'https://cs.visiblemeasures.com'; -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl || bid.vastXml); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length); - default: - return false; - } -} - -function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; - const { placementId, endpointId } = params; - const bidfloor = getBidFloor(bid); - - const placement = { - bidId, - schain, - bidfloor - }; - - if (placementId) { - placement.placementId = placementId; - placement.type = 'publisher'; - } else if (endpointId) { - placement.endpointId = endpointId; - placement.type = 'network'; - } - - if (mediaTypes && mediaTypes[BANNER]) { - placement.adFormat = BANNER; - placement.sizes = mediaTypes[BANNER].sizes; - } else if (mediaTypes && mediaTypes[VIDEO]) { - placement.adFormat = VIDEO; - placement.playerSize = mediaTypes[VIDEO].playerSize; - placement.minduration = mediaTypes[VIDEO].minduration; - placement.maxduration = mediaTypes[VIDEO].maxduration; - placement.mimes = mediaTypes[VIDEO].mimes; - placement.protocols = mediaTypes[VIDEO].protocols; - placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; - placement.skip = mediaTypes[VIDEO].skip; - placement.skipafter = mediaTypes[VIDEO].skipafter; - placement.minbitrate = mediaTypes[VIDEO].minbitrate; - placement.maxbitrate = mediaTypes[VIDEO].maxbitrate; - placement.delivery = mediaTypes[VIDEO].delivery; - placement.playbackmethod = mediaTypes[VIDEO].playbackmethod; - placement.api = mediaTypes[VIDEO].api; - placement.linearity = mediaTypes[VIDEO].linearity; - } else if (mediaTypes && mediaTypes[NATIVE]) { - placement.native = mediaTypes[NATIVE]; - placement.adFormat = NATIVE; - } - - return placement; -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (err) { - logError(err); - return 0; - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: (bid = {}) => { - const { params, bidId, mediaTypes } = bid; - let valid = Boolean(bidId && params && (params.placementId || params.endpointId)); - - if (mediaTypes && mediaTypes[BANNER]) { - valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes); - } else if (mediaTypes && mediaTypes[VIDEO]) { - valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize); - } else if (mediaTypes && mediaTypes[NATIVE]) { - valid = valid && Boolean(mediaTypes[NATIVE]); - } else { - valid = false; - } - return valid; - }, - - buildRequests: (validBidRequests = [], bidderRequest = {}) => { - // convert Native ORTB definition to old-style prebid native definition - validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); - - let deviceWidth = 0; - let deviceHeight = 0; - - let winLocation; - try { - const winTop = window.top; - deviceWidth = winTop.screen.width; - deviceHeight = winTop.screen.height; - winLocation = winTop.location; - } catch (e) { - logMessage(e); - winLocation = window.location; - } - - const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page; - let refferLocation; - try { - refferLocation = refferUrl && new URL(refferUrl); - } catch (e) { - logMessage(e); - } - // TODO: does the fallback make sense here? - let location = refferLocation || winLocation; - const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : ''; - const host = location.host; - const page = location.pathname; - const secure = location.protocol === 'https:' ? 1 : 0; - const placements = []; - const request = { - deviceWidth, - deviceHeight, - language, - secure, - host, - page, - placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, - tmax: bidderRequest.timeout - }; - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - placements.push(getPlacementReqData(bid)); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : []; - resItem.meta = { ...resItem.meta, advertiserDomains }; - - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; - if (gdprConsent && gdprConsent.consentString) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent && uspConsent.consentString) { - syncUrl += `&ccpa_consent=${uspConsent.consentString}`; - } - - const coppa = config.getConfig('coppa') ? 1 : 0; - syncUrl += `&coppa=${coppa}`; - - return [{ - type: syncType, - url: syncUrl - }]; - } + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) }; registerBidder(spec); diff --git a/modules/visxBidAdapter.js b/modules/visxBidAdapter.js index c7f415e4dac..217cab48cee 100644 --- a/modules/visxBidAdapter.js +++ b/modules/visxBidAdapter.js @@ -1,10 +1,11 @@ -import {deepAccess, logError, parseSizesInput, triggerPixel} from '../src/utils.js'; +import {deepAccess, logError, mergeDeep, parseSizesInput, sizeTupleToRtbSize, sizesToSizeTuples, triggerPixel} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {config} from '../src/config.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {INSTREAM as VIDEO_INSTREAM} from '../src/video.js'; import {getStorageManager} from '../src/storageManager.js'; import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { getBidFromResponse } from '../libraries/processResponse/index.js'; const BIDDER_CODE = 'visx'; const GVLID = 154; @@ -32,7 +33,7 @@ const LOG_ERROR_MESS = { onlyVideoInstream: `Only video ${VIDEO_INSTREAM} supported`, videoMissing: 'Bid request videoType property is missing - ' }; -const currencyWhiteList = ['EUR', 'USD', 'GBP', 'PLN']; +const currencyWhiteList = ['EUR', 'USD', 'GBP', 'PLN', 'CHF', 'SEK']; export const storage = getStorageManager({bidderCode: BIDDER_CODE}); const _bidResponseTimeLogged = []; export const spec = { @@ -69,6 +70,7 @@ export const spec = { let payloadSite; let payloadRegs; let payloadContent; + let payloadUser; if (currencyWhiteList.indexOf(currency) === -1) { logError(LOG_ERROR_MESS.notAllowedCurrency + currency); @@ -116,6 +118,24 @@ export const spec = { const { ortb2 } = bidderRequest; const { device, site, regs, content } = ortb2; + const userOrtb2 = ortb2.user; + let user; + let userReq; + const vads = _getUserId(); + if (payloadUserEids || payload.gdpr_consent || vads) { + user = { + ext: { + ...(payloadUserEids && { eids: payloadUserEids }), + ...(payload.gdpr_consent && { consent: payload.gdpr_consent }), + ...(vads && { vads }) + } + }; + } + if (user) { + userReq = mergeDeep(user, userOrtb2); + } else { + userReq = userOrtb2; + } if (device) { payloadDevice = device; } @@ -128,6 +148,9 @@ export const spec = { if (content) { payloadContent = content; } + if (userReq) { + payloadUser = userReq; + } } const tmax = timeout; @@ -139,14 +162,6 @@ export const spec = { } }; - const vads = _getUserId(); - const user = { - ext: { - ...(payloadUserEids && { eids: payloadUserEids }), - ...(payload.gdpr_consent && { consent: payload.gdpr_consent }), - ...(vads && { vads }) - } - }; if (payloadRegs === undefined) { payloadRegs = ('gdpr_applies' in payload) && { ext: { @@ -161,7 +176,7 @@ export const spec = { tmax, cur: [currency], source, - ...(Object.keys(user.ext).length && { user }), + ...(payloadUser && { user: payloadUser }), ...(payloadRegs && {regs: payloadRegs}), ...(payloadDevice && { device: payloadDevice }), ...(payloadSite && { site: payloadSite }), @@ -190,7 +205,7 @@ export const spec = { if (!errorMessage && serverResponse.seatbid) { serverResponse.seatbid.forEach(respItem => { - _addBidResponse(_getBidFromResponse(respItem), bidsMap, currency, bidResponses); + _addBidResponse(getBidFromResponse(respItem, LOG_ERROR_MESS), bidsMap, currency, bidResponses); }); } if (errorMessage) logError(errorMessage); @@ -260,13 +275,7 @@ function makeBanner(bannerParams) { if (bannerSizes) { const sizes = parseSizesInput(bannerSizes); if (sizes.length) { - const format = sizes.map(size => { - const [ width, height ] = size.split('x'); - const w = parseInt(width, 10); - const h = parseInt(height, 10); - return { w, h }; - }); - + const format = sizesToSizeTuples(bannerSizes).map(sizeTupleToRtbSize); return { format }; } } @@ -306,17 +315,6 @@ function buildImpObject(bid) { } } -function _getBidFromResponse(respItem) { - if (!respItem) { - logError(LOG_ERROR_MESS.emptySeatbid); - } else if (!respItem.bid) { - logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); - } else if (!respItem.bid[0]) { - logError(LOG_ERROR_MESS.noBid); - } - return respItem && respItem.bid && respItem.bid[0]; -} - function _addBidResponse(serverBid, bidsMap, currency, bidResponses) { if (!serverBid) return; let errorMessage; diff --git a/modules/waardexBidAdapter.js b/modules/waardexBidAdapter.js index 92b7fc26e4c..c4ca5d299bc 100644 --- a/modules/waardexBidAdapter.js +++ b/modules/waardexBidAdapter.js @@ -147,7 +147,6 @@ const createVideoObject = (videoMediaTypes, videoParams) => { maxduration: getBidIdParameter('maxduration', videoParams) || 500, protocols: getBidIdParameter('protocols', videoParams) || [2, 3, 5, 6], startdelay: getBidIdParameter('startdelay', videoParams) || 0, - placement: getBidIdParameter('placement', videoParams) || videoMediaTypes.context === 'outstream' ? 3 : 1, skip: getBidIdParameter('skip', videoParams) || 1, skipafter: getBidIdParameter('skipafter', videoParams) || 0, minbitrate: getBidIdParameter('minbitrate', videoParams) || 0, diff --git a/modules/widespaceBidAdapter.js b/modules/widespaceBidAdapter.js index ea6f1bce793..6fa14f5d68c 100644 --- a/modules/widespaceBidAdapter.js +++ b/modules/widespaceBidAdapter.js @@ -1,6 +1,6 @@ import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {parseQueryStringParameters, parseSizesInput} from '../src/utils.js'; +import {deepClone, parseQueryStringParameters, parseSizesInput} from '../src/utils.js'; import {find, includes} from '../src/polyfill.js'; import {getStorageManager} from '../src/storageManager.js'; @@ -212,7 +212,7 @@ function getLcuid() { } function encodedParamValue(value) { - const requiredStringify = typeof JSON.parse(JSON.stringify(value)) === 'object'; + const requiredStringify = typeof deepClone(value) === 'object'; return encodeURIComponent(requiredStringify ? JSON.stringify(value) : value); } diff --git a/modules/winrBidAdapter.js b/modules/winrBidAdapter.js index 6cde0412071..b29a854cbab 100644 --- a/modules/winrBidAdapter.js +++ b/modules/winrBidAdapter.js @@ -13,9 +13,10 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER} from '../src/mediaTypes.js'; import {find, includes} from '../src/polyfill.js'; import {getStorageManager} from '../src/storageManager.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js'; +import { transformSizes } from '../libraries/sizeUtils/tranformSize.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -456,7 +457,7 @@ function bidToTag(bid) { } tag.keywords = getANKeywordParam(bid.ortb2, bid.params.keywords) - let gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); + let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); if (gpid) { tag.gpid = gpid; } @@ -470,32 +471,6 @@ function bidToTag(bid) { return tag; } -/* Turn bid request sizes into ut-compatible format */ -function transformSizes(requestSizes) { - let sizes = []; - let sizeObj = {}; - - if ( - isArray(requestSizes) && - requestSizes.length === 2 && - !isArray(requestSizes[0]) - ) { - sizeObj.width = parseInt(requestSizes[0], 10); - sizeObj.height = parseInt(requestSizes[1], 10); - sizes.push(sizeObj); - } else if (typeof requestSizes === 'object') { - for (let i = 0; i < requestSizes.length; i++) { - let size = requestSizes[i]; - sizeObj = {}; - sizeObj.width = parseInt(size[0], 10); - sizeObj.height = parseInt(size[1], 10); - sizes.push(sizeObj); - } - } - - return sizes; -} - function hasUserInfo(bid) { return !!bid.params.user; } diff --git a/modules/yahoosspBidAdapter.js b/modules/yahooAdsBidAdapter.js similarity index 98% rename from modules/yahoosspBidAdapter.js rename to modules/yahooAdsBidAdapter.js index 0453350a85a..49efb7c20cb 100644 --- a/modules/yahoosspBidAdapter.js +++ b/modules/yahooAdsBidAdapter.js @@ -3,12 +3,15 @@ import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { deepAccess, isFn, isStr, isNumber, isArray, isEmpty, isPlainObject, generateUUID, logInfo, logWarn } from '../src/utils.js'; import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; -import {hasPurpose1Consent} from '../src/utils/gpdr.js'; +import {hasPurpose1Consent} from '../src/utils/gdpr.js'; const INTEGRATION_METHOD = 'prebid.js'; const BIDDER_CODE = 'yahooAds'; -const BIDDER_ALIASES = ['yahoossp', 'yahooAdvertising'] const GVLID = 25; +const BIDDER_ALIASES = [ + { code: 'yahoossp', gvlid: GVLID }, + { code: 'yahooAdvertising', gvlid: GVLID } +]; const ADAPTER_VERSION = '1.1.0'; const PREBID_VERSION = '$prebid.version$'; const DEFAULT_BID_TTL = 300; @@ -45,7 +48,6 @@ const SUPPORTED_USER_ID_SOURCES = [ 'neustar.biz', 'nextroll.com', 'novatiq.com', - 'parrable.com', 'pubcid.org', 'quantcast.com', 'tapad.com', @@ -371,6 +373,7 @@ function appendImpObject(bid, openRtbObject) { pos: deepAccess(bid, 'params.bidOverride.imp.video.pos') || bid.mediaTypes.video.pos || undefined, playbackmethod: deepAccess(bid, 'params.bidOverride.imp.video.playbackmethod') || bid.mediaTypes.video.playbackmethod || undefined, placement: deepAccess(bid, 'params.bidOverride.imp.video.placement') || bid.mediaTypes.video.placement || undefined, + plcmt: deepAccess(bid, 'params.bidOverride.imp.video.plcmt') || bid.mediaTypes.video.plcmt || undefined, linearity: deepAccess(bid, 'params.bidOverride.imp.video.linearity') || bid.mediaTypes.video.linearity || 1, protocols: deepAccess(bid, 'params.bidOverride.imp.video.protocols') || bid.mediaTypes.video.protocols || [2, 5], startdelay: deepAccess(bid, 'params.bidOverride.imp.video.startdelay') || bid.mediaTypes.video.startdelay || 0, diff --git a/modules/yahoosspBidAdapter.md b/modules/yahooAdsBidAdapter.md similarity index 99% rename from modules/yahoosspBidAdapter.md rename to modules/yahooAdsBidAdapter.md index 62fe0f22a55..df9b71b2314 100644 --- a/modules/yahoosspBidAdapter.md +++ b/modules/yahooAdsBidAdapter.md @@ -581,6 +581,7 @@ Currently the bidOverride object only accepts the following: * pos * playbackmethod * placement + * plcmt * linearity * protocols * rewarded @@ -619,6 +620,7 @@ const adUnits = [{ pos: 1, playbackmethod: 0, placement: 1, + plcmt: 1, linearity: 1, protocols: [2,5], startdelay: 0, diff --git a/modules/yandexIdSystem.js b/modules/yandexIdSystem.js new file mode 100644 index 00000000000..24b1f611ccd --- /dev/null +++ b/modules/yandexIdSystem.js @@ -0,0 +1,145 @@ +/** + * The {@link module:modules/userId} module is required + * @module modules/yandexIdSystem + * @requires module:modules/userId + */ + +// @ts-check + +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { logError, logInfo } from '../src/utils.js'; + +// .com suffix is just a convention for naming the bidder eids +// See https://github.com/prebid/Prebid.js/pull/11196#discussion_r1591165139 +const BIDDER_EID_KEY = 'yandex.com'; +const YANDEX_ID_KEY = 'yandexId'; +export const BIDDER_CODE = 'yandex'; +export const YANDEX_USER_ID_KEY = '_ym_uid'; +export const YANDEX_COOKIE_STORAGE_TYPE = 'cookie'; +export const YANDEX_MIN_EXPIRE_DAYS = 30; + +export const PREBID_STORAGE = getStorageManager({ + moduleType: MODULE_TYPE_UID, + moduleName: BIDDER_CODE, + bidderCode: undefined +}); + +export const yandexIdSubmodule = { + /** + * Used to link submodule with config. + * @type {string} + */ + name: BIDDER_CODE, + /** + * Decodes the stored id value for passing to bid requests. + * @param {string} value + */ + decode(value) { + logInfo('decoded value yandexId', value); + + return { [YANDEX_ID_KEY]: value }; + }, + /** + * @param {import('./userId/index.js').SubmoduleConfig} submoduleConfig + * @param {unknown} [_consentData] + * @param {string} [storedId] Id that was saved by the core previously. + */ + getId(submoduleConfig, _consentData, storedId) { + if (checkConfigHasErrorsAndReport(submoduleConfig)) { + return; + } + + if (storedId) { + return { + id: storedId + }; + } + + return { + id: new YandexUidGenerator().generateUid(), + }; + }, + eids: { + [YANDEX_ID_KEY]: { + source: BIDDER_EID_KEY, + atype: 1, + }, + }, +}; + +/** + * @param {import('./userId/index.js').SubmoduleConfig} submoduleConfig + * @returns {boolean} `true` - when there are errors, `false` - otherwise. + */ +function checkConfigHasErrorsAndReport(submoduleConfig) { + let error = false; + + const READABLE_MODULE_NAME = 'Yandex ID module'; + + if (submoduleConfig.storage == null) { + logError(`Misconfigured ${READABLE_MODULE_NAME}. "storage" is required.`) + return true; + } + + if (submoduleConfig.storage?.name !== YANDEX_USER_ID_KEY) { + logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.name" is required to be "${YANDEX_USER_ID_KEY}"`); + error = true; + } + + if (submoduleConfig.storage?.type !== YANDEX_COOKIE_STORAGE_TYPE) { + logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.type" is required to be "${YANDEX_COOKIE_STORAGE_TYPE}"`); + error = true; + } + + if ((submoduleConfig.storage?.expires ?? 0) < YANDEX_MIN_EXPIRE_DAYS) { + logError(`Misconfigured ${READABLE_MODULE_NAME}, "storage.expires" is required to be not less than "${YANDEX_MIN_EXPIRE_DAYS}"`); + error = true; + } + + return error; +} + +/** + * Yandex-specific generator for uid. Needs to be compatible with Yandex Metrica tag. + * @see https://github.com/yandex/metrica-tag/blob/main/src/utils/uid/uid.ts#L51 + */ +class YandexUidGenerator { + /** + * @param {number} min + * @param {number} max + */ + _getRandomInteger(min, max) { + const generateRandom = this._getRandomGenerator(); + + return Math.floor(generateRandom() * (max - min)) + min; + } + + _getCurrentSecTimestamp() { + return Math.round(Date.now() / 1000); + } + + generateUid() { + return [ + this._getCurrentSecTimestamp(), + this._getRandomInteger(1000000, 999999999), + ].join(''); + } + + _getRandomGenerator() { + if (window.crypto) { + return () => { + const buffer = new Uint32Array(1); + crypto.getRandomValues(buffer); + + return buffer[0] / 0xffffffff; + }; + } + + // Polyfill for environments that don't support Crypto API + return () => Math.random(); + } +} + +submodule('userId', yandexIdSubmodule); diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js index 0f0c1b46e54..af01ee73f09 100644 --- a/modules/yieldmoBidAdapter.js +++ b/modules/yieldmoBidAdapter.js @@ -177,7 +177,7 @@ export const spec = { serverRequest.topics = topicsData; } if (eids.length) { - serverRequest.user = { eids }; + deepSetValue(serverRequest, 'user.ext.eids', eids); }; serverRequests.push({ method: 'POST', diff --git a/modules/yuktamediaAnalyticsAdapter.js b/modules/yuktamediaAnalyticsAdapter.js index 25e4dc73b74..19825041589 100644 --- a/modules/yuktamediaAnalyticsAdapter.js +++ b/modules/yuktamediaAnalyticsAdapter.js @@ -1,12 +1,11 @@ import {buildUrl, generateUUID, getWindowLocation, logError, logInfo, parseSizesInput, parseUrl} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import {ajax, fetch} from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS, STATUS } from '../src/constants.js'; import {getStorageManager} from '../src/storageManager.js'; import {getRefererInfo} from '../src/refererDetection.js'; import {includes as strIncludes} from '../src/polyfill.js'; -import {getGlobal} from '../src/prebidGlobal.js'; import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; const MODULE_CODE = 'yuktamedia'; @@ -37,7 +36,7 @@ const _pageInfo = { referer: referer, refererDomain: parseUrl(referer).host, yuktamediaAnalyticsVersion: yuktamediaAnalyticsVersion, - prebidVersion: getGlobal().version + prebidVersion: 'v' + 'prebid.version$' }; function getParameterByName(param) { @@ -51,10 +50,6 @@ function getParameterByName(param) { return vars[param] ? vars[param] : ''; } -function isNavigatorSendBeaconSupported() { - return ('navigator' in window) && ('sendBeacon' in window.navigator); -} - function updateSessionId() { if (isSessionIdTimeoutExpired()) { let newSessionId = generateUUID(); @@ -89,11 +84,14 @@ function send(data, status) { hostname: 'analytics-prebid.yuktamedia.com', pathname: '/api/bids' }); - if (isNavigatorSendBeaconSupported()) { - window.navigator.sendBeacon(yuktamediaAnalyticsRequestUrl, JSON.stringify(data)); - } else { + fetch(yuktamediaAnalyticsRequestUrl, { + body: JSON.stringify(data), + keepalive: true, + withCredentials: true, + method: 'POST' + }).catch((_e) => { ajax(yuktamediaAnalyticsRequestUrl, undefined, JSON.stringify(data), { method: 'POST', contentType: 'text/plain' }); - } + }); } var yuktamediaAnalyticsAdapter = Object.assign(adapter({ analyticsType: 'endpoint' }), { diff --git a/modules/zeta_global_sspAnalyticsAdapter.js b/modules/zeta_global_sspAnalyticsAdapter.js index 31bcffcd7b1..02cfb8739b7 100644 --- a/modules/zeta_global_sspAnalyticsAdapter.js +++ b/modules/zeta_global_sspAnalyticsAdapter.js @@ -41,7 +41,8 @@ function adRenderSucceededHandler(args) { size: args.bid?.size, adomain: args.bid?.adserverTargeting?.hb_adomain, timeToRespond: args.bid?.timeToRespond, - cpm: args.bid?.cpm + cpm: args.bid?.cpm, + adUnitCode: args.bid?.adUnitCode }, device: { ua: navigator.userAgent @@ -63,7 +64,8 @@ function auctionEndHandler(args) { bidder: b?.bidder, mediaType: b?.mediaTypes?.video ? 'VIDEO' : (b?.mediaTypes?.banner ? 'BANNER' : undefined), size: b?.sizes?.filter(s => s && s.length === 2).filter(s => Number.isInteger(s[0]) && Number.isInteger(s[1])).map(s => s[0] + 'x' + s[1]).find(s => s), - device: b?.ortb2?.device + device: b?.ortb2?.device, + adUnitCode: b?.adUnitCode })) })), bidsReceived: args.bidsReceived?.map(br => ({ @@ -75,7 +77,8 @@ function auctionEndHandler(args) { size: br?.size, adomain: br?.adserverTargeting?.hb_adomain, timeToRespond: br?.timeToRespond, - cpm: br?.cpm + cpm: br?.cpm, + adUnitCode: br?.adUnitCode })) } sendEvent(EVENTS.AUCTION_END, event); @@ -93,7 +96,8 @@ function bidTimeoutHandler(args) { mediaType: t?.mediaTypes?.video ? 'VIDEO' : (t?.mediaTypes?.banner ? 'BANNER' : undefined), size: t?.sizes?.filter(s => s && s.length === 2).filter(s => Number.isInteger(s[0]) && Number.isInteger(s[1])).map(s => s[0] + 'x' + s[1]).find(s => s), timeout: t?.timeout, - device: t?.ortb2?.device + device: t?.ortb2?.device, + adUnitCode: t?.adUnitCode })) } sendEvent(EVENTS.BID_TIMEOUT, event); diff --git a/modules/zeta_global_sspBidAdapter.js b/modules/zeta_global_sspBidAdapter.js index 918d03861ae..2ea6d745096 100644 --- a/modules/zeta_global_sspBidAdapter.js +++ b/modules/zeta_global_sspBidAdapter.js @@ -128,8 +128,8 @@ export const spec = { id: bidderRequest.bidderRequestId, cur: [DEFAULT_CUR], imp: imps, - site: params.site ? params.site : {}, - device: {...(bidderRequest.ortb2?.device || {}), ...params.device}, + site: {...bidderRequest?.ortb2?.site, ...params?.site}, + device: {...bidderRequest?.ortb2?.device, ...params?.device}, user: params.user ? params.user : {}, app: params.app ? params.app : {}, ext: { @@ -147,6 +147,18 @@ export const spec = { payload.device.w = screen.width; payload.device.h = screen.height; + if (bidderRequest.ortb2?.user?.geo && bidderRequest.ortb2?.device?.geo) { + payload.device.geo = { ...payload.device.geo, ...bidderRequest.ortb2?.device.geo }; + payload.user.geo = { ...payload.user.geo, ...bidderRequest.ortb2?.user.geo }; + } else { + if (bidderRequest.ortb2?.user?.geo) { + payload.user.geo = payload.device.geo = { ...payload.user.geo, ...bidderRequest.ortb2?.user.geo }; + } + if (bidderRequest.ortb2?.device?.geo) { + payload.user.geo = payload.device.geo = { ...payload.user.geo, ...bidderRequest.ortb2?.device.geo }; + } + } + if (bidderRequest?.ortb2?.device?.sua) { payload.device.sua = bidderRequest.ortb2.device.sua; } diff --git a/package-lock.json b/package-lock.json index 36afa9c25ae..09f7b34ea8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,20 @@ { "name": "prebid.js", - "version": "8.52.0-pre", + "version": "9.6.0-pre", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "prebid.js", - "version": "8.52.0-pre", + "version": "9.6.0-pre", "license": "Apache-2.0", "dependencies": { - "@babel/core": "^7.16.7", + "@babel/core": "^7.24.6", "@babel/plugin-transform-runtime": "^7.18.9", "@babel/preset-env": "^7.16.8", "@babel/runtime": "^7.18.9", "core-js": "^3.13.0", "core-js-pure": "^3.13.0", - "criteo-direct-rsa-validate": "^1.1.0", "crypto-js": "^4.2.0", "dlv": "1.1.3", "dset": "3.1.2", @@ -47,7 +46,7 @@ "eslint": "^7.27.0", "eslint-config-standard": "^10.2.1", "eslint-plugin-import": "^2.20.2", - "eslint-plugin-jsdoc": "^38.1.6", + "eslint-plugin-jsdoc": "^48.5.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prebid": "file:./plugins/eslint", "eslint-plugin-promise": "^5.1.0", @@ -55,7 +54,7 @@ "execa": "^1.0.0", "faker": "^5.5.3", "fs.extra": "^1.3.2", - "gulp": "^4.0.0", + "gulp": "^4.0.2", "gulp-clean": "^0.4.0", "gulp-concat": "^2.6.0", "gulp-connect": "^5.7.0", @@ -94,8 +93,9 @@ "morgan": "^1.10.0", "node-html-parser": "^6.1.5", "opn": "^5.4.0", + "querystring": "^0.2.1", "resolve-from": "^5.0.0", - "sinon": "^4.1.3", + "sinon": "^4.5.0", "through2": "^4.0.2", "url": "^0.11.0", "url-parse": "^1.0.5", @@ -111,64 +111,64 @@ "yargs": "^1.3.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=20.0.0" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "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.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", - "convert-source-map": "^1.7.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -179,102 +179,89 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", - "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.7.tgz", + "integrity": "sha512-SO5E3bVxDuxyNxM5agFv480YA2HO6ohZbGxbazZdIk3KQOPOGVNw6q78I9/lbviIf95eq6tPozeYnJLbjnC8IA==", "dev": true, "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || >=14.0.0" }, "peerDependencies": { - "@babel/core": ">=7.11.0", - "eslint": "^7.5.0 || ^8.0.0" + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, "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.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", - "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -284,12 +271,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", + "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -299,131 +287,123 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.4.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", "dependencies": { - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", + "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-wrap-function": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -433,121 +413,124 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dependencies": { - "@babel/types": "^7.19.4" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "dependencies": { - "@babel/types": "^7.20.0" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", + "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-function-name": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "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.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -555,12 +538,13 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", + "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -569,234 +553,55 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", - "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", - "dependencies": { - "@babel/compat-data": "^7.19.4", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", + "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", + "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "engines": { "node": ">=6.9.0" }, @@ -804,21 +609,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -878,11 +668,11 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -891,6 +681,31 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -996,28 +811,60 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", + "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1027,11 +874,11 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1041,11 +888,11 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.0.tgz", - "integrity": "sha512-sXOohbpHZSk7GjxK9b3dKB7CfqUD5DwOH+DggKzOQ7TXYP+RCSbRykfjQmn/zq+rBjycVRtLf9pYhAaEJA786w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", + "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1054,19 +901,49 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", - "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.19.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", + "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", "globals": "^11.1.0" }, "engines": { @@ -1077,11 +954,12 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1091,11 +969,11 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.0.tgz", - "integrity": "sha512-1dIhvZfkDVx/zn2S1aFwlruspTt4189j7fEkH0Y0VyuDM6bQt7bD6kLcz3l4IlLG+e5OReaBz9ROAbttRtUHqA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", + "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1105,12 +983,12 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1120,11 +998,26 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1134,12 +1027,27 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1149,11 +1057,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1163,13 +1072,28 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", + "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1179,11 +1103,26 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -1193,11 +1132,11 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1207,12 +1146,12 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1222,13 +1161,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1238,14 +1177,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", + "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1255,12 +1194,12 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1270,12 +1209,12 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1285,11 +1224,58 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1299,12 +1285,43 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", + "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1314,11 +1331,43 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.1.tgz", - "integrity": "sha512-nDvKLrAvl+kf6BOy1UJ3MGwzzfTMgppxwiD2Jb4LO3xjYyZq30oQzDNJbCQpMdG9+j2IXHoiMrw5Cm/L6ZoxXQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1328,11 +1377,11 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1342,12 +1391,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1357,11 +1406,11 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1371,16 +1420,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "semver": "^6.3.0" + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1390,11 +1439,11 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1404,12 +1453,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1419,11 +1468,11 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1433,11 +1482,11 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1447,11 +1496,11 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", + "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1461,11 +1510,26 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1475,12 +1539,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1489,38 +1553,43 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/preset-env": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz", - "integrity": "sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==", - "dependencies": { - "@babel/compat-data": "^7.19.4", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.19.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.19.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", + "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1530,45 +1599,61 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.19.4", - "@babel/plugin-transform-classes": "^7.19.0", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.19.4", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.18.6", - "@babel/plugin-transform-modules-commonjs": "^7.18.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.0", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.18.8", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.19.4", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1578,58 +1663,61 @@ } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, "node_modules/@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dependencies": { - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "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.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", - "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", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1637,12 +1725,12 @@ } }, "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.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1658,18 +1746,30 @@ "node": ">=0.1.90" } }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.22.2", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.22.2.tgz", - "integrity": "sha512-pM6WQKcuAtdYoqCsXSvVSu3Ij8K0HY50L8tIheOKHDl0wH1uA4zbP88etY8SIeP16NVCMCTFU+Q2DahSKheGGQ==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "dependencies": { - "comment-parser": "1.3.1", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~2.2.5" + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", + "comment-parser": "1.4.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" }, "engines": { - "node": "^12 || ^14 || ^16 || ^17" + "node": ">=16" } }, "node_modules/@eslint/eslintrc": { @@ -1709,9 +1809,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1883,6 +1983,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", @@ -1897,6 +1998,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@isaacs/cliui": { @@ -1904,6 +2006,7 @@ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -1916,23 +2019,12 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1944,13 +2036,15 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1963,26 +2057,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -2025,6 +2105,7 @@ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" }, @@ -2049,6 +2130,7 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -2066,6 +2148,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -2081,6 +2164,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2097,6 +2181,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2108,13 +2193,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/@jest/types/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2124,6 +2211,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -2132,78 +2220,65 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "engines": { "node": ">=6.0.0" } }, "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==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@ljharb/through": { - "version": "2.3.12", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz", - "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==", + "version": "2.3.13", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", + "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5" + "call-bind": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -2225,46 +2300,34 @@ "dev": true }, "node_modules/@percy/appium-app": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@percy/appium-app/-/appium-app-2.0.3.tgz", - "integrity": "sha512-6INeUJSyK2LzWV4Cc9bszNqKr3/NLcjFelUC2grjPnm6+jLA29inBF4ZE3PeTfLeCSw/0jyCGWV5fr9AyxtzCA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@percy/appium-app/-/appium-app-2.0.6.tgz", + "integrity": "sha512-0NT8xgaq4UOhcqVc4H3D440M7H5Zko8mDpY5j30TRpjOQ3ctLPJalmUVKOCFv4rSzjd2LmyE2F9KXTPA3zqQsw==", "dev": true, "dependencies": { - "@percy/sdk-utils": "^1.27.0-beta.0", + "@percy/sdk-utils": "^1.28.2", "tmp": "^0.2.1" }, "engines": { "node": ">=14" } }, - "node_modules/@percy/appium-app/node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, "node_modules/@percy/sdk-utils": { - "version": "1.27.7", - "resolved": "https://registry.npmjs.org/@percy/sdk-utils/-/sdk-utils-1.27.7.tgz", - "integrity": "sha512-E21dIEQ9wwGDno41FdMDYf6jJow5scbWGClqKE/ptB+950W4UF5C4hxhVVQoEJxDdLE/Gy/8ZJR7upvPHShWDg==", + "version": "1.28.7", + "resolved": "https://registry.npmjs.org/@percy/sdk-utils/-/sdk-utils-1.28.7.tgz", + "integrity": "sha512-LIhfHnkcS0fyIdo3gvKn7rwodZjbEtyLkgiDRSRulcBOatI2mhn2Bh269sXXiiFTyAW2BDQjyE3DWc4hkGbsbQ==", "dev": true, "engines": { "node": ">=14" } }, "node_modules/@percy/selenium-webdriver": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@percy/selenium-webdriver/-/selenium-webdriver-2.0.3.tgz", - "integrity": "sha512-JfLJVRkwNfqVofe7iGKtoQbOcKSSj9t4pWFbSUk95JfwAA7b9/c+dlBsxgIRrdrMYzLRjnJkYAFSZkJ4F4A19A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@percy/selenium-webdriver/-/selenium-webdriver-2.0.5.tgz", + "integrity": "sha512-bNj52xQm02dY872loFa+8OwyuGcdYHYvCKflmSEsF9EDRiSDj0Wr+XP+DDIgDAl9xXschA7OOdXCLTWV4zEQWA==", "dev": true, "dependencies": { - "@percy/sdk-utils": "^1.27.2", + "@percy/sdk-utils": "^1.28.0", "node-request-interceptor": "^0.6.3" }, "engines": { @@ -2276,17 +2339,51 @@ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "version": "1.0.0-next.25", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", + "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "dev": true }, + "node_modules/@promptbook/utils": { + "version": "0.50.0-10", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.50.0-10.tgz", + "integrity": "sha512-Z94YoY/wcZb5m1QoXgmIC1rVeDguGK5bWmUTYdWCqh/LHVifRdJ1C+tBzS0h+HMOD0XzMjZhBQ/mBgTZ/QNW/g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "dependencies": { + "moment": "2.30.1", + "prettier": "2.8.1", + "spacetrim": "0.11.25" + } + }, "node_modules/@puppeteer/browsers": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.9.1.tgz", @@ -2308,26 +2405,21 @@ "node": ">=16.3.0" } }, - "node_modules/@puppeteer/browsers/node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "dependencies": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "node_modules/@puppeteer/browsers/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "node_modules/@puppeteer/browsers/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": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/@puppeteer/browsers/node_modules/yargs": { @@ -2355,21 +2447,21 @@ "dev": true }, "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==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", "dev": true, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" @@ -2402,21 +2494,21 @@ "dev": true }, "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "dev": true }, "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, "dependencies": { - "defer-to-connect": "^2.0.0" + "defer-to-connect": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=14.16" } }, "node_modules/@tootallnate/once": { @@ -2424,6 +2516,7 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "engines": { @@ -2437,21 +2530,21 @@ "dev": true }, "node_modules/@types/aria-query": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", - "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true }, "node_modules/@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, "dependencies": { "@types/http-cache-semantics": "*", - "@types/keyv": "*", + "@types/keyv": "^3.1.4", "@types/node": "*", - "@types/responselike": "*" + "@types/responselike": "^1.0.0" } }, "node_modules/@types/cookie": { @@ -2461,27 +2554,27 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, "dependencies": { "@types/ms": "*" } }, "node_modules/@types/eslint": { - "version": "8.4.9", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.9.tgz", - "integrity": "sha512-jFCSo4wJzlHQLCpceUhUnXdrPuCNOjGFMQ8Eg6JXxlz3QaCKOb7eGi2cephQdM4XTYsNej69P9JDJ1zqNIbncQ==", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, "dependencies": { "@types/estree": "*", @@ -2489,9 +2582,9 @@ } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "dependencies": { "@types/eslint": "*", @@ -2499,9 +2592,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/expect": { @@ -2511,9 +2604,9 @@ "dev": true }, "node_modules/@types/extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.1.tgz", - "integrity": "sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.4.tgz", + "integrity": "sha512-ArMouDUTJEz1SQRpFsT2rIw7DeqICFv5aaVzLSIYMYQSLcwcGOfT3VyglQs/p7K3F7fT4zxr0NWxYZIdifD6dA==", "dev": true }, "node_modules/@types/gitconfiglocal": { @@ -2522,19 +2615,23 @@ "integrity": "sha512-W6hyZux6TrtKfF2I9XNLVcsFr4xRr0T+S6hrJ9nDkhA2vzsFPIEAbnY4vgb6v2yKXQ9MJVcbLsARNlMfg4EVtQ==", "dev": true }, - "node_modules/@types/github-slugger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/github-slugger/-/github-slugger-1.3.0.tgz", - "integrity": "sha512-J/rMZa7RqiH/rT29TEVZO4nBoDP9XJOjnbbIofg7GQKs4JIduEO3WLpte+6WeUz/TcrXKlY+bM7FYrp8yFB+3g==", - "dev": true + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "dependencies": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } }, "node_modules/@types/hast": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", - "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", "dev": true, "dependencies": { - "@types/unist": "*" + "@types/unist": "^2" } }, "node_modules/@types/http-cache-semantics": { @@ -2547,13 +2644,15 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -2563,14 +2662,15 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/json5": { @@ -2580,24 +2680,29 @@ "dev": true }, "node_modules/@types/keyv": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-4.2.0.tgz", - "integrity": "sha512-xoBtGl5R9jeKUhc8ZqeYaRDx04qqJ10yhhXYGmJ4Jr8qKpvMsDQQrNUvF/wUJ4klOtmJeJM+p2Xo3zp9uaC3tw==", - "deprecated": "This is a stub types definition. keyv provides its own type definitions, so you do not need this installed.", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dev": true, "dependencies": { - "keyv": "*" + "@types/node": "*" } }, "node_modules/@types/mdast": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", - "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", "dev": true, "dependencies": { - "@types/unist": "*" + "@types/unist": "^2" } }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, "node_modules/@types/mocha": { "version": "10.0.6", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", @@ -2605,30 +2710,36 @@ "dev": true }, "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", "dev": true }, "node_modules/@types/node": { - "version": "20.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", - "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "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==", + "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/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", "dev": true }, "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, "dependencies": { "@types/node": "*" @@ -2638,12 +2749,13 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.3.tgz", + "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==", "dev": true }, "node_modules/@types/triple-beam": { @@ -2653,21 +2765,21 @@ "dev": true }, "node_modules/@types/ua-parser-js": { - "version": "0.7.36", - "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", - "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==", "dev": true }, "node_modules/@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", "dev": true }, "node_modules/@types/vinyl": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.6.tgz", - "integrity": "sha512-ayJ0iOCDNHnKpKTgBG6Q6JOnHTj9zFta+3j2b8Ejza0e4cvRyMn0ZoLEmbPrTHe5YYRlDYPvPWVdV4cTaRyH7g==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.12.tgz", + "integrity": "sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==", "dev": true, "dependencies": { "@types/expect": "^1.20.4", @@ -2675,9 +2787,9 @@ } }, "node_modules/@types/which": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", - "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", + "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", "dev": true }, "node_modules/@types/ws": { @@ -2685,6 +2797,7 @@ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2694,6 +2807,7 @@ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -2702,30 +2816,44 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "optional": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@typescript-eslint/types": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", + "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@videojs/http-streaming": { - "version": "2.14.3", - "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.14.3.tgz", - "integrity": "sha512-2tFwxCaNbcEZzQugWf8EERwNMyNtspfHnvxRGRABQs09W/5SqmkWFuGWfUAm4wQKlXGfdPyAJ1338ASl459xAA==", + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "3.0.5", "aes-decrypter": "3.1.3", "global": "^4.4.0", - "m3u8-parser": "4.7.1", - "mpd-parser": "0.21.1", + "m3u8-parser": "4.8.0", + "mpd-parser": "^0.22.1", "mux.js": "6.0.1", "video.js": "^6 || ^7" }, @@ -2764,9 +2892,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.1.tgz", - "integrity": "sha512-Tmp/IcYEemKaqAYCS08sh0vORLJkMr0NRV76Gl8sHGxXT5151cITJCET20063wk0Yr/1koQ6dnmP6eEqezmd/Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, "dependencies": { "magic-string": "^0.30.5", @@ -2777,131 +2905,80 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/snapshot/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@vue/compiler-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz", - "integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz", + "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==", "dev": true, "optional": true, "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.41", + "@babel/parser": "^7.24.4", + "@vue/shared": "3.4.27", + "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map": "^0.6.1" - } - }, - "node_modules/@vue/compiler-core/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz", - "integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz", + "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==", "dev": true, "optional": true, "dependencies": { - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-core": "3.4.27", + "@vue/shared": "3.4.27" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz", - "integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz", + "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==", "dev": true, "optional": true, "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-ssr": "3.2.41", - "@vue/reactivity-transform": "3.2.41", - "@vue/shared": "3.2.41", + "@babel/parser": "^7.24.4", + "@vue/compiler-core": "3.4.27", + "@vue/compiler-dom": "3.4.27", + "@vue/compiler-ssr": "3.4.27", + "@vue/shared": "3.4.27", "estree-walker": "^2.0.2", - "magic-string": "^0.25.7", - "postcss": "^8.1.10", - "source-map": "^0.6.1" - } - }, - "node_modules/@vue/compiler-sfc/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" + "magic-string": "^0.30.10", + "postcss": "^8.4.38", + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz", - "integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==", - "dev": true, - "optional": true, - "dependencies": { - "@vue/compiler-dom": "3.2.41", - "@vue/shared": "3.2.41" - } - }, - "node_modules/@vue/reactivity-transform": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz", - "integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz", + "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==", "dev": true, "optional": true, "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7" + "@vue/compiler-dom": "3.4.27", + "@vue/shared": "3.4.27" } }, "node_modules/@vue/shared": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz", - "integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", + "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==", "dev": true, "optional": true }, "node_modules/@wdio/browserstack-service": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/browserstack-service/-/browserstack-service-8.29.1.tgz", - "integrity": "sha512-dLEJcdVF0Cu+2REByVOfLUzx9FvMias1VsxSCZpKXeIAGAIWBBdNdooK6Vdc9QdS36S5v/mk0/rTTQhYn4nWjQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/browserstack-service/-/browserstack-service-8.39.0.tgz", + "integrity": "sha512-EEbmg9hBk0FAf9b2oHEL0w8aIscKPy3ms0/zSaLp+jDMuWHllpVQ83GCW9qHIJbKUzTNUlF031fRdPzq+GQaVg==", "dev": true, + "license": "MIT", "dependencies": { "@percy/appium-app": "^2.0.1", "@percy/selenium-webdriver": "^2.0.3", "@types/gitconfiglocal": "^2.0.1", - "@wdio/logger": "8.28.0", - "@wdio/reporter": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/reporter": "8.39.0", + "@wdio/types": "8.39.0", "browserstack-local": "^1.5.1", "chalk": "^5.3.0", "csv-writer": "^1.6.0", @@ -2910,9 +2987,9 @@ "gitconfiglocal": "^2.1.0", "got": "^12.6.1", "uuid": "^9.0.0", - "webdriverio": "8.29.1", + "webdriverio": "8.39.0", "winston-transport": "^4.5.0", - "yauzl": "^2.10.0" + "yauzl": "^3.0.0" }, "engines": { "node": "^16.13 || >=18" @@ -2921,146 +2998,149 @@ "@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@wdio/browserstack-service/node_modules/@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "node_modules/@wdio/browserstack-service/node_modules/@wdio/reporter": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.39.0.tgz", + "integrity": "sha512-XahXhmaA1okdwg4/ThHFSqy/41KywxhbtszPcTzyXB+9INaqFNHA1b1vvWs0mrD5+tTtKbg4caTcEHVJU4iv0w==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" + "@types/node": "^20.1.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "diff": "^5.0.0", + "object-inspect": "^1.12.0" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/browserstack-service/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "node_modules/@wdio/browserstack-service/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, - "engines": { - "node": ">=14.16" + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" + "engines": { + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/browserstack-service/node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "node_modules/@wdio/browserstack-service/node_modules/@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, + "license": "MIT", "dependencies": { - "defer-to-connect": "^2.0.1" + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" }, "engines": { - "node": ">=14.16" + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/browserstack-service/node_modules/@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@wdio/browserstack-service/node_modules/archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, + "license": "MIT", "dependencies": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/browserstack-service/node_modules/archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, + "license": "MIT", "dependencies": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/browserstack-service/node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@wdio/browserstack-service/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, - "node_modules/@wdio/browserstack-service/node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "node_modules/@wdio/browserstack-service/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, - "engines": { - "node": ">=14.16" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/@wdio/browserstack-service/node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "node_modules/@wdio/browserstack-service/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "dev": true, - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=14.16" + "node": ">=8.0.0" } }, "node_modules/@wdio/browserstack-service/node_modules/chalk": { @@ -3076,10 +3156,11 @@ } }, "node_modules/@wdio/browserstack-service/node_modules/chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -3096,31 +3177,34 @@ } }, "node_modules/@wdio/browserstack-service/node_modules/compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/browserstack-service/node_modules/crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/browserstack-service/node_modules/cross-fetch": { @@ -3128,32 +3212,46 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "node-fetch": "^2.6.11" } }, + "node_modules/@wdio/browserstack-service/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/@wdio/browserstack-service/node_modules/devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" }, @@ -3166,49 +3264,16 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz", "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "peer": true }, - "node_modules/@wdio/browserstack-service/node_modules/devtools/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@wdio/browserstack-service/node_modules/edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/shirshak55" - } - }, "node_modules/@wdio/browserstack-service/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "engines": { @@ -3218,79 +3283,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/browserstack-service/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/@wdio/browserstack-service/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@wdio/browserstack-service/node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@wdio/browserstack-service/node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, "node_modules/@wdio/browserstack-service/node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -3302,28 +3300,46 @@ "node": ">= 6" } }, - "node_modules/@wdio/browserstack-service/node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "node_modules/@wdio/browserstack-service/node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" + "ms": "2.1.2" }, "engines": { - "node": ">=10.19.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@wdio/browserstack-service/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/@wdio/browserstack-service/node_modules/http-proxy-agent/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, + "license": "MIT", "optional": true, - "peer": true, + "peer": true + }, + "node_modules/@wdio/browserstack-service/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, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@wdio/browserstack-service/node_modules/lighthouse-logger": { @@ -3331,6 +3347,7 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.1.tgz", "integrity": "sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -3338,55 +3355,22 @@ "marky": "^1.2.2" } }, - "node_modules/@wdio/browserstack-service/node_modules/lighthouse-logger/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@wdio/browserstack-service/node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wdio/browserstack-service/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, - "node_modules/@wdio/browserstack-service/node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wdio/browserstack-service/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3402,6 +3386,7 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, + "license": "MIT", "optional": true, "peer": true }, @@ -3410,6 +3395,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -3425,32 +3411,12 @@ } } }, - "node_modules/@wdio/browserstack-service/node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@wdio/browserstack-service/node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true, - "engines": { - "node": ">=12.20" - } - }, "node_modules/@wdio/browserstack-service/node_modules/proxy-agent": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -3466,10 +3432,11 @@ } }, "node_modules/@wdio/browserstack-service/node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -3477,11 +3444,30 @@ "node": ">= 14" } }, + "node_modules/@wdio/browserstack-service/node_modules/proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/browserstack-service/node_modules/proxy-agent/node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -3491,10 +3477,11 @@ } }, "node_modules/@wdio/browserstack-service/node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -3503,11 +3490,19 @@ "node": ">= 14" } }, + "node_modules/@wdio/browserstack-service/node_modules/proxy-agent/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, + "license": "MIT" + }, "node_modules/@wdio/browserstack-service/node_modules/puppeteer-core": { "version": "20.3.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.3.0.tgz", "integrity": "sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -3530,33 +3525,84 @@ } } }, - "node_modules/@wdio/browserstack-service/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/@wdio/browserstack-service/node_modules/puppeteer-core/node_modules/@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">= 6" + "node": ">=16.0.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@wdio/browserstack-service/node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "node_modules/@wdio/browserstack-service/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "lowercase-keys": "^3.0.0" + "ms": "2.1.2" }, "engines": { - "node": ">=14.16" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@wdio/browserstack-service/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@wdio/browserstack-service/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@wdio/browserstack-service/node_modules/serialize-error": { @@ -3564,6 +3610,7 @@ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^2.12.2" }, @@ -3574,39 +3621,90 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/browserstack-service/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "node_modules/@wdio/browserstack-service/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "safe-buffer": "~5.2.0" } }, - "node_modules/@wdio/browserstack-service/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==", + "node_modules/@wdio/browserstack-service/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" } }, - "node_modules/@wdio/browserstack-service/node_modules/ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "node_modules/@wdio/browserstack-service/node_modules/tar-fs/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@wdio/browserstack-service/node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wdio/browserstack-service/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, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/browserstack-service/node_modules/ua-parser-js": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, { "type": "paypal", "url": "https://paypal.me/faisalman" @@ -3616,46 +3714,36 @@ "url": "https://github.com/sponsors/faisalman" } ], + "license": "MIT", "optional": true, "peer": true, "engines": { "node": "*" } }, - "node_modules/@wdio/browserstack-service/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@wdio/browserstack-service/node_modules/webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -3664,7 +3752,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "engines": { "node": "^16.13 || >=18" @@ -3683,6 +3771,7 @@ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz", "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", @@ -3712,6 +3801,7 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.16.tgz", "integrity": "sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "mitt": "3.0.0" }, @@ -3724,21 +3814,49 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, + "license": "MIT", "dependencies": { "node-fetch": "^2.6.12" } }, + "node_modules/@wdio/browserstack-service/node_modules/webdriverio/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, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/browserstack-service/node_modules/webdriverio/node_modules/devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", - "dev": true + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@wdio/browserstack-service/node_modules/webdriverio/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, + "license": "MIT" }, "node_modules/@wdio/browserstack-service/node_modules/webdriverio/node_modules/puppeteer-core": { "version": "20.9.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz", "integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "1.4.6", "chromium-bidi": "0.4.16", @@ -3763,13 +3881,15 @@ "version": "0.0.1147663", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@wdio/browserstack-service/node_modules/webdriverio/node_modules/tar-fs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dev": true, + "license": "MIT", "dependencies": { "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", @@ -3781,6 +3901,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -3802,6 +3923,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -3816,33 +3938,35 @@ } }, "node_modules/@wdio/browserstack-service/node_modules/zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, + "license": "MIT", "dependencies": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/cli": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.29.1.tgz", - "integrity": "sha512-WWRTf0g0O+ovTTvS1kEhZ/svX32M7jERuuMF1MaldKCi7rZwHsQqOyJD+fO1UDjuxqS96LHSGsZn0auwUfCTXA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.39.0.tgz", + "integrity": "sha512-kAd+8TYjJWRN6gZaRGiSu6Yj3k4+ULRt2NWAgNtGhnr0/Rwlr3j9bjAIhXGL574VqrH+rSnrevDdeGuLcZa1xg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.1", "@vitest/snapshot": "^1.2.1", - "@wdio/config": "8.29.1", - "@wdio/globals": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/globals": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "async-exit-hook": "^2.0.1", "chalk": "^5.2.0", "chokidar": "^3.5.3", @@ -3855,9 +3979,9 @@ "lodash.flattendeep": "^4.4.0", "lodash.pickby": "^4.6.0", "lodash.union": "^4.6.0", - "read-pkg-up": "^10.0.0", + "read-pkg-up": "10.0.0", "recursive-readdir": "^2.2.3", - "webdriverio": "8.29.1", + "webdriverio": "8.39.0", "yargs": "^17.7.2" }, "bin": { @@ -3867,117 +3991,147 @@ "node": "^16.13 || >=18" } }, - "node_modules/@wdio/cli/node_modules/@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "node_modules/@wdio/cli/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" + "@types/node": "^20.1.0" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/cli/node_modules/@puppeteer/browsers/node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "node_modules/@wdio/cli/node_modules/@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" }, "engines": { - "node": ">=12" + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/cli/node_modules/@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@wdio/cli/node_modules/archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, + "license": "MIT", "dependencies": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/cli/node_modules/archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, + "license": "MIT", "dependencies": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" + } + }, + "node_modules/@wdio/cli/node_modules/archiver-utils/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, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@wdio/cli/node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@wdio/cli/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, + "node_modules/@wdio/cli/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@wdio/cli/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@wdio/cli/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -3991,10 +4145,11 @@ } }, "node_modules/@wdio/cli/node_modules/chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -4011,31 +4166,47 @@ } }, "node_modules/@wdio/cli/node_modules/compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" + } + }, + "node_modules/@wdio/cli/node_modules/compress-commons/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, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@wdio/cli/node_modules/crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/cli/node_modules/cross-fetch": { @@ -4043,32 +4214,46 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "node-fetch": "^2.6.11" } }, + "node_modules/@wdio/cli/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/@wdio/cli/node_modules/devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" }, @@ -4081,49 +4266,16 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz", "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "peer": true }, - "node_modules/@wdio/cli/node_modules/devtools/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@wdio/cli/node_modules/edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/shirshak55" - } - }, "node_modules/@wdio/cli/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "engines": { @@ -4156,22 +4308,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@wdio/cli/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wdio/cli/node_modules/get-stream": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", @@ -4184,63 +4320,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/cli/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@wdio/cli/node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@wdio/cli/node_modules/hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@wdio/cli/node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/@wdio/cli/node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -4252,36 +4337,45 @@ "node": ">= 6" } }, - "node_modules/@wdio/cli/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/@wdio/cli/node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@wdio/cli/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/@wdio/cli/node_modules/http-proxy-agent/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, + "license": "MIT", "optional": true, - "peer": true, - "engines": { - "node": ">=16" - } + "peer": true }, - "node_modules/@wdio/cli/node_modules/json-parse-even-better-errors": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", - "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "node_modules/@wdio/cli/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": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@wdio/cli/node_modules/lighthouse-logger": { @@ -4289,6 +4383,7 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.1.tgz", "integrity": "sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -4296,39 +4391,14 @@ "marky": "^1.2.2" } }, - "node_modules/@wdio/cli/node_modules/lighthouse-logger/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/@wdio/cli/node_modules/lines-and-columns": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", - "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/@wdio/cli/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "node_modules/@wdio/cli/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, + "license": "ISC", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, "node_modules/@wdio/cli/node_modules/mimic-fn": { @@ -4344,10 +4414,11 @@ } }, "node_modules/@wdio/cli/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4363,6 +4434,7 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, + "license": "MIT", "optional": true, "peer": true }, @@ -4371,6 +4443,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -4386,25 +4459,10 @@ } } }, - "node_modules/@wdio/cli/node_modules/normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", - "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/@wdio/cli/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "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" @@ -4431,76 +4489,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/cli/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@wdio/cli/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@wdio/cli/node_modules/parse-json": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", - "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.21.4", - "error-ex": "^1.3.2", - "json-parse-even-better-errors": "^3.0.0", - "lines-and-columns": "^2.0.3", - "type-fest": "^3.8.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@wdio/cli/node_modules/parse-json/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@wdio/cli/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, "node_modules/@wdio/cli/node_modules/path-key": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", @@ -4518,6 +4506,7 @@ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -4533,10 +4522,11 @@ } }, "node_modules/@wdio/cli/node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -4544,11 +4534,30 @@ "node": ">= 14" } }, + "node_modules/@wdio/cli/node_modules/proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/cli/node_modules/proxy-agent/node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -4558,10 +4567,11 @@ } }, "node_modules/@wdio/cli/node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -4570,20 +4580,19 @@ "node": ">= 14" } }, - "node_modules/@wdio/cli/node_modules/proxy-agent/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "node_modules/@wdio/cli/node_modules/proxy-agent/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, - "engines": { - "node": ">=12" - } + "license": "MIT" }, "node_modules/@wdio/cli/node_modules/puppeteer-core": { "version": "20.3.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.3.0.tgz", "integrity": "sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -4606,68 +4615,105 @@ } } }, - "node_modules/@wdio/cli/node_modules/read-pkg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", - "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", + "node_modules/@wdio/cli/node_modules/puppeteer-core/node_modules/@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { - "@types/normalize-package-data": "^2.4.1", - "normalize-package-data": "^6.0.0", - "parse-json": "^7.0.0", - "type-fest": "^4.2.0" - }, - "engines": { - "node": ">=16" + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@wdio/cli/node_modules/read-pkg-up": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz", - "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", + "node_modules/@wdio/cli/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "find-up": "^6.3.0", - "read-pkg": "^8.1.0", - "type-fest": "^4.2.0" + "ms": "2.1.2" }, "engines": { - "node": ">=16" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@wdio/cli/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/@wdio/cli/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@wdio/cli/node_modules/puppeteer-core/node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "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": ">= 6" + "node": ">=12" } }, - "node_modules/@wdio/cli/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==", + "node_modules/@wdio/cli/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@wdio/cli/node_modules/serialize-error": { @@ -4675,6 +4721,7 @@ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^2.12.2" }, @@ -4685,18 +4732,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/cli/node_modules/serialize-error/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/@wdio/cli/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -4709,33 +4744,84 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@wdio/cli/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "node_modules/@wdio/cli/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "safe-buffer": "~5.2.0" + } + }, + "node_modules/@wdio/cli/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/@wdio/cli/node_modules/tar-fs/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@wdio/cli/node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" } }, "node_modules/@wdio/cli/node_modules/type-fest": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.1.tgz", - "integrity": "sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=16" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@wdio/cli/node_modules/ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "funding": [ { @@ -4751,48 +4837,36 @@ "url": "https://github.com/sponsors/faisalman" } ], + "license": "MIT", "optional": true, "peer": true, "engines": { "node": "*" } }, - "node_modules/@wdio/cli/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@wdio/cli/node_modules/webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -4801,7 +4875,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "engines": { "node": "^16.13 || >=18" @@ -4820,6 +4894,7 @@ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz", "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", @@ -4849,6 +4924,7 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.16.tgz", "integrity": "sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "mitt": "3.0.0" }, @@ -4861,21 +4937,49 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, + "license": "MIT", "dependencies": { "node-fetch": "^2.6.12" } }, + "node_modules/@wdio/cli/node_modules/webdriverio/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, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/cli/node_modules/webdriverio/node_modules/devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", - "dev": true + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@wdio/cli/node_modules/webdriverio/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, + "license": "MIT" }, "node_modules/@wdio/cli/node_modules/webdriverio/node_modules/puppeteer-core": { "version": "20.9.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz", "integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "1.4.6", "chromium-bidi": "0.4.16", @@ -4900,13 +5004,15 @@ "version": "0.0.1147663", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@wdio/cli/node_modules/webdriverio/node_modules/tar-fs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dev": true, + "license": "MIT", "dependencies": { "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", @@ -4918,6 +5024,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -4936,6 +5043,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -4970,40 +5078,29 @@ "node": ">=12" } }, - "node_modules/@wdio/cli/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wdio/cli/node_modules/zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, + "license": "MIT", "dependencies": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/concise-reporter": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/concise-reporter/-/concise-reporter-8.29.1.tgz", - "integrity": "sha512-dUhClWeq1naL1Qa1nSMDeH8aCVViOKiEzhBhQjgrMOz1Mh3l6O/woqbK2iKDVZDRhfGghtGcV0vpoEUvt8ZKOA==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/concise-reporter/-/concise-reporter-8.38.2.tgz", + "integrity": "sha512-wE36By4Z9iCtRzihpYrmCehsmNc8t3gHviBsUxV4tmYh/SQr+WX/dysWnojer6KWIJ2rT0rOzyQPmrwhdFKAFg==", "dev": true, "dependencies": { - "@wdio/reporter": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/reporter": "8.38.2", + "@wdio/types": "8.38.2", "chalk": "^5.0.1", "pretty-ms": "^7.0.1" }, @@ -5024,14 +5121,15 @@ } }, "node_modules/@wdio/config": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.29.1.tgz", - "integrity": "sha512-zNUac4lM429HDKAitO+fdlwUH1ACQU8lww+DNVgUyuEb86xgVdTqHeiJr/3kOMJAq9IATeE7mDtYyyn6HPm1JA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.39.0.tgz", + "integrity": "sha512-yNuGPMPibY91s936gnJCHWlStvIyDrwLwGfLC/NCdTin4F7HL4Gp5iJnHWkJFty1/DfFi8jjoIUBNLM8HEez+A==", "dev": true, + "license": "MIT", "dependencies": { - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "decamelize": "^6.0.0", "deepmerge-ts": "^5.0.0", "glob": "^10.2.2", @@ -5041,153 +5139,136 @@ "node": "^16.13 || >=18" } }, - "node_modules/@wdio/config/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@wdio/config/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@wdio/config/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "node_modules/@wdio/config/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, + "license": "MIT", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "@types/node": "^20.1.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/config/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "node_modules/@wdio/config/node_modules/@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^16.13 || >=18" } }, "node_modules/@wdio/globals": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.29.1.tgz", - "integrity": "sha512-F+fPnX75f44/crZDfQ2FYSino/IMIdbnQGLIkaH0VnoljVJIHuxnX4y5Zqr4yRgurL9DsZaH22cLHrPXaHUhPg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.39.0.tgz", + "integrity": "sha512-qZo6JjRCIOtdvba6fdSqj6b91TnWXD6rmamyud93FTqbcspnhBvr8lmgOs5wnslTKeeTTigCjpsT310b4/AyHA==", "dev": true, + "license": "MIT", "engines": { "node": "^16.13 || >=18" }, "optionalDependencies": { - "expect-webdriverio": "^4.9.3", - "webdriverio": "8.29.1" + "expect-webdriverio": "^4.11.2", + "webdriverio": "8.39.0" } }, - "node_modules/@wdio/globals/node_modules/@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "node_modules/@wdio/globals/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, + "license": "MIT", "optional": true, - "peer": true, "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" + "@types/node": "^20.1.0" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/globals/node_modules/@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "node_modules/@wdio/globals/node_modules/@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, + "license": "MIT", "optional": true, - "peer": true + "dependencies": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + }, + "engines": { + "node": "^16.13 || >=18" + } }, "node_modules/@wdio/globals/node_modules/archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/globals/node_modules/archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/globals/node_modules/async": { @@ -5195,6 +5276,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/@wdio/globals/node_modules/brace-expansion": { @@ -5202,16 +5284,55 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "balanced-match": "^1.0.0" } }, + "node_modules/@wdio/globals/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@wdio/globals/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@wdio/globals/node_modules/chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -5228,33 +5349,36 @@ } }, "node_modules/@wdio/globals/node_modules/compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/globals/node_modules/crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/globals/node_modules/cross-fetch": { @@ -5262,32 +5386,46 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "node-fetch": "^2.6.11" } }, + "node_modules/@wdio/globals/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/@wdio/globals/node_modules/devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" }, @@ -5300,49 +5438,16 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz", "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "peer": true }, - "node_modules/@wdio/globals/node_modules/devtools/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@wdio/globals/node_modules/edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/shirshak55" - } - }, "node_modules/@wdio/globals/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "engines": { @@ -5352,44 +5457,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/globals/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "optional": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@wdio/globals/node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "optional": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@wdio/globals/node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -5401,15 +5474,47 @@ "node": ">= 6" } }, - "node_modules/@wdio/globals/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/@wdio/globals/node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "optional": true, "peer": true, + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=16" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@wdio/globals/node_modules/http-proxy-agent/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, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@wdio/globals/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, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@wdio/globals/node_modules/lighthouse-logger": { @@ -5417,6 +5522,7 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.1.tgz", "integrity": "sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -5424,32 +5530,23 @@ "marky": "^1.2.2" } }, - "node_modules/@wdio/globals/node_modules/lighthouse-logger/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, "node_modules/@wdio/globals/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "optional": true, "engines": { "node": ">=12" } }, "node_modules/@wdio/globals/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "optional": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -5466,6 +5563,7 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, + "license": "MIT", "optional": true, "peer": true }, @@ -5474,6 +5572,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "whatwg-url": "^5.0.0" @@ -5495,6 +5594,7 @@ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "agent-base": "^7.0.2", @@ -5511,10 +5611,11 @@ } }, "node_modules/@wdio/globals/node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "debug": "^4.3.4" @@ -5523,11 +5624,31 @@ "node": ">= 14" } }, + "node_modules/@wdio/globals/node_modules/proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/globals/node_modules/proxy-agent/node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "agent-base": "^7.1.0", @@ -5538,10 +5659,11 @@ } }, "node_modules/@wdio/globals/node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "agent-base": "^7.0.2", @@ -5551,11 +5673,20 @@ "node": ">= 14" } }, + "node_modules/@wdio/globals/node_modules/proxy-agent/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, + "license": "MIT", + "optional": true + }, "node_modules/@wdio/globals/node_modules/puppeteer-core": { "version": "20.3.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.3.0.tgz", "integrity": "sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -5578,26 +5709,93 @@ } } }, - "node_modules/@wdio/globals/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/@wdio/globals/node_modules/puppeteer-core/node_modules/@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", "dev": true, + "license": "Apache-2.0", "optional": true, + "peer": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/@wdio/globals/node_modules/serialize-error": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", - "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", - "dev": true, + "node": ">=16.0.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@wdio/globals/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@wdio/globals/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@wdio/globals/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@wdio/globals/node_modules/serialize-error": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", + "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", + "dev": true, + "license": "MIT", "optional": true, "dependencies": { "type-fest": "^2.12.2" @@ -5609,16 +5807,66 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/globals/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "node_modules/@wdio/globals/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "safe-buffer": "~5.2.0" + } + }, + "node_modules/@wdio/globals/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/@wdio/globals/node_modules/tar-fs/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@wdio/globals/node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" } }, "node_modules/@wdio/globals/node_modules/type-fest": { @@ -5626,6 +5874,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "optional": true, "engines": { "node": ">=12.20" @@ -5635,9 +5884,9 @@ } }, "node_modules/@wdio/globals/node_modules/ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "funding": [ { @@ -5653,49 +5902,37 @@ "url": "https://github.com/sponsors/faisalman" } ], + "license": "MIT", "optional": true, "peer": true, "engines": { "node": "*" } }, - "node_modules/@wdio/globals/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@wdio/globals/node_modules/webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -5704,7 +5941,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "engines": { "node": "^16.13 || >=18" @@ -5723,6 +5960,7 @@ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz", "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "debug": "4.3.4", @@ -5753,6 +5991,7 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.16.tgz", "integrity": "sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "mitt": "3.0.0" @@ -5766,16 +6005,45 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "node-fetch": "^2.6.12" } }, + "node_modules/@wdio/globals/node_modules/webdriverio/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, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/globals/node_modules/webdriverio/node_modules/devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@wdio/globals/node_modules/webdriverio/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, + "license": "MIT", "optional": true }, "node_modules/@wdio/globals/node_modules/webdriverio/node_modules/puppeteer-core": { @@ -5783,6 +6051,7 @@ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz", "integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "@puppeteer/browsers": "1.4.6", @@ -5809,6 +6078,7 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==", "dev": true, + "license": "BSD-3-Clause", "optional": true }, "node_modules/@wdio/globals/node_modules/webdriverio/node_modules/tar-fs": { @@ -5816,6 +6086,7 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "mkdirp-classic": "^0.5.2", @@ -5828,6 +6099,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=10.0.0" @@ -5850,6 +6122,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "cliui": "^8.0.1", @@ -5865,31 +6138,33 @@ } }, "node_modules/@wdio/globals/node_modules/zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/local-runner": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.29.1.tgz", - "integrity": "sha512-Z3QAgxe1uQ97C7NS1CdMhgmHaLu/sbb47HTbw1yuuLk+SwsBIQGhNpTSA18QVRSUXq70G3bFvjACwqyap1IEQg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.39.0.tgz", + "integrity": "sha512-TSGJVVWqshH7IO13OKw7G/364q3FczZDEh4h6bYe+GAs91KpZrEhZanyALgjh5F3crWtlffX+GA2HUwpi8X0sA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", - "@wdio/logger": "8.28.0", + "@wdio/logger": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/runner": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/runner": "8.39.0", + "@wdio/types": "8.39.0", "async-exit-hook": "^2.0.1", "split2": "^4.1.0", "stream-buffers": "^3.0.2" @@ -5898,10 +6173,23 @@ "node": "^16.13 || >=18" } }, + "node_modules/@wdio/local-runner/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, "node_modules/@wdio/logger": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.28.0.tgz", - "integrity": "sha512-/s6zNCqwy1hoc+K4SJypis0Ud0dlJ+urOelJFO1x0G0rwDRWyFiUP6ijTaCcFxAm29jYEcEPWijl2xkVIHwOyA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.38.0.tgz", + "integrity": "sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==", "dev": true, "dependencies": { "chalk": "^5.1.2", @@ -5913,18 +6201,6 @@ "node": "^16.13 || >=18" } }, - "node_modules/@wdio/logger/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/@wdio/logger/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -5937,32 +6213,17 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@wdio/logger/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@wdio/mocha-framework": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.29.1.tgz", - "integrity": "sha512-R9dKMNqWgtUvZo33ORjUQV8Z/WLX5h/pg9u/xIvZSGXuNSw1h+5DWF6UiNFscxBFblL9UvBi6V9ila2LHgE4ew==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.38.2.tgz", + "integrity": "sha512-qJmRL5E6/ypjCUACH4hvCAAmTdU4YUrUlp9o/IKvTIAHMnZPE0/HgUFixCeu8Mop+rdzTPVBrbqxpRDdSnraYA==", "dev": true, "dependencies": { "@types/mocha": "^10.0.0", "@types/node": "^20.1.0", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.38.2", + "@wdio/utils": "8.38.2", "mocha": "^10.0.0" }, "engines": { @@ -5970,9 +6231,9 @@ } }, "node_modules/@wdio/protocols": { - "version": "8.24.12", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.24.12.tgz", - "integrity": "sha512-QnVj3FkapmVD3h2zoZk+ZQ8gevSj9D9MiIQIy8eOnY4FAneYZ9R9GvoW+mgNcCZO8S8++S/jZHetR8n+8Q808g==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.38.0.tgz", + "integrity": "sha512-7BPi7aXwUtnXZPeWJRmnCNFjyDvGrXlBmN9D4Pi58nILkyjVRQKEY9/qv/pcdyB0cvmIvw++Kl/1Lg+RxG++UA==", "dev": true }, "node_modules/@wdio/repl": { @@ -5980,6 +6241,7 @@ "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-8.24.12.tgz", "integrity": "sha512-321F3sWafnlw93uRTSjEBVuvWCxTkWNDs7ektQS15drrroL3TMeFOynu4rDrIz0jXD9Vas0HCD2Tq/P0uxFLdw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0" }, @@ -5988,14 +6250,14 @@ } }, "node_modules/@wdio/reporter": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.29.1.tgz", - "integrity": "sha512-LZeYHC+HHJRYiFH9odaotDazZh0zNhu4mTuL/T/e3c/Q3oPSQjLvfQYhB3Ece1QA9PKjP1VPmr+g9CvC0lMixA==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.38.2.tgz", + "integrity": "sha512-R78UdAtAnkaV22NYlCCcbPPhmYweiDURiw64LYhlVIQrKNuXUQcafR2kRlWKy31rZc9thSLs5LzrZDReENUlFQ==", "dev": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.38.2", "diff": "^5.0.0", "object-inspect": "^1.12.0" }, @@ -6004,123 +6266,162 @@ } }, "node_modules/@wdio/runner": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.29.1.tgz", - "integrity": "sha512-MvYFf4RgRmzxjAzy6nxvaDG1ycBRvoz772fT06csjxuaVYm57s8mlB8X+U1UQMx/IzujAb53fSeAmNcyU3FNEA==", - "dev": true, - "dependencies": { - "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/globals": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "deepmerge-ts": "^5.0.0", - "expect-webdriverio": "^4.9.3", - "gaze": "^1.1.2", - "webdriver": "8.29.1", - "webdriverio": "8.29.1" + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.39.0.tgz", + "integrity": "sha512-M1ixrrCtuwxHVzwsOKGMWBZCteafV0ztoS9+evMWGQtj0ZEsmhjAhWR3n2nZftt24vWOs+eNLGe2p+IO9Sm9bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.11.28", + "@wdio/config": "8.39.0", + "@wdio/globals": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "deepmerge-ts": "^5.1.0", + "expect-webdriverio": "^4.12.0", + "gaze": "^1.1.3", + "webdriver": "8.39.0", + "webdriverio": "8.39.0" }, "engines": { "node": "^16.13 || >=18" } }, - "node_modules/@wdio/runner/node_modules/@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "node_modules/@wdio/runner/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" + "@types/node": "^20.1.0" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^16.13 || >=18" } }, - "node_modules/@wdio/runner/node_modules/@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "node_modules/@wdio/runner/node_modules/@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, - "optional": true, - "peer": true + "license": "MIT", + "dependencies": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + }, + "engines": { + "node": "^16.13 || >=18" + } }, "node_modules/@wdio/runner/node_modules/archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, + "license": "MIT", "dependencies": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/runner/node_modules/archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, + "license": "MIT", "dependencies": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/runner/node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@wdio/runner/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, + "node_modules/@wdio/runner/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@wdio/runner/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@wdio/runner/node_modules/chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -6137,31 +6438,34 @@ } }, "node_modules/@wdio/runner/node_modules/compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/runner/node_modules/crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/runner/node_modules/cross-fetch": { @@ -6169,32 +6473,46 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "node-fetch": "^2.6.11" } }, + "node_modules/@wdio/runner/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/@wdio/runner/node_modules/devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" }, @@ -6207,49 +6525,16 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz", "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "peer": true }, - "node_modules/@wdio/runner/node_modules/devtools/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@wdio/runner/node_modules/edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/shirshak55" - } - }, "node_modules/@wdio/runner/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "engines": { @@ -6259,42 +6544,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/runner/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@wdio/runner/node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@wdio/runner/node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -6306,15 +6561,46 @@ "node": ">= 6" } }, - "node_modules/@wdio/runner/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/@wdio/runner/node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "optional": true, "peer": true, + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=16" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@wdio/runner/node_modules/http-proxy-agent/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, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@wdio/runner/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, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@wdio/runner/node_modules/lighthouse-logger": { @@ -6322,6 +6608,7 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.1.tgz", "integrity": "sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -6329,31 +6616,22 @@ "marky": "^1.2.2" } }, - "node_modules/@wdio/runner/node_modules/lighthouse-logger/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, "node_modules/@wdio/runner/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/@wdio/runner/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6369,6 +6647,7 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, + "license": "MIT", "optional": true, "peer": true }, @@ -6377,6 +6656,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -6397,6 +6677,7 @@ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -6412,10 +6693,11 @@ } }, "node_modules/@wdio/runner/node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -6423,11 +6705,30 @@ "node": ">= 14" } }, + "node_modules/@wdio/runner/node_modules/proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/runner/node_modules/proxy-agent/node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -6437,10 +6738,11 @@ } }, "node_modules/@wdio/runner/node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -6449,11 +6751,19 @@ "node": ">= 14" } }, + "node_modules/@wdio/runner/node_modules/proxy-agent/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, + "license": "MIT" + }, "node_modules/@wdio/runner/node_modules/puppeteer-core": { "version": "20.3.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.3.0.tgz", "integrity": "sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -6476,18 +6786,84 @@ } } }, + "node_modules/@wdio/runner/node_modules/puppeteer-core/node_modules/@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@wdio/runner/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@wdio/runner/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/@wdio/runner/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@wdio/runner/node_modules/serialize-error": { @@ -6495,6 +6871,7 @@ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^2.12.2" }, @@ -6505,35 +6882,86 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wdio/runner/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "node_modules/@wdio/runner/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "safe-buffer": "~5.2.0" } }, - "node_modules/@wdio/runner/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==", + "node_modules/@wdio/runner/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" } }, - "node_modules/@wdio/runner/node_modules/ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "node_modules/@wdio/runner/node_modules/tar-fs/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "funding": [ + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@wdio/runner/node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wdio/runner/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, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wdio/runner/node_modules/ua-parser-js": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", + "dev": true, + "funding": [ { "type": "opencollective", "url": "https://opencollective.com/ua-parser-js" @@ -6547,48 +6975,36 @@ "url": "https://github.com/sponsors/faisalman" } ], + "license": "MIT", "optional": true, "peer": true, "engines": { "node": "*" } }, - "node_modules/@wdio/runner/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@wdio/runner/node_modules/webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -6597,7 +7013,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "engines": { "node": "^16.13 || >=18" @@ -6616,6 +7032,7 @@ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz", "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", @@ -6645,6 +7062,7 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.16.tgz", "integrity": "sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "mitt": "3.0.0" }, @@ -6657,21 +7075,49 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, + "license": "MIT", "dependencies": { "node-fetch": "^2.6.12" } }, + "node_modules/@wdio/runner/node_modules/webdriverio/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, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@wdio/runner/node_modules/webdriverio/node_modules/devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", - "dev": true + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@wdio/runner/node_modules/webdriverio/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, + "license": "MIT" }, "node_modules/@wdio/runner/node_modules/webdriverio/node_modules/puppeteer-core": { "version": "20.9.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz", "integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "1.4.6", "chromium-bidi": "0.4.16", @@ -6696,13 +7142,15 @@ "version": "0.0.1147663", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@wdio/runner/node_modules/webdriverio/node_modules/tar-fs": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dev": true, + "license": "MIT", "dependencies": { "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", @@ -6714,6 +7162,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -6735,6 +7184,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -6749,27 +7199,28 @@ } }, "node_modules/@wdio/runner/node_modules/zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, + "license": "MIT", "dependencies": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/@wdio/spec-reporter": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.29.1.tgz", - "integrity": "sha512-tuDHihrTjCxFCbSjT0jMvAarLA1MtatnCnhv0vguu3ZWXELR1uESX2KzBmpJ+chGZz3oCcKszT8HOr6Pg2a1QA==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.38.2.tgz", + "integrity": "sha512-Dntk+lmrp+0I3HRRWkkXED+smshvgsW5cdLKwJhEJ1liI48MdBpdNGf9IHTVckE6nfxcWDyFI4icD9qYv/5bFA==", "dev": true, "dependencies": { - "@wdio/reporter": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/reporter": "8.38.2", + "@wdio/types": "8.38.2", "chalk": "^5.1.2", "easy-table": "^1.2.0", "pretty-ms": "^7.0.0" @@ -6791,9 +7242,9 @@ } }, "node_modules/@wdio/types": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.29.1.tgz", - "integrity": "sha512-rZYzu+sK8zY1PjCEWxNu4ELJPYKDZRn7HFcYNgR122ylHygfldwkb5TioI6Pn311hQH/S+663KEeoq//Jb0f8A==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.38.2.tgz", + "integrity": "sha512-+wj1c1OSLdnN4WO5b44Ih4263dTl/eSwMGSI4/pCgIyXIuYQH38JQ+6WRa+c8vJEskUzboq2cSgEQumVZ39ozQ==", "dev": true, "dependencies": { "@types/node": "^20.1.0" @@ -6803,18 +7254,18 @@ } }, "node_modules/@wdio/utils": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.29.1.tgz", - "integrity": "sha512-Dm91DKL/ZKeZ2QogWT8Twv0p+slEgKyB/5x9/kcCG0Q2nNa+tZedTjOhryzrsPiWc+jTSBmjGE4katRXpJRFJg==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.38.2.tgz", + "integrity": "sha512-y5AnBwsGcu/XuCBGCgKmlvKdwEIFyzLA+Cr+denySxY3jbWDONtPUcGaVdFALwsIa5jcIjcATqGmZcCPGnkd7g==", "dev": true, "dependencies": { "@puppeteer/browsers": "^1.6.0", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.38.2", "decamelize": "^6.0.0", "deepmerge-ts": "^5.1.0", - "edgedriver": "^5.3.5", - "geckodriver": "^4.2.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", "get-port": "^7.0.0", "import-meta-resolve": "^4.0.0", "locate-app": "^2.1.0", @@ -6826,168 +7277,156 @@ "node": "^16.13 || >=18" } }, - "node_modules/@wdio/utils/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, "node_modules/@xmldom/xmldom": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.8.tgz", - "integrity": "sha512-PrJx38EfpitFhwmILRl37jAdBlsww6AZ6rRVK4QS7T7RHLhX7mSs647sTmgr9GIxe3qjXdesmomEgbgaokrVFg==", + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -7005,12 +7444,36 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "node_modules/@zip.js/zip.js": { + "version": "2.7.45", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.45.tgz", + "integrity": "sha512-Mm2EXF33DJQ/3GWWEWeP1UCqzpQ5+fiMvT3QWspsXY05DyqqxWu7a9awSzU4/spHMHVFrTjani1PR0vprgZpow==", + "dev": true, + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=16.5.0" + } + }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -7045,9 +7508,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" @@ -7201,9 +7664,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -7226,16 +7689,16 @@ } }, "node_modules/archiver": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", - "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, "dependencies": { "archiver-utils": "^2.1.0", - "async": "^3.2.3", + "async": "^3.2.4", "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", + "readdir-glob": "^1.1.2", "tar-stream": "^2.2.0", "zip-stream": "^4.1.0" }, @@ -7264,16 +7727,37 @@ "node": ">= 6" } }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/archiver/node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "dev": true }, "node_modules/archiver/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -7284,12 +7768,37 @@ "node": ">= 6" } }, + "node_modules/archiver/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -7299,12 +7808,12 @@ } }, "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "dependencies": { - "deep-equal": "^2.0.5" + "dequal": "^2.0.3" } }, "node_modules/arr-diff": { @@ -7371,6 +7880,22 @@ "node": ">=0.10.0" } }, + "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": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", @@ -7401,15 +7926,16 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -7503,15 +8029,53 @@ "node": ">=0.10.0" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -7521,6 +8085,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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": { + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -7531,15 +8117,16 @@ } }, "node_modules/assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", "dev": true, "dependencies": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" } }, "node_modules/assert-plus": { @@ -7581,9 +8168,9 @@ } }, "node_modules/ast-types/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, "node_modules/astral-regex": { @@ -7617,10 +8204,16 @@ } }, "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] }, "node_modules/async-exit-hook": { "version": "2.0.1", @@ -7662,10 +8255,13 @@ } }, "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==", + "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": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -7683,15 +8279,15 @@ } }, "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", "dev": true }, "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", "dev": true }, "node_modules/babel-code-frame": { @@ -7793,6 +8389,12 @@ "source-map": "^0.5.7" } }, + "node_modules/babel-core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/babel-core/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -7853,9 +8455,9 @@ } }, "node_modules/babel-loader": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", - "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "dev": true, "dependencies": { "find-cache-dir": "^3.3.1", @@ -7897,39 +8499,39 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-register": { @@ -7955,18 +8557,6 @@ "dev": true, "hasInstallScript": true }, - "node_modules/babel-register/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/babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -8111,6 +8701,52 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.3.0.tgz", + "integrity": "sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg==", + "dev": true, + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", + "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "dev": true, + "optional": true, + "dependencies": { + "streamx": "^2.18.0" + } + }, "node_modules/base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", @@ -8189,9 +8825,9 @@ "dev": true }, "node_modules/basic-ftp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.4.tgz", - "integrity": "sha512-8PzkB0arJFV4jJWSGOYR+OEic6aeKMu/osRhBULN6RY0ykby6LKhbmuQ5ublvaas5BOwboah5D87nrHyuh8PPA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -8222,9 +8858,9 @@ } }, "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", "dev": true, "engines": { "node": ">=0.6" @@ -8253,12 +8889,15 @@ } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/binaryextensions": { @@ -8295,9 +8934,9 @@ } }, "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -8309,9 +8948,9 @@ } }, "node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/body": { "version": "5.1.0", @@ -8403,12 +9042,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==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -8421,9 +9060,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "funding": [ { "type": "opencollective", @@ -8432,13 +9071,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" }, "bin": { "browserslist": "cli.js" @@ -8457,9 +9100,9 @@ } }, "node_modules/browserstack-local": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.1.tgz", - "integrity": "sha512-T/wxyWDzvBHbDvl7fZKpFU7mYze6nrUkBhNy+d+8bXBqgQX10HTYvajIGO0wb49oGSLCPM0CMZTV/s7e6LF0sA==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.5.tgz", + "integrity": "sha512-jKne7yosrMcptj3hqxp36TP9k0ZW2sCqhyurX24rUL4G3eT7OLgv+CSQN8iq5dtkv5IK+g+v8fWvsiC/S9KxMg==", "dev": true, "dependencies": { "agent-base": "^6.0.2", @@ -8680,55 +9323,57 @@ } }, "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "dev": true, "engines": { - "node": ">=10.6.0" + "node": ">=14.16" } }, "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", "dev": true, "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" } }, "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "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, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8759,9 +9404,9 @@ "dev": true }, "node_modules/caniuse-lite": { - "version": "1.0.30001429", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz", - "integrity": "sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg==", + "version": "1.0.30001633", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001633.tgz", + "integrity": "sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==", "funding": [ { "type": "opencollective", @@ -8770,6 +9415,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -8790,18 +9439,18 @@ } }, "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -8869,25 +9518,22 @@ "dev": true }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -8900,6 +9546,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -8911,9 +9560,9 @@ "dev": true }, "node_modules/chrome-launcher": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.1.tgz", - "integrity": "sha512-UugC8u59/w2AyX5sHLZUHoxBAiSiunUhZa3zZwMH6zPVis0C3dDKiRWyUGIo14tTbZHGVviWxv3PQWZ7taZ4fg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", "dev": true, "dependencies": { "@types/node": "*", @@ -8941,9 +9590,9 @@ } }, "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, "engines": { "node": ">=6.0" @@ -8954,6 +9603,7 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.9.tgz", "integrity": "sha512-u3DC6XwgLCA9QJ5ak1voPslCmacQdulZNCPsI3qNXxSnEcZS7DFIbww+5RM2bznMEje7cc0oydavRLRvOIZtHw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -8974,6 +9624,7 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } @@ -9014,72 +9665,17 @@ "node": ">=0.10.0" } }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/cli-cursor": { @@ -9107,12 +9703,12 @@ } }, "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, "engines": { - "node": ">= 10" + "node": ">= 12" } }, "node_modules/cliui": { @@ -9129,6 +9725,68 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", @@ -9159,6 +9817,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", @@ -9256,9 +9923,9 @@ } }, "node_modules/comma-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", - "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "dev": true, "funding": { "type": "github", @@ -9272,9 +9939,9 @@ "dev": true }, "node_modules/comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true, "engines": { "node": ">= 12.0.0" @@ -9287,15 +9954,18 @@ "dev": true }, "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, "dependencies": { "buffer-crc32": "^0.2.13", @@ -9308,9 +9978,9 @@ } }, "node_modules/compress-commons/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -9476,9 +10146,9 @@ "dev": true }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { "version": "0.6.0", @@ -9513,9 +10183,9 @@ } }, "node_modules/core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -9523,11 +10193,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", - "integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dependencies": { - "browserslist": "^4.21.4" + "browserslist": "^4.23.0" }, "funding": { "type": "opencollective", @@ -9535,9 +10205,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.0.tgz", - "integrity": "sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", + "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -9594,9 +10264,9 @@ } }, "node_modules/crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, "dependencies": { "crc-32": "^1.2.0", @@ -9607,9 +10277,9 @@ } }, "node_modules/crc32-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -9620,11 +10290,6 @@ "node": ">= 6" } }, - "node_modules/criteo-direct-rsa-validate": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/criteo-direct-rsa-validate/-/criteo-direct-rsa-validate-1.1.0.tgz", - "integrity": "sha512-7gQ3zX+d+hS/vOxzLrZ4aRAceB7qNJ0VzaGNpcWjDCmtOpASB50USJDupTik/H2nHgiSAA3VNZ3SFuONs8LR9Q==" - }, "node_modules/cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", @@ -9634,6 +10299,26 @@ "node-fetch": "2.6.7" } }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -9648,6 +10333,27 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/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/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/crypto-js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", @@ -9726,13 +10432,16 @@ "dev": true }, "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", "dev": true, "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" } }, "node_modules/dashdash": { @@ -9748,12 +10457,63 @@ } }, "node_modules/data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, "engines": { - "node": ">= 14" + "node": ">= 12" + } + }, + "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": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/date-format": { @@ -9781,10 +10541,16 @@ "dev": true, "optional": true }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { "ms": "2.1.2" }, @@ -9818,12 +10584,12 @@ } }, "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", "dev": true, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9879,38 +10645,44 @@ } }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/deep-equal": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz", - "integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "es-get-iterator": "^1.1.1", - "get-intrinsic": "^1.0.1", - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.2", - "is-regex": "^1.1.1", + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", "isarray": "^2.0.5", - "object-is": "^1.1.4", + "object-is": "^1.1.5", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3", - "which-boxed-primitive": "^1.0.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", "which-collection": "^1.0.1", - "which-typed-array": "^1.1.2" + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9923,9 +10695,9 @@ "dev": true }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "engines": { "node": ">=0.10.0" @@ -9992,24 +10764,28 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "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==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -10166,21 +10942,21 @@ } }, "node_modules/devtools": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.25.4.tgz", - "integrity": "sha512-R6/S/dCqxoX4Y6PxIGM9JFAuSRZzUeV5r+CoE/frhmno6mTe7dEEgwkJlfit3LkKRoul8n4DsL2A3QtWOvq5IA==", + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.35.0.tgz", + "integrity": "sha512-7HMZMcJSCK/PaBCWVs4n4ZhtBNdUQj10iPwXvj/JDkqPreEXN/XW9GJAoMuLPFmCEKfxe+LrIbgs8ocGJ6rp/A==", "dev": true, "dependencies": { "@types/node": "^18.0.0", "@types/ua-parser-js": "^0.7.33", - "@wdio/config": "7.25.4", - "@wdio/logger": "7.19.0", - "@wdio/protocols": "7.22.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@wdio/config": "7.33.0", + "@wdio/logger": "7.26.0", + "@wdio/protocols": "7.27.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "chrome-launcher": "^0.15.0", "edge-paths": "^2.1.0", - "puppeteer-core": "^13.1.3", + "puppeteer-core": "13.1.3", "query-selector-shadow-dom": "^1.0.0", "ua-parser-js": "^1.0.1", "uuid": "^9.0.0" @@ -10190,26 +10966,60 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1061995", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1061995.tgz", - "integrity": "sha512-pKZZWTjWa/IF4ENCg6GN8bu/AxSZgdhjSa26uc23wz38Blt2Tnm9icOPcSG3Cht55rMq35in1w3rWVPcZ60ArA==", + "version": "0.0.1260888", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1260888.tgz", + "integrity": "sha512-9rTIZ4ZjWwalCPiaY+kPiALLfOKgAz5CTi/Zb1L+qSZ8PH3zVo1T8JcgXIIqg1iM3pZ6hF+n9xO5r2jZ/SF+jg==", "dev": true }, + "node_modules/devtools/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/devtools/node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/devtools/node_modules/@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "version": "18.19.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", + "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/devtools/node_modules/@types/which": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", + "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", "dev": true }, "node_modules/devtools/node_modules/@wdio/config": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.25.4.tgz", - "integrity": "sha512-vb0emDtD9FbFh/yqW6oNdo2iuhQp8XKj6GX9fyy9v4wZgg3B0HPMVJxhIfcoHz7LMBWlHSo9YdvhFI5EQHRLBA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.33.0.tgz", + "integrity": "sha512-SaCZNKrDtBghf7ujyaxTiU4pBW+1Kms32shSoXpJ/wFop6/MiA7nb19qpUPoJtEDw5/NOKevUKz8nBMBXphiew==", "dev": true, "dependencies": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@types/glob": "^8.1.0", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "deepmerge": "^4.0.0", "glob": "^8.0.3" }, @@ -10218,9 +11028,9 @@ } }, "node_modules/devtools/node_modules/@wdio/logger": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.19.0.tgz", - "integrity": "sha512-xR7SN/kGei1QJD1aagzxs3KMuzNxdT/7LYYx+lt6BII49+fqL/SO+5X0FDCZD0Ds93AuQvvz9eGyzrBI2FFXmQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", + "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, "dependencies": { "chalk": "^4.0.0", @@ -10233,18 +11043,18 @@ } }, "node_modules/devtools/node_modules/@wdio/protocols": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.22.0.tgz", - "integrity": "sha512-8EXRR+Ymdwousm/VGtW3H1hwxZ/1g1H99A1lF0U4GuJ5cFWHCd0IVE5H31Z52i8ZruouW8jueMkGZPSo2IIUSQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", + "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", "dev": true, "engines": { "node": ">=12.0.0" } }, "node_modules/devtools/node_modules/@wdio/types": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.25.4.tgz", - "integrity": "sha512-muvNmq48QZCvocctnbe0URq2FjJjUPIG4iLoeMmyF0AQgdbjaUkMkw3BHYNHVTbSOU9WMsr2z8alhj/I2H6NRQ==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.33.0.tgz", + "integrity": "sha512-tNcuN5Kl+i5CffaeTYV1omzAo4rVjiI1m9raIA8ph6iVteWdCzYv2/ImpGgFiBPb7Mf6VokU3+q9Slh5Jitaww==", "dev": true, "dependencies": { "@types/node": "^18.0.0", @@ -10263,13 +11073,13 @@ } }, "node_modules/devtools/node_modules/@wdio/utils": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.25.4.tgz", - "integrity": "sha512-8iwQDk+foUqSzKZKfhLxjlCKOkfRJPNHaezQoevNgnrTq/t0ek+ldZCATezb9B8jprAuP4mgS9xi22akc6RkzA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.33.0.tgz", + "integrity": "sha512-4kQQ86EvEN6fBY5+u7M08cT6LfJtpk1rHd203xyxmbmV9lpNv/OCl4CsC+SD0jGT0aZZqYSIJ/Pil07pAh5K0g==", "dev": true, "dependencies": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", "p-iteration": "^1.1.8" }, "engines": { @@ -10300,6 +11110,33 @@ "balanced-match": "^1.0.0" } }, + "node_modules/devtools/node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/devtools/node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/devtools/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -10334,10 +11171,59 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/devtools/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/devtools/node_modules/devtools-protocol": { + "version": "0.0.948846", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.948846.tgz", + "integrity": "sha512-5fGyt9xmMqUl2VI7+rnUkKCiAQIpLns8sfQtTENy5L70ktbNw0Z3TFJ1JoFNYdx/jffz4YXU45VF75wKZD7sZQ==", + "dev": true + }, + "node_modules/devtools/node_modules/edge-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", + "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", + "dev": true, + "dependencies": { + "@types/which": "^1.3.2", + "which": "^2.0.2" + } + }, + "node_modules/devtools/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/devtools/node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -10353,6 +11239,31 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/devtools/node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/devtools/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -10362,10 +11273,51 @@ "node": ">=8" } }, + "node_modules/devtools/node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/devtools/node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/devtools/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/devtools/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/devtools/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10374,6 +11326,108 @@ "node": ">=10" } }, + "node_modules/devtools/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/devtools/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/devtools/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/devtools/node_modules/puppeteer-core": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.1.3.tgz", + "integrity": "sha512-96pzvVBzq5lUGt3L/QrIH3mxn3NfZylHeusNhq06xBAHPI0Upc0SC/9u7tXjL0oRnmcExeVRJivr1lj7Ah/yDQ==", + "dev": true, + "dependencies": { + "debug": "4.3.2", + "devtools-protocol": "0.0.948846", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "node-fetch": "2.6.7", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.2.3" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/devtools/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/devtools/node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/devtools/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/devtools/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10386,10 +11440,38 @@ "node": ">=8" } }, + "node_modules/devtools/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/devtools/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/devtools/node_modules/ua-parser-js": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", - "integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "funding": [ { @@ -10399,19 +11481,50 @@ { "type": "paypal", "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" } ], "engines": { "node": "*" } }, - "node_modules/devtools/node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "node_modules/devtools/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, "bin": { - "uuid": "dist/bin/uuid" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/devtools/node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/di": { @@ -10421,9 +11534,9 @@ "dev": true }, "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" @@ -10434,6 +11547,7 @@ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -10468,9 +11582,9 @@ } }, "node_modules/documentation": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/documentation/-/documentation-14.0.1.tgz", - "integrity": "sha512-Y/brACCE3sNnDJPFiWlhXrqGY+NelLYVZShLGse5bT1KdohP4JkPf5T2KNq1YWhIEbDYl/1tebRLC0WYbPQxVw==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/documentation/-/documentation-14.0.3.tgz", + "integrity": "sha512-B7cAviVKN9Rw7Ofd+9grhVuxiHwly6Ieh+d/ceMw8UdBOv/irkuwnDEJP8tq0wgdLJDUVuIkovV+AX9mTrZFxg==", "dev": true, "dependencies": { "@babel/core": "^7.18.10", @@ -10538,9 +11652,9 @@ } }, "node_modules/documentation/node_modules/chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", + "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" @@ -10549,10 +11663,27 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/documentation/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/documentation/node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -10568,6 +11699,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/documentation/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/documentation/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -10580,10 +11723,49 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/documentation/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/documentation/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/documentation/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/documentation/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/documentation/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10592,10 +11774,147 @@ "node": ">=10" } }, + "node_modules/documentation/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/documentation/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/documentation/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/documentation/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/documentation/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/documentation/node_modules/read-pkg": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-7.1.0.tgz", + "integrity": "sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^2.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/documentation/node_modules/read-pkg-up": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-9.1.0.tgz", + "integrity": "sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==", + "dev": true, + "dependencies": { + "find-up": "^6.3.0", + "read-pkg": "^7.1.0", + "type-fest": "^2.5.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/documentation/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/documentation/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/documentation/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/documentation/node_modules/yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "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", @@ -10604,7 +11923,7 @@ "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" @@ -10684,15 +12003,15 @@ } }, "node_modules/dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dset": { @@ -10743,21 +12062,21 @@ "dev": true }, "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "dev": true, "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "stream-shift": "^1.0.2" } }, "node_modules/duplexify/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -10818,71 +12137,13 @@ "safer-buffer": "^2.1.0" } }, - "node_modules/edge-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", - "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", - "dev": true, - "dependencies": { - "@types/which": "^1.3.2", - "which": "^2.0.2" - } - }, - "node_modules/edgedriver": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.3.9.tgz", - "integrity": "sha512-G0wNgFMFRDnFfKaXG2R6HiyVHqhKwdQ3EgoxW3wPlns2wKqem7F+HgkWBcevN7Vz0nN4AXtskID7/6jsYDXcKw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@wdio/logger": "^8.16.17", - "decamelize": "^6.0.0", - "edge-paths": "^3.0.5", - "node-fetch": "^3.3.2", - "unzipper": "^0.10.14", - "which": "^4.0.0" - }, - "bin": { - "edgedriver": "bin/edgedriver.js" - } - }, - "node_modules/edgedriver/node_modules/@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "node_modules/ecc-jsbn/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, - "node_modules/edgedriver/node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/edgedriver/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/edgedriver/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/edgedriver/node_modules/edge-paths": { + "node_modules/edge-paths": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", @@ -10898,7 +12159,13 @@ "url": "https://github.com/sponsors/shirshak55" } }, - "node_modules/edgedriver/node_modules/edge-paths/node_modules/which": { + "node_modules/edge-paths/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/edge-paths/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", @@ -10913,64 +12180,22 @@ "node": ">= 8" } }, - "node_modules/edgedriver/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/edgedriver/node_modules/unzipper": { - "version": "0.10.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", - "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, - "node_modules/edgedriver/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "node_modules/edgedriver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.6.0.tgz", + "integrity": "sha512-IeJXEczG+DNYBIa9gFgVYTqrawlxmc9SUqUsWU2E98jOsO/amA7wzabKOS8Bwgr/3xWoyXCJ6yGFrbFKrilyyQ==", "dev": true, + "hasInstallScript": true, "dependencies": { - "isexe": "^3.1.1" + "@wdio/logger": "^8.28.0", + "@zip.js/zip.js": "^2.7.44", + "decamelize": "^6.0.0", + "edge-paths": "^3.0.5", + "node-fetch": "^3.3.2", + "which": "^4.0.0" }, "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/edgedriver/node_modules/which/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" + "edgedriver": "bin/edgedriver.js" } }, "node_modules/ee-first": { @@ -10994,9 +12219,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + "version": "1.4.802", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz", + "integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -11031,10 +12256,11 @@ } }, "node_modules/engine.io": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", - "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", "dev": true, + "license": "MIT", "dependencies": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -11044,17 +12270,17 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.11.0" + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/engine.io-parser": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", - "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -11070,9 +12296,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -11083,17 +12309,30 @@ } }, "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -11143,35 +12382,57 @@ } }, "node_modules/es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", + "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-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "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", - "internal-slot": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "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.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "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" @@ -11180,38 +12441,84 @@ "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==", + "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==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-get-iterator": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", - "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.0", - "has-symbols": "^1.0.1", - "is-arguments": "^1.1.0", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", "is-map": "^2.0.2", "is-set": "^2.0.2", - "is-string": "^1.0.5", - "isarray": "^2.0.5" + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", + "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", "dev": true }, - "node_modules/es-shim-unscopables": { + "node_modules/es-object-atoms": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "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.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -11232,14 +12539,15 @@ } }, "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "dev": true, "hasInstallScript": true, "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" }, "engines": { @@ -11266,12 +12574,6 @@ "es6-symbol": "^3.1.1" } }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, "node_modules/es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -11287,13 +12589,16 @@ } }, "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", "dev": true, "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" } }, "node_modules/es6-weak-map": { @@ -11309,9 +12614,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "engines": { "node": ">=6" } @@ -11495,13 +12800,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "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", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -11514,9 +12820,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -11559,24 +12865,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -11586,12 +12896,12 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { @@ -11606,32 +12916,28 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/eslint-plugin-jsdoc": { - "version": "38.1.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-38.1.6.tgz", - "integrity": "sha512-n4s95oYlg0L43Bs8C0dkzIldxYf8pLCutC/tCbjIdF7VDiobuzPI+HZn9Q0BvgOvgPNgh5n7CSStql25HUG4Tw==", + "version": "48.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.5.0.tgz", + "integrity": "sha512-ukXPNpGby3KjCveCizIS8t1EbuJEHYEu/tBg8GCbn/YbHcXwphyvYCdvRZ/oMRfTscGSSzfsWoZ+ZkAP0/6YMQ==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.22.1", - "comment-parser": "1.3.1", + "@es-joy/jsdoccomment": "~0.43.1", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", - "regextras": "^0.8.0", - "semver": "^7.3.5", - "spdx-expression-parse": "^3.0.1" + "esquery": "^1.5.0", + "parse-imports": "^2.1.0", + "semver": "^7.6.2", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.0" }, "engines": { - "node": "^12 || ^14 || ^16 || ^17" + "node": ">=18" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { @@ -11647,13 +12953,10 @@ } }, "node_modules/eslint-plugin-jsdoc/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==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -11661,6 +12964,16 @@ "node": ">=10" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -11682,9 +12995,9 @@ } }, "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -11832,9 +13145,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -11856,13 +13169,10 @@ } }, "node_modules/eslint/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==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -11870,6 +13180,18 @@ "node": ">=10" } }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/eslint/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -11906,6 +13228,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -11943,9 +13280,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "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" @@ -12047,6 +13384,16 @@ "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", "dev": true }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -12096,6 +13443,12 @@ "node": ">=4.8" } }, + "node_modules/execa/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/execa/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -12198,72 +13551,17 @@ "node": ">=0.10.0" } }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/expand-brackets/node_modules/is-extendable": { @@ -12298,6 +13596,7 @@ "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", @@ -12310,12 +13609,13 @@ } }, "node_modules/expect-webdriverio": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-4.9.3.tgz", - "integrity": "sha512-ASHsFc/QaK5ipF4ct3e8hd3elm8wNXk/Qa3EemtYDmfUQ4uzwqDf75m/QFQpwVNCjEpkNP7Be/6X9kz7bN0P9Q==", + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-4.15.1.tgz", + "integrity": "sha512-xtBSidt7Whs1fsUC+utxVzfmkmaStXWW17b+BcMCiCltx0Yku6l7BTv1Y14DEKX8L6rttaDQobYyRtBKbi4ssg==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/snapshot": "^1.2.1", + "@vitest/snapshot": "^1.2.2", "expect": "^29.7.0", "jest-matcher-utils": "^29.7.0", "lodash.isequal": "^4.5.0" @@ -12324,87 +13624,89 @@ "node": ">=16 || >=18 || >=20" }, "optionalDependencies": { - "@wdio/globals": "^8.27.0", - "@wdio/logger": "^8.24.12", - "webdriverio": "^8.27.0" + "@wdio/globals": "^8.29.3", + "@wdio/logger": "^8.28.0", + "webdriverio": "^8.29.3" } }, - "node_modules/expect-webdriverio/node_modules/@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "node_modules/expect-webdriverio/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, + "license": "MIT", "optional": true, - "peer": true, "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" + "@types/node": "^20.1.0" }, "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^16.13 || >=18" } }, - "node_modules/expect-webdriverio/node_modules/@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "node_modules/expect-webdriverio/node_modules/@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, + "license": "MIT", "optional": true, - "peer": true + "dependencies": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + }, + "engines": { + "node": "^16.13 || >=18" + } }, "node_modules/expect-webdriverio/node_modules/archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/expect-webdriverio/node_modules/archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/expect-webdriverio/node_modules/async": { @@ -12412,6 +13714,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/expect-webdriverio/node_modules/brace-expansion": { @@ -12419,16 +13722,55 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "balanced-match": "^1.0.0" } }, + "node_modules/expect-webdriverio/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/expect-webdriverio/node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/expect-webdriverio/node_modules/chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -12445,33 +13787,36 @@ } }, "node_modules/expect-webdriverio/node_modules/compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/expect-webdriverio/node_modules/crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/expect-webdriverio/node_modules/cross-fetch": { @@ -12479,32 +13824,46 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.6.tgz", "integrity": "sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "node-fetch": "^2.6.11" } }, + "node_modules/expect-webdriverio/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/expect-webdriverio/node_modules/devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" }, @@ -12517,49 +13876,16 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz", "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==", "dev": true, + "license": "BSD-3-Clause", "optional": true, "peer": true }, - "node_modules/expect-webdriverio/node_modules/devtools/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/expect-webdriverio/node_modules/edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/shirshak55" - } - }, "node_modules/expect-webdriverio/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "engines": { @@ -12569,44 +13895,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/expect-webdriverio/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "optional": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/expect-webdriverio/node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "optional": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/expect-webdriverio/node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -12618,15 +13912,47 @@ "node": ">= 6" } }, - "node_modules/expect-webdriverio/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/expect-webdriverio/node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "optional": true, "peer": true, + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=16" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/expect-webdriverio/node_modules/http-proxy-agent/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, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/expect-webdriverio/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, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/expect-webdriverio/node_modules/lighthouse-logger": { @@ -12634,6 +13960,7 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.1.tgz", "integrity": "sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -12641,32 +13968,23 @@ "marky": "^1.2.2" } }, - "node_modules/expect-webdriverio/node_modules/lighthouse-logger/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "ms": "2.0.0" - } - }, "node_modules/expect-webdriverio/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "optional": true, "engines": { "node": ">=12" } }, "node_modules/expect-webdriverio/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "optional": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -12683,6 +14001,7 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true, + "license": "MIT", "optional": true, "peer": true }, @@ -12691,6 +14010,7 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "whatwg-url": "^5.0.0" @@ -12712,6 +14032,7 @@ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "agent-base": "^7.0.2", @@ -12728,10 +14049,11 @@ } }, "node_modules/expect-webdriverio/node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "debug": "^4.3.4" @@ -12740,11 +14062,31 @@ "node": ">= 14" } }, + "node_modules/expect-webdriverio/node_modules/proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/expect-webdriverio/node_modules/proxy-agent/node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "agent-base": "^7.1.0", @@ -12755,10 +14097,11 @@ } }, "node_modules/expect-webdriverio/node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "agent-base": "^7.0.2", @@ -12768,11 +14111,20 @@ "node": ">= 14" } }, + "node_modules/expect-webdriverio/node_modules/proxy-agent/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, + "license": "MIT", + "optional": true + }, "node_modules/expect-webdriverio/node_modules/puppeteer-core": { "version": "20.3.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.3.0.tgz", "integrity": "sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -12795,19 +14147,85 @@ } } }, + "node_modules/expect-webdriverio/node_modules/puppeteer-core/node_modules/@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/expect-webdriverio/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/expect-webdriverio/node_modules/puppeteer-core/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, + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/expect-webdriverio/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/expect-webdriverio/node_modules/serialize-error": { @@ -12815,6 +14233,7 @@ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "type-fest": "^2.12.2" @@ -12826,16 +14245,66 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/expect-webdriverio/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "node_modules/expect-webdriverio/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "safe-buffer": "~5.2.0" + } + }, + "node_modules/expect-webdriverio/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/expect-webdriverio/node_modules/tar-fs/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/expect-webdriverio/node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" } }, "node_modules/expect-webdriverio/node_modules/type-fest": { @@ -12843,6 +14312,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "optional": true, "engines": { "node": ">=12.20" @@ -12852,9 +14322,9 @@ } }, "node_modules/expect-webdriverio/node_modules/ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "funding": [ { @@ -12870,49 +14340,37 @@ "url": "https://github.com/sponsors/faisalman" } ], + "license": "MIT", "optional": true, "peer": true, "engines": { "node": "*" } }, - "node_modules/expect-webdriverio/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "optional": true, - "peer": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/expect-webdriverio/node_modules/webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -12921,7 +14379,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "engines": { "node": "^16.13 || >=18" @@ -12940,6 +14398,7 @@ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz", "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "debug": "4.3.4", @@ -12970,6 +14429,7 @@ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.16.tgz", "integrity": "sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "mitt": "3.0.0" @@ -12983,16 +14443,45 @@ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "node-fetch": "^2.6.12" } }, + "node_modules/expect-webdriverio/node_modules/webdriverio/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, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/expect-webdriverio/node_modules/webdriverio/node_modules/devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/expect-webdriverio/node_modules/webdriverio/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, + "license": "MIT", "optional": true }, "node_modules/expect-webdriverio/node_modules/webdriverio/node_modules/puppeteer-core": { @@ -13000,6 +14489,7 @@ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz", "integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==", "dev": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "@puppeteer/browsers": "1.4.6", @@ -13026,6 +14516,7 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==", "dev": true, + "license": "BSD-3-Clause", "optional": true }, "node_modules/expect-webdriverio/node_modules/webdriverio/node_modules/tar-fs": { @@ -13033,6 +14524,7 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "mkdirp-classic": "^0.5.2", @@ -13045,6 +14537,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=10.0.0" @@ -13067,6 +14560,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "cliui": "^8.0.1", @@ -13082,18 +14576,19 @@ } }, "node_modules/expect-webdriverio/node_modules/zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14" } }, "node_modules/express": { @@ -13159,12 +14654,6 @@ "type": "^2.7.2" } }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -13206,6 +14695,18 @@ "node": ">=4" } }, + "node_modules/external-editor/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -13293,6 +14794,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/extract-zip/node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -13398,24 +14909,37 @@ } }, "node_modules/fetch-blob/node_modules/web-streams-polyfill": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", - "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", "dev": true, "dependencies": { - "escape-string-regexp": "^1.0.5" + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" }, "engines": { - "node": ">=8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/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": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -13471,9 +14995,9 @@ } }, "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==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -13557,182 +15081,6 @@ "node": ">= 0.10" } }, - "node_modules/findup-sync/node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/braces/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/fill-range/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/findup-sync/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/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/findup-sync/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fined": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", @@ -13780,12 +15128,13 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -13793,9 +15142,9 @@ } }, "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==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/flush-write-stream": { @@ -13865,10 +15214,11 @@ "dev": true }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -13885,6 +15235,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -13996,17 +15347,32 @@ "dev": true }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz", + "integrity": "sha512-5rU898vl/Z948L+kkJedbmo/iltzmiF5bn/eEk0j/SgrPpI+Ydau9xlJPicV7Av2CHYBGz5LAlwTnBU80j1zPQ==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" + "jsonfile": "~1.0.1", + "mkdirp": "0.3.x", + "ncp": "~0.4.2", + "rimraf": "~2.2.0" + } + }, + "node_modules/fs-extra/node_modules/mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha512-8OCq0De/h9ZxseqzCH8Kw/Filf5pF/vMI6+BH7Lu0jXz2pqYCjTAQRolSxRIi+Ax+oCCjlxoJMP0YQ4XlrQNHg==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true + }, + "node_modules/fs-extra/node_modules/rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha512-R5KMKHnPAQaZMqLOsyuyUmcIjSeDm+73eoqQpaXA7AZ22BL+6C+1mcUscgOsNd8WVlJuvlgAPsegcx7pjlV0Dg==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "bin": { + "rimraf": "bin.js" } }, "node_modules/fs-mkdirp-stream": { @@ -14054,24 +15420,6 @@ "node": "*" } }, - "node_modules/fs.extra/node_modules/fs-extra": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz", - "integrity": "sha512-5rU898vl/Z948L+kkJedbmo/iltzmiF5bn/eEk0j/SgrPpI+Ydau9xlJPicV7Av2CHYBGz5LAlwTnBU80j1zPQ==", - "dev": true, - "dependencies": { - "jsonfile": "~1.0.1", - "mkdirp": "0.3.x", - "ncp": "~0.4.2", - "rimraf": "~2.2.0" - } - }, - "node_modules/fs.extra/node_modules/jsonfile": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz", - "integrity": "sha512-KbsDJNRfRPF5v49tMNf9sqyyGqGLBcz1v5kZT01kG5ns5mQSltwxCKVmUzVKtEinkUnTDtSrp6ngWpV7Xw0ZlA==", - "dev": true - }, "node_modules/fs.extra/node_modules/mkdirp": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", @@ -14079,15 +15427,6 @@ "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "dev": true }, - "node_modules/fs.extra/node_modules/rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha512-R5KMKHnPAQaZMqLOsyuyUmcIjSeDm+73eoqQpaXA7AZ22BL+6C+1mcUscgOsNd8WVlJuvlgAPsegcx7pjlV0Dg==", - "dev": true, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -14095,9 +15434,9 @@ "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==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, "os": [ @@ -14111,6 +15450,7 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "deprecated": "This package is no longer supported.", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -14122,22 +15462,32 @@ "node": ">=0.6" } }, - "node_modules/fstream/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==", + "node_modules/fstream/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { - "minimist": "^1.2.6" + "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" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/fstream/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -14163,15 +15513,15 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "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.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -14200,6 +15550,7 @@ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, + "license": "MIT", "dependencies": { "globule": "^1.0.0" }, @@ -14208,19 +15559,19 @@ } }, "node_modules/geckodriver": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.3.1.tgz", - "integrity": "sha512-ol7JLsj55o5k+z7YzeSy2mdJROXMAxIa+uzr3A1yEMr5HISqQOTslE3ZeARcxR4jpAY3fxmHM+sq32qbe/eXfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.1.tgz", + "integrity": "sha512-nnAdIrwLkMcDu4BitWXF23pEMeZZ0Cj7HaWWFdSpeedBP9z6ft150JYiGO2mwzw6UiR823Znk1JeIf07RyzloA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@wdio/logger": "^8.24.12", + "@wdio/logger": "^8.28.0", + "@zip.js/zip.js": "^2.7.44", "decamelize": "^6.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", "node-fetch": "^3.3.2", - "tar-fs": "^3.0.4", - "unzipper": "^0.10.14", + "tar-fs": "^3.0.6", "which": "^4.0.0" }, "bin": { @@ -14231,9 +15582,9 @@ } }, "node_modules/geckodriver/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "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": { "debug": "^4.3.4" @@ -14242,40 +15593,10 @@ "node": ">= 14" } }, - "node_modules/geckodriver/node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/geckodriver/node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/geckodriver/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/geckodriver/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "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", @@ -14285,86 +15606,18 @@ "node": ">= 14" } }, - "node_modules/geckodriver/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/geckodriver/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, "node_modules/geckodriver/node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, "dependencies": { - "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^3.1.5" - } - }, - "node_modules/geckodriver/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/geckodriver/node_modules/unzipper": { - "version": "0.10.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", - "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, - "node_modules/geckodriver/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" } }, "node_modules/gensync": { @@ -14385,24 +15638,28 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "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" } @@ -14417,9 +15674,9 @@ } }, "node_modules/get-port": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.0.0.tgz", - "integrity": "sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", "dev": true, "engines": { "node": ">=16" @@ -14441,13 +15698,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==", + "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.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -14457,52 +15715,55 @@ } }, "node_modules/get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, "dependencies": { "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", + "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4", - "fs-extra": "^8.1.0" + "fs-extra": "^11.2.0" }, "engines": { "node": ">= 14" } }, + "node_modules/get-uri/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/get-uri/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "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": "^4.0.0", - "universalify": "^0.1.0" + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=14.14" } }, "node_modules/get-uri/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "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/get-uri/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -14541,9 +15802,9 @@ } }, "node_modules/git-url-parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.1.tgz", + "integrity": "sha512-PCFJyeSSdtnbfhSNRw9Wk96dDCNx+sogTe4YNXeXSJxt7xz5hvXekuRn9JX7m+Mf4OscCu8h+mtAl3+h5Fo8lQ==", "dev": true, "dependencies": { "git-up": "^7.0.0" @@ -14571,20 +15832,24 @@ "dev": true }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, + "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -14623,6 +15888,27 @@ "node": ">= 0.10" } }, + "node_modules/glob-stream/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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-stream/node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -14691,15 +15977,6 @@ "node": ">=0.10.0" } }, - "node_modules/glob-watcher/node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/glob-watcher/node_modules/binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -14784,7 +16061,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", "dev": true, "hasInstallScript": true, "optional": true, @@ -14860,18 +16137,6 @@ "node": ">=0.10.0" } }, - "node_modules/glob-watcher/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/glob-watcher/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -14884,64 +16149,6 @@ "node": ">=0.10.0" } }, - "node_modules/glob-watcher/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-watcher/node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-watcher/node_modules/micromatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-watcher/node_modules/micromatch/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/glob-watcher/node_modules/readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", @@ -14969,6 +16176,32 @@ "node": ">=0.10.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/global": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", @@ -15015,6 +16248,12 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "node_modules/global-prefix/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/global-prefix/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -15041,11 +16280,28 @@ "integrity": "sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==", "dev": true }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globule": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==", "dev": true, + "license": "MIT", "dependencies": { "glob": "~7.1.1", "lodash": "^4.17.21", @@ -15059,7 +16315,9 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15080,6 +16338,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -15111,34 +16370,46 @@ } }, "node_modules/got": { - "version": "11.8.5", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", - "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", "dev": true, "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" }, "engines": { - "node": ">=10.19.0" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sindresorhus/got?sponsor=1" } }, + "node_modules/got/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/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/grapheme-splitter": { "version": "1.0.4", @@ -15151,6 +16422,7 @@ "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", "dev": true, + "license": "MIT", "dependencies": { "glob-watcher": "^5.0.3", "gulp-cli": "^2.2.0", @@ -15180,10 +16452,32 @@ "node": ">=0.9" } }, + "node_modules/gulp-clean/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/gulp-clean/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -15644,15 +16938,6 @@ "node": ">=0.10.0" } }, - "node_modules/gulp-eslint/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/gulp-eslint/node_modules/arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -15680,6 +16965,15 @@ "node": ">=4" } }, + "node_modules/gulp-eslint/node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/gulp-eslint/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -15804,18 +17098,6 @@ "node": ">=4" } }, - "node_modules/gulp-eslint/node_modules/eslint/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/gulp-eslint/node_modules/espree": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", @@ -15843,6 +17125,21 @@ "node": ">=0.10.0" } }, + "node_modules/gulp-eslint/node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gulp-eslint/node_modules/file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -15875,6 +17172,27 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "node_modules/gulp-eslint/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/gulp-eslint/node_modules/globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -15954,6 +17272,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/gulp-eslint/node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/gulp-eslint/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -15963,6 +17293,12 @@ "node": ">=4" } }, + "node_modules/gulp-eslint/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/gulp-eslint/node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -15976,17 +17312,11 @@ "node": ">= 0.8.0" } }, - "node_modules/gulp-eslint/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/gulp-eslint/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true }, "node_modules/gulp-eslint/node_modules/optionator": { "version": "0.8.3", @@ -16051,6 +17381,7 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -16059,6 +17390,27 @@ "rimraf": "bin.js" } }, + "node_modules/gulp-eslint/node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/gulp-eslint/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, "node_modules/gulp-eslint/node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -16094,6 +17446,27 @@ "node": ">=6" } }, + "node_modules/gulp-eslint/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gulp-eslint/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/gulp-eslint/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -16147,18 +17520,6 @@ "node": ">=6" } }, - "node_modules/gulp-eslint/node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/gulp-eslint/node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -16275,12 +17636,12 @@ } }, "node_modules/gulp-replace": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.1.3.tgz", - "integrity": "sha512-HcPHpWY4XdF8zxYkDODHnG2+7a3nD/Y8Mfu3aBgMiCFDW3X2GiOKXllsAmILcxe3KZT2BXoN18WrpEFm48KfLQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.1.4.tgz", + "integrity": "sha512-SVSF7ikuWKhpAW4l4wapAqPPSToJoiNKsbDoUnRrSgwZHH7lH8pbPeQj1aOVYQrbZKhfSVBxVW+Py7vtulRktw==", "dev": true, "dependencies": { - "@types/node": "^14.14.41", + "@types/node": "*", "@types/vinyl": "^2.0.4", "istextorbinary": "^3.0.0", "replacestream": "^4.0.3", @@ -16290,12 +17651,6 @@ "node": ">=10" } }, - "node_modules/gulp-replace/node_modules/@types/node": { - "version": "14.18.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.33.tgz", - "integrity": "sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==", - "dev": true - }, "node_modules/gulp-shell": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.8.0.tgz", @@ -16482,6 +17837,12 @@ "node": ">=0.4.0" } }, + "node_modules/gulp-sourcemaps/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/gulp-sourcemaps/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -16845,13 +18206,13 @@ } }, "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "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.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, @@ -16898,12 +18259,9 @@ } }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "engines": { "node": ">= 0.4.0" } @@ -16959,20 +18317,20 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.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==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "engines": { "node": ">= 0.4" }, @@ -16992,12 +18350,12 @@ } }, "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==", + "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.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -17076,9 +18434,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, @@ -17086,14 +18444,55 @@ "node": ">= 0.4" } }, - "node_modules/hast-util-is-element": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.2.tgz", - "integrity": "sha512-thjnlGAnwP8ef/GSO1Q8BfVk2gundnc2peGQqEg2kUt/IqesiGg/5mSwN2fE7nLzy61pg88NG6xV+UrGOrx9EA==", + "node_modules/hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", "dev": true, "dependencies": { "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0" + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" }, "funding": { "type": "opencollective", @@ -17101,9 +18500,9 @@ } }, "node_modules/hast-util-sanitize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-4.0.0.tgz", - "integrity": "sha512-pw56+69jq+QSr/coADNvWTmBPDy+XsmwaF5KnUys4/wM1jt/fZdl7GPxhXXXYdXnz3Gj3qMkbUCH2uKjvX0MgQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-4.1.0.tgz", + "integrity": "sha512-Hd9tU0ltknMGRDv+d6Ro/4XKzBqQnP/EZrpiTbpFYfXv/uOhWeKc+2uajcbEvAEH98VZd7eII2PiXm13RihnLw==", "dev": true, "dependencies": { "@types/hast": "^2.0.0" @@ -17114,21 +18513,40 @@ } }, "node_modules/hast-util-to-html": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.3.tgz", - "integrity": "sha512-/D/E5ymdPYhHpPkuTHOUkSatxr4w1ZKrZsG0Zv/3C2SRVT0JFJG53VS45AMrBtYk0wp5A7ksEhiC8QaOZM95+A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", + "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", "dev": true, "dependencies": { "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", - "hast-util-is-element": "^2.0.0", + "hast-util-raw": "^7.0.0", "hast-util-whitespace": "^2.0.0", "html-void-elements": "^2.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.2", - "unist-util-is": "^5.0.0" + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" }, "funding": { "type": "opencollective", @@ -17136,10 +18554,27 @@ } }, "node_modules/hast-util-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz", - "integrity": "sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", "dev": true, + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -17161,9 +18596,9 @@ "dev": true }, "node_modules/highlight.js": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.6.0.tgz", - "integrity": "sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw==", + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", + "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", "dev": true, "engines": { "node": ">=12.0.0" @@ -17195,15 +18630,24 @@ } }, "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==", + "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": "^6.0.0" + "lru-cache": "^10.0.1" }, "engines": { - "node": ">=10" + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/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/html-escaper": { @@ -17264,9 +18708,9 @@ } }, "node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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", @@ -17277,9 +18721,9 @@ } }, "node_modules/http-proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "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": { "debug": "^4.3.4" @@ -17304,13 +18748,13 @@ } }, "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "dev": true, "dependencies": { "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" + "resolve-alpn": "^1.2.0" }, "engines": { "node": ">=10.19.0" @@ -17378,6 +18822,13 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -17404,9 +18855,9 @@ } }, "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "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", @@ -17432,6 +18883,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -17478,21 +18930,6 @@ "node": ">=14.18.0" } }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/inquirer/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -17505,128 +18942,26 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/inquirer/node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/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/inquirer/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": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inquirer/node_modules/figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inquirer/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inquirer/node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/inquirer/node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/inquirer/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/inquirer/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "node_modules/inquirer/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "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": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -17660,10 +18995,23 @@ "node": ">=0.10.0" } }, - "node_modules/ip": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", - "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true }, "node_modules/ipaddr.js": { @@ -17696,24 +19044,15 @@ } }, "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", "dev": true, "dependencies": { - "kind-of": "^6.0.0" + "hasown": "^2.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/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": ">= 0.10" } }, "node_modules/is-arguments": { @@ -17732,6 +19071,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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", @@ -17814,35 +19169,41 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", "dev": true, "dependencies": { - "kind-of": "^6.0.0" + "hasown": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/is-data-descriptor/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/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.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-date-object": { @@ -17861,26 +19222,16 @@ } }, "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/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": ">= 0.4" } }, "node_modules/is-docker": { @@ -17993,10 +19344,13 @@ } }, "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -18027,9 +19381,9 @@ } }, "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==", + "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" @@ -18124,21 +19478,27 @@ "dev": true }, "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "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==", + "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.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -18193,16 +19553,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "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": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -18230,12 +19586,12 @@ } }, "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -18257,10 +19613,13 @@ } }, "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -18278,13 +19637,16 @@ } }, "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -18330,10 +19692,13 @@ } }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } }, "node_modules/isobject": { "version": "3.0.1", @@ -18376,9 +19741,9 @@ } }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "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" @@ -18401,17 +19766,17 @@ } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "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": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-report/node_modules/has-flag": { @@ -18423,6 +19788,33 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-report/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/istanbul-lib-report/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/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -18459,9 +19851,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "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", @@ -18475,6 +19867,7 @@ "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "inflight": "^1.0.4", @@ -18496,17 +19889,11 @@ "node": ">=0.10.0" } }, - "node_modules/istanbul/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/istanbul/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/istanbul/node_modules/resolve": { "version": "1.1.7", @@ -18555,10 +19942,11 @@ } }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -18573,9 +19961,9 @@ } }, "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dev": true, "dependencies": { "async": "^3.2.3", @@ -18671,6 +20059,7 @@ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -18686,6 +20075,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -18701,6 +20091,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -18717,6 +20108,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -18728,13 +20120,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -18744,6 +20138,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -18756,6 +20151,7 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -18765,6 +20161,7 @@ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", @@ -18780,6 +20177,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -18795,6 +20193,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -18811,6 +20210,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -18822,13 +20222,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -18838,6 +20240,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -18850,6 +20253,7 @@ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -18870,6 +20274,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -18885,6 +20290,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -18901,6 +20307,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -18912,22 +20319,39 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/jest-message-util/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/jest-message-util/node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/jest-message-util/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -18937,6 +20361,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -18949,6 +20374,7 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -18966,6 +20392,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -18981,6 +20408,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -18997,6 +20425,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -19008,13 +20437,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/jest-util/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -19024,6 +20455,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -19099,15 +20531,15 @@ } }, "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "dev": true }, "node_modules/jsdoc-type-pratt-parser": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.5.tgz", - "integrity": "sha512-2a6eRxSxp1BW040hFvaJxhsCMI9lT8QB8t14t+NY5tC5rckIR0U9cr2tjOeaFirmEOy6MHvmJnY7zTBHq431Lw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, "engines": { "node": ">=12.0.0" @@ -19131,10 +20563,13 @@ "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 + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/json-schema": { "version": "0.4.0", @@ -19161,9 +20596,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, @@ -19172,16 +20607,10 @@ } }, "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" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz", + "integrity": "sha512-KbsDJNRfRPF5v49tMNf9sqyyGqGLBcz1v5kZT01kG5ns5mQSltwxCKVmUzVKtEinkUnTDtSrp6ngWpV7Xw0ZlA==", + "dev": true }, "node_modules/jsprim": { "version": "1.4.2", @@ -19198,6 +20627,19 @@ "node": ">=0.6.0" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "node_modules/just-debounce": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", @@ -19211,9 +20653,9 @@ "dev": true }, "node_modules/karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.3.tgz", + "integrity": "sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==", "dev": true, "dependencies": { "@colors/colors": "1.5.0", @@ -19235,7 +20677,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^4.4.1", + "socket.io": "^4.7.2", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.30", @@ -19285,14 +20727,20 @@ } }, "node_modules/karma-chrome-launcher": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", - "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, "dependencies": { "which": "^1.2.1" } }, + "node_modules/karma-chrome-launcher/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/karma-chrome-launcher/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -19306,9 +20754,9 @@ } }, "node_modules/karma-coverage": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.0.tgz", - "integrity": "sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.2.0", @@ -19338,6 +20786,27 @@ "url": "https://github.com/sponsors/mattlewis92" } }, + "node_modules/karma-coverage-istanbul-reporter/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/karma-coverage-istanbul-reporter/node_modules/istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", @@ -19389,6 +20858,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -19425,13 +20895,34 @@ } }, "node_modules/karma-firefox-launcher": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz", - "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", + "integrity": "sha512-LMM2bseebLbYjODBOVt7TCPP9OI2vZIXCavIXhkO9m+10Uj5l7u/SKoeRmYx8FYHTVGZSpk6peX+3BMHC1WwNw==", "dev": true, "dependencies": { "is-wsl": "^2.2.0", - "which": "^2.0.1" + "which": "^3.0.0" + } + }, + "node_modules/karma-firefox-launcher/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/karma-firefox-launcher/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/karma-ie-launcher": { @@ -19552,22 +21043,94 @@ } }, "node_modules/karma-webpack": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0.tgz", - "integrity": "sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.1.tgz", + "integrity": "sha512-oo38O+P3W2mSPCSUrQdySSPv1LvPpXP+f+bBimNomS5sW+1V4SuhCuW8TfJzV+rDv921w2fDSDw0xJbPe6U+kQ==", "dev": true, "dependencies": { "glob": "^7.1.3", - "minimatch": "^3.0.4", + "minimatch": "^9.0.3", "webpack-merge": "^4.1.5" }, "engines": { - "node": ">= 6" + "node": ">= 18" }, "peerDependencies": { "webpack": "^5.0.0" } }, + "node_modules/karma-webpack/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/karma-webpack/node_modules/glob/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/karma-webpack/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/karma-webpack/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -19579,16 +21142,43 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/karma/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==", + "node_modules/karma/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "minimist": "^1.2.6" + "color-name": "~1.1.4" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/karma/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/karma/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/karma/node_modules/source-map": { @@ -19600,16 +21190,33 @@ "node": ">=0.10.0" } }, - "node_modules/karma/node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "node_modules/karma/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "rimraf": "^3.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8.17.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/karma/node_modules/yargs": { @@ -19695,6 +21302,7 @@ "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -19773,6 +21381,16 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -19805,9 +21423,9 @@ } }, "node_modules/lighthouse-logger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz", - "integrity": "sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, "dependencies": { "debug": "^2.6.9", @@ -19830,10 +21448,13 @@ "dev": true }, "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } }, "node_modules/listenercount": { "version": "1.0.1", @@ -19940,12 +21561,22 @@ } }, "node_modules/locate-app": { - "version": "2.2.13", - "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.2.13.tgz", - "integrity": "sha512-1jp6iRFrHKBj9vq6Idb0cSjly+KnCIMbxZ2BBKSEzIC4ZJosv47wnLoiJu2EgOAdjhGvNcy/P2fbDCS/WziI8g==", + "version": "2.4.15", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.4.15.tgz", + "integrity": "sha512-oAGHATXPUHSQ74Om+3dXBRNYtCzU7Wzuhlj/WIZchqHb/5/TGJRzLEtHipMDOak0UZG9U365RMXyBzgV/fhOww==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/locate-app/blob/main/README.md#%EF%B8%8F-contributing" + } + ], "dependencies": { - "n12": "1.8.16", + "@promptbook/utils": "0.50.0-10", "type-fest": "2.13.0", "userhome": "1.0.0" } @@ -20105,7 +21736,8 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isobject": { "version": "3.0.2", @@ -20213,16 +21845,16 @@ } }, "node_modules/log4js": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", - "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", "dev": true, "dependencies": { "date-format": "^4.0.14", "debug": "^4.3.4", "flatted": "^3.2.7", "rfdc": "^1.3.0", - "streamroller": "^3.1.3" + "streamroller": "^3.1.5" }, "engines": { "node": ">=8.0" @@ -20255,9 +21887,9 @@ } }, "node_modules/loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", "dev": true, "engines": { "node": ">= 0.6.0" @@ -20280,9 +21912,9 @@ "dev": true }, "node_modules/longest-streak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.1.tgz", - "integrity": "sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "dev": true, "funding": { "type": "github", @@ -20302,33 +21934,32 @@ } }, "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "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, + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/lru-queue": { @@ -20341,9 +21972,9 @@ } }, "node_modules/m3u8-parser": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.7.1.tgz", - "integrity": "sha512-pbrQwiMiq+MmI9bl7UjtPT3AK603PV9bogNlr83uC+X9IoxqL5E4k7kU7fMQ0dpRgxgeSMygqUa0IMLQNXLBNA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.8.0.tgz", + "integrity": "sha512-UqA2a/Pw3liR6Df3gwxrqghCP17OpPlQj6RBPLYygf/ZSQ4MoSgvdvhvt35qV+3NaaA0FSZx93Ix+2brT1U7cA==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", @@ -20352,13 +21983,12 @@ } }, "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, - "optional": true, "dependencies": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.15" } }, "node_modules/make-dir": { @@ -20425,9 +22055,9 @@ } }, "node_modules/markdown-table": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz", - "integrity": "sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", "dev": true, "funding": { "type": "github", @@ -20455,106 +22085,6 @@ "node": ">= 0.10.0" } }, - "node_modules/matchdep/node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/braces/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/fill-range/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/matchdep/node_modules/findup-sync": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", @@ -20570,12 +22100,6 @@ "node": ">= 0.10" } }, - "node_modules/matchdep/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "node_modules/matchdep/node_modules/is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", @@ -20588,80 +22112,10 @@ "node": ">=0.10.0" } }, - "node_modules/matchdep/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/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/matchdep/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mdast-util-definitions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz", - "integrity": "sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", + "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -20674,11 +22128,12 @@ } }, "node_modules/mdast-util-find-and-replace": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.1.tgz", - "integrity": "sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", + "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", "dev": true, "dependencies": { + "@types/mdast": "^3.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.0.0" @@ -20701,9 +22156,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz", - "integrity": "sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -20725,19 +22180,22 @@ } }, "node_modules/mdast-util-from-markdown/node_modules/mdast-util-to-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", - "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/mdast-util-gfm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.1.tgz", - "integrity": "sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", + "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", "dev": true, "dependencies": { "mdast-util-from-markdown": "^1.0.0", @@ -20754,9 +22212,9 @@ } }, "node_modules/mdast-util-gfm-autolink-literal": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.2.tgz", - "integrity": "sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", + "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -20770,9 +22228,9 @@ } }, "node_modules/mdast-util-gfm-footnote": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.1.tgz", - "integrity": "sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", + "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -20785,9 +22243,9 @@ } }, "node_modules/mdast-util-gfm-strikethrough": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.1.tgz", - "integrity": "sha512-zKJbEPe+JP6EUv0mZ0tQUyLQOC+FADt0bARldONot/nefuISkaZFlmVK4tU6JgfyZGrky02m/I6PmehgAgZgqg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", + "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -20799,9 +22257,9 @@ } }, "node_modules/mdast-util-gfm-table": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.6.tgz", - "integrity": "sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", + "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -20815,9 +22273,9 @@ } }, "node_modules/mdast-util-gfm-task-list-item": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.1.tgz", - "integrity": "sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", + "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -20837,10 +22295,24 @@ "mdast-util-to-string": "^1.0.0" } }, + "node_modules/mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-to-hast": { - "version": "12.2.4", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.4.tgz", - "integrity": "sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", + "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", "dev": true, "dependencies": { "@types/hast": "^2.0.0", @@ -20848,7 +22320,6 @@ "mdast-util-definitions": "^5.0.0", "micromark-util-sanitize-uri": "^1.1.0", "trim-lines": "^3.0.0", - "unist-builder": "^3.0.0", "unist-util-generated": "^2.0.0", "unist-util-position": "^4.0.0", "unist-util-visit": "^4.0.0" @@ -20859,14 +22330,15 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz", - "integrity": "sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", "mdast-util-to-string": "^3.0.0", "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", @@ -20878,10 +22350,13 @@ } }, "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", - "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -20898,58 +22373,37 @@ } }, "node_modules/mdast-util-toc": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-6.1.0.tgz", - "integrity": "sha512-0PuqZELXZl4ms1sF7Lqigrqik4Ll3UhbI+jdTrfw7pZ9QPawgl7LD4GQ8MkU7bT/EwiVqChNTbifa2jLLKo76A==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-6.1.1.tgz", + "integrity": "sha512-Er21728Kow8hehecK2GZtb7Ny3omcoPUVrmObiSUwmoRYVZaXLR751QROEFjR8W/vAQdHMLj49Lz20J55XaNpw==", "dev": true, "dependencies": { "@types/extend": "^3.0.0", - "@types/github-slugger": "^1.0.0", "@types/mdast": "^3.0.0", "extend": "^3.0.0", - "github-slugger": "^1.0.0", + "github-slugger": "^2.0.0", "mdast-util-to-string": "^3.1.0", "unist-util-is": "^5.0.0", - "unist-util-visit": "^3.0.0" + "unist-util-visit": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-toc/node_modules/mdast-util-to-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", - "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-toc/node_modules/unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/mdast-util-toc/node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "dev": true }, - "node_modules/mdast-util-toc/node_modules/unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", + "node_modules/mdast-util-toc/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" + "@types/mdast": "^3.0.0" }, "funding": { "type": "opencollective", @@ -20965,19 +22419,22 @@ } }, "node_modules/memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", "dev": true, "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", + "d": "^1.0.2", + "es5-ext": "^0.10.64", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" } }, "node_modules/memory-fs": { @@ -21013,9 +22470,9 @@ } }, "node_modules/micromark": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", - "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", "dev": true, "funding": [ { @@ -21048,9 +22505,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz", - "integrity": "sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", "dev": true, "funding": [ { @@ -21082,9 +22539,9 @@ } }, "node_modules/micromark-extension-gfm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.1.tgz", - "integrity": "sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", + "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", "dev": true, "dependencies": { "micromark-extension-gfm-autolink-literal": "^1.0.0", @@ -21102,16 +22559,15 @@ } }, "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.3.tgz", - "integrity": "sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", + "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", "dev": true, "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-sanitize-uri": "^1.0.0", "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "micromark-util-types": "^1.0.0" }, "funding": { "type": "opencollective", @@ -21119,9 +22575,9 @@ } }, "node_modules/micromark-extension-gfm-footnote": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.4.tgz", - "integrity": "sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", + "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", "dev": true, "dependencies": { "micromark-core-commonmark": "^1.0.0", @@ -21139,9 +22595,9 @@ } }, "node_modules/micromark-extension-gfm-strikethrough": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.4.tgz", - "integrity": "sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", + "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", "dev": true, "dependencies": { "micromark-util-chunked": "^1.0.0", @@ -21157,9 +22613,9 @@ } }, "node_modules/micromark-extension-gfm-table": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.5.tgz", - "integrity": "sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", + "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", "dev": true, "dependencies": { "micromark-factory-space": "^1.0.0", @@ -21174,9 +22630,9 @@ } }, "node_modules/micromark-extension-gfm-tagfilter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.1.tgz", - "integrity": "sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", + "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", "dev": true, "dependencies": { "micromark-util-types": "^1.0.0" @@ -21187,9 +22643,9 @@ } }, "node_modules/micromark-extension-gfm-task-list-item": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.3.tgz", - "integrity": "sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", + "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", "dev": true, "dependencies": { "micromark-factory-space": "^1.0.0", @@ -21204,9 +22660,9 @@ } }, "node_modules/micromark-factory-destination": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz", - "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", "dev": true, "funding": [ { @@ -21225,9 +22681,9 @@ } }, "node_modules/micromark-factory-label": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz", - "integrity": "sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", "dev": true, "funding": [ { @@ -21247,9 +22703,9 @@ } }, "node_modules/micromark-factory-space": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz", - "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", "dev": true, "funding": [ { @@ -21267,9 +22723,9 @@ } }, "node_modules/micromark-factory-title": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz", - "integrity": "sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", "dev": true, "funding": [ { @@ -21285,14 +22741,13 @@ "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "micromark-util-types": "^1.0.0" } }, "node_modules/micromark-factory-whitespace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz", - "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", "dev": true, "funding": [ { @@ -21312,9 +22767,9 @@ } }, "node_modules/micromark-util-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz", - "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", "dev": true, "funding": [ { @@ -21332,9 +22787,9 @@ } }, "node_modules/micromark-util-chunked": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz", - "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", "dev": true, "funding": [ { @@ -21351,9 +22806,9 @@ } }, "node_modules/micromark-util-classify-character": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz", - "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", "dev": true, "funding": [ { @@ -21372,9 +22827,9 @@ } }, "node_modules/micromark-util-combine-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz", - "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", "dev": true, "funding": [ { @@ -21392,9 +22847,9 @@ } }, "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz", - "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", "dev": true, "funding": [ { @@ -21411,9 +22866,9 @@ } }, "node_modules/micromark-util-decode-string": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz", - "integrity": "sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", "dev": true, "funding": [ { @@ -21433,9 +22888,9 @@ } }, "node_modules/micromark-util-encode": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz", - "integrity": "sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", "dev": true, "funding": [ { @@ -21449,9 +22904,9 @@ ] }, "node_modules/micromark-util-html-tag-name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz", - "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", "dev": true, "funding": [ { @@ -21465,9 +22920,9 @@ ] }, "node_modules/micromark-util-normalize-identifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", - "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", "dev": true, "funding": [ { @@ -21484,9 +22939,9 @@ } }, "node_modules/micromark-util-resolve-all": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz", - "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", "dev": true, "funding": [ { @@ -21503,9 +22958,9 @@ } }, "node_modules/micromark-util-sanitize-uri": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", - "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", "dev": true, "funding": [ { @@ -21524,9 +22979,9 @@ } }, "node_modules/micromark-util-subtokenize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz", - "integrity": "sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", "dev": true, "funding": [ { @@ -21546,9 +23001,9 @@ } }, "node_modules/micromark-util-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz", - "integrity": "sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", "dev": true, "funding": [ { @@ -21562,9 +23017,9 @@ ] }, "node_modules/micromark-util-types": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.2.tgz", - "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "dev": true, "funding": [ { @@ -21578,16 +23033,193 @@ ] }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" }, "engines": { - "node": ">=8.6" + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/mime": { @@ -21631,12 +23263,15 @@ } }, "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "dev": true, "engines": { - "node": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/min-document": { @@ -21661,19 +23296,20 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -21682,7 +23318,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -21697,6 +23334,18 @@ "node": ">=0.10.0" } }, + "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/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -21704,9 +23353,9 @@ "dev": true }, "node_modules/mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -21716,13 +23365,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -21737,10 +23385,6 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/ansi-colors": { @@ -21773,6 +23417,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/mocha/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -21801,6 +23454,33 @@ "node": ">=8" } }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -21830,6 +23510,29 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/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/mocha/node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -21868,37 +23571,25 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/glob/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/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -21908,6 +23599,18 @@ "node": ">=8" } }, + "node_modules/mocha/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mocha/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -21963,15 +23666,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -22008,6 +23702,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/mocha/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -22035,6 +23741,23 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/mocha/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/mocha/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -22062,6 +23785,27 @@ "node": ">=10" } }, + "node_modules/mocha/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -22106,14 +23850,14 @@ } }, "node_modules/mpd-parser": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.21.1.tgz", - "integrity": "sha512-BxlSXWbKE1n7eyEPBnTEkrzhS3PdmkkKdM1pgKbPnPOH0WFZIc0sPOWi7m0Uo3Wd2a4Or8Qf4ZbS7+ASqQ49fw==", + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "^3.0.5", - "@xmldom/xmldom": "^0.7.2", + "@xmldom/xmldom": "^0.8.3", "global": "^4.4.0" }, "bin": { @@ -22130,9 +23874,9 @@ } }, "node_modules/mrmime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, "engines": { "node": ">=10" @@ -22162,10 +23906,13 @@ } }, "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/mux.js": { "version": "6.0.1", @@ -22184,24 +23931,25 @@ "npm": ">=5" } }, - "node_modules/n12": { - "version": "1.8.16", - "resolved": "https://registry.npmjs.org/n12/-/n12-1.8.16.tgz", - "integrity": "sha512-CZqHAqbzS0UsaUGkMsL+lMaYLyFr1+/ea+pD8dMziqSjkcuWVWDtgWx9phyfT7C3llqQ2+LwnStSb5afggBMfA==", - "dev": true - }, "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", "dev": true, "optional": true }, "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "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" + } + ], + "optional": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -22379,29 +24127,27 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, "dependencies": { - "whatwg-url": "^5.0.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "node_modules/node-html-parser": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.6.tgz", - "integrity": "sha512-C/MGDQ2NjdjzUq41bW9kW00MPZecAe/oo89vZEFLDfWoQVDk/DdML1yuxVVKLDMFIFax2VTq6Vpfzyn7z5yYgQ==", + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.13.tgz", + "integrity": "sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==", "dev": true, "dependencies": { "css-select": "^5.1.0", @@ -22409,9 +24155,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/node-request-interceptor": { "version": "0.6.3", @@ -22450,28 +24196,25 @@ } }, "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==", + "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": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.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": ">=10" + "node": "^16.14.0 || >=18.0.0" } }, "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==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -22489,12 +24232,12 @@ } }, "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "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": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -22598,57 +24341,23 @@ "node": ">=0.10.0" } }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-copy/node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/object-copy/node_modules/kind-of": { @@ -22664,21 +24373,21 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -22709,13 +24418,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" }, @@ -22741,6 +24450,38 @@ "node": ">=0.10.0" } }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", @@ -22780,14 +24521,14 @@ } }, "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -22871,9 +24612,9 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { "deep-is": "^0.1.3", @@ -22881,7 +24622,7 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -22968,6 +24709,18 @@ "node": ">=8" } }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ora/node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -22984,6 +24737,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ora/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -23036,12 +24801,12 @@ } }, "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12.20" } }, "node_modules/p-finally": { @@ -23118,9 +24883,9 @@ } }, "node_modules/pac-proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "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": { "debug": "^4.3.4" @@ -23130,9 +24895,9 @@ } }, "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "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", @@ -23143,19 +24908,32 @@ } }, "node_modules/pac-resolver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", - "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, "dependencies": { "degenerator": "^5.0.0", - "ip": "^1.1.8", "netmask": "^2.0.2" }, "engines": { "node": ">= 14" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -23182,19 +24960,45 @@ "node": ">=0.8" } }, + "node_modules/parse-imports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.0.tgz", + "integrity": "sha512-JQWgmK2o4w8leUkZeZPatWdAny6vXGU/3siIUvMF6J2rDCud9aTt8h/px9oZJ6U3EcfhngBJ635uPFI0q0VAeA==", + "dev": true, + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" }, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "engines": { + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -23245,6 +25049,12 @@ "parse-path": "^7.0.0" } }, + "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/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -23322,26 +25132,28 @@ } }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", "dev": true, + "license": "ISC", "engines": { "node": "14 || >=16.14" } @@ -23411,9 +25223,9 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -23509,10 +25321,19 @@ "node": ">=0.10.0" } }, + "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.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -23522,31 +25343,22 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "optional": true, "dependencies": { - "nanoid": "^3.3.4", + "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" } }, - "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true, - "optional": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -23556,6 +25368,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -23639,9 +25466,9 @@ } }, "node_modules/property-information": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", - "integrity": "sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "dev": true, "funding": { "type": "github", @@ -23686,9 +25513,9 @@ } }, "node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "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": { "debug": "^4.3.4" @@ -23698,9 +25525,9 @@ } }, "node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "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", @@ -23796,9 +25623,9 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -23827,12 +25654,71 @@ "node": ">=10.18.1" } }, + "node_modules/puppeteer-core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/puppeteer-core/node_modules/devtools-protocol": { "version": "0.0.981744", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.981744.tgz", "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", "dev": true }, + "node_modules/puppeteer-core/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/puppeteer-core/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/puppeteer-core/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/puppeteer-core/node_modules/ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", @@ -23858,6 +25744,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", "dev": true, "engines": { "node": ">=0.6.0", @@ -23888,15 +25775,15 @@ } }, "node_modules/query-selector-shadow-dom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.0.tgz", - "integrity": "sha512-bK0/0cCI+R8ZmOF1QjT7HupDUYCxbf/9TJgAmSXQxZpftXmTAeil9DRoCnTDkWbvOyZzhcMBwKpptWcdkGFIMg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", + "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", "dev": true }, "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "dev": true, "engines": { @@ -23959,41 +25846,41 @@ } }, "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, "node_modules/read-pkg": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-7.1.0.tgz", - "integrity": "sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", + "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", "dev": true, "dependencies": { "@types/normalize-package-data": "^2.4.1", - "normalize-package-data": "^3.0.2", - "parse-json": "^5.2.0", - "type-fest": "^2.0.0" + "normalize-package-data": "^6.0.0", + "parse-json": "^7.0.0", + "type-fest": "^4.2.0" }, "engines": { - "node": ">=12.20" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg-up": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-9.1.0.tgz", - "integrity": "sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.0.0.tgz", + "integrity": "sha512-jgmKiS//w2Zs+YbX039CorlkOp8FIVbSAN8r8GJHDsGlmNPXo+VeHkqAwCiQVTTx5/LwLZTcEw59z3DvcLbr0g==", "dev": true, "dependencies": { "find-up": "^6.3.0", - "read-pkg": "^7.1.0", - "type-fest": "^2.5.0" + "read-pkg": "^8.0.0", + "type-fest": "^3.12.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -24016,9 +25903,9 @@ } }, "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.1.1.tgz", - "integrity": "sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, "dependencies": { "p-locate": "^6.0.0" @@ -24070,45 +25957,33 @@ } }, "node_modules/read-pkg-up/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/read-pkg-up/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", "dev": true, "engines": { - "node": ">=12.20" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg/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==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.0.tgz", + "integrity": "sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw==", "dev": true, "engines": { - "node": ">=12.20" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -24130,9 +26005,9 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/readdir-glob": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.2.tgz", - "integrity": "sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, "dependencies": { "minimatch": "^5.1.0" @@ -24148,9 +26023,9 @@ } }, "node_modules/readdir-glob/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -24201,9 +26076,9 @@ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dependencies": { "regenerate": "^1.4.2" }, @@ -24212,14 +26087,14 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dependencies": { "@babel/runtime": "^7.8.4" } @@ -24251,14 +26126,15 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "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.1.3", - "functions-have-names": "^1.2.2" + "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" @@ -24280,35 +26156,21 @@ } }, "node_modules/regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dependencies": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { "node": ">=4" } }, - "node_modules/regextras": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", - "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", - "dev": true, - "engines": { - "node": ">=0.1.14" - } - }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" - }, "node_modules/regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", @@ -24329,9 +26191,9 @@ } }, "node_modules/remark": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.2.tgz", - "integrity": "sha512-A3ARm2V4BgiRXaUo5K0dRvJ1lbogrbXnhkJRmD0yw092/Yl0kOCZt1k9ZeElEwkZsWGsMumz6qL5MfNJH9nOBA==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.3.tgz", + "integrity": "sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -24361,9 +26223,9 @@ } }, "node_modules/remark-html": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-15.0.1.tgz", - "integrity": "sha512-7ta5UPRqj8nP0GhGMYUAghZ/DRno7dgq7alcW90A7+9pgJsXzGJlFgwF8HOP1b1tMgT3WwbeANN+CaTimMfyNQ==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-15.0.2.tgz", + "integrity": "sha512-/CIOI7wzHJzsh48AiuIyIe1clxVkUtreul73zcCXLub0FmnevQE0UMFDQm7NUx8/3rl/4zCshlMfqBdWScQthw==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -24378,9 +26240,9 @@ } }, "node_modules/remark-parse": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz", - "integrity": "sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", + "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -24408,9 +26270,9 @@ } }, "node_modules/remark-stringify": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.2.tgz", - "integrity": "sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.3.tgz", + "integrity": "sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==", "dev": true, "dependencies": { "@types/mdast": "^3.0.0", @@ -24591,6 +26453,16 @@ "node": ">=0.6" } }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -24622,11 +26494,11 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -24685,21 +26557,24 @@ "dev": true }, "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dev": true, "dependencies": { - "lowercase-keys": "^2.0.0" + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/resq": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.2.tgz", - "integrity": "sha512-HmgVS3j+FLrEDBTDYysPdPVF9/hioDMJ/otOiQDKqk77YfZeeLOj0qi34yObumcud1gBpk+wpBTEg4kMicD++A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", + "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", "dev": true, "dependencies": { "fast-deep-equal": "^2.0.1" @@ -24734,9 +26609,9 @@ } }, "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "node_modules/rgb2hex": { @@ -24749,6 +26624,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -24760,10 +26636,31 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true, "engines": { "node": ">=0.12.0" @@ -24779,17 +26676,20 @@ } }, "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" + "tslib": "^2.1.0" } }, + "node_modules/rxjs/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -24808,6 +26708,24 @@ "integrity": "sha512-4R309+gWflJktzPXBQCobbWEHlzC4aK3a+Ov3tz2Ib2aBxiwd11phkdIBH1l0EO22x24CJMUQkpKFumRriCSRg==", "dev": true }, + "node_modules/safe-array-concat": { + "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.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -24843,15 +26761,18 @@ } }, "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" } @@ -25118,15 +27039,31 @@ "dev": true }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "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==", "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^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" @@ -25213,13 +27150,17 @@ } }, "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==", "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" @@ -25235,8 +27176,10 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "deprecated": "16.1.1", "dev": true, "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/formatio": "^2.0.0", "diff": "^3.1.0", @@ -25257,14 +27200,14 @@ } }, "node_modules/sirv": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", - "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dev": true, "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.0" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { "node": ">= 10" @@ -25279,6 +27222,12 @@ "node": ">=0.10.0" } }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, "node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -25447,72 +27396,17 @@ "node": ">=0.10.0" } }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/snapdragon/node_modules/is-extendable": { @@ -25545,35 +27439,38 @@ } }, "node_modules/socket.io": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", - "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", + "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.4.1", + "engine.io": "~6.5.2", "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.1" + "socket.io-parser": "~4.2.4" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, + "license": "MIT", "dependencies": { - "ws": "~8.11.0" + "debug": "~4.3.4", + "ws": "~8.17.1" } }, "node_modules/socket.io-parser": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz", - "integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -25584,26 +27481,26 @@ } }, "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, "dependencies": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks-proxy-agent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", - "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", "dev": true, "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.1", "debug": "^4.3.4", "socks": "^2.7.1" }, @@ -25612,9 +27509,9 @@ } }, "node_modules/socks-proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "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": { "debug": "^4.3.4" @@ -25623,12 +27520,6 @@ "node": ">= 14" } }, - "node_modules/socks/node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "dev": true - }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -25645,9 +27536,9 @@ } }, "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, "optional": true, "engines": { @@ -25681,23 +27572,32 @@ "deprecated": "See https://github.com/lydell/source-map-url#deprecated", "dev": true }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true, - "optional": true - }, "node_modules/space-separated-tokens": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", - "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/spacetrim": { + "version": "0.11.25", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.25.tgz", + "integrity": "sha512-SWxXDROciuJs9YEYXUBjot5k/cqNGPPbT3QmkInFne4AGc1y+76It+jqU8rfsXKt57RRiunzZn1m9+KfuuNklw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" + } + ] + }, "node_modules/sparkles": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", @@ -25708,9 +27608,9 @@ } }, "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "dependencies": { "spdx-expression-parse": "^3.0.0", @@ -25718,9 +27618,9 @@ } }, "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, "node_modules/spdx-expression-parse": { @@ -25734,9 +27634,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, "node_modules/split": { @@ -25791,9 +27691,9 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "dev": true, "dependencies": { "asn1": "~0.2.3", @@ -25815,6 +27715,12 @@ "node": ">=0.10.0" } }, + "node_modules/sshpk/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -25829,6 +27735,7 @@ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -25841,6 +27748,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -25870,72 +27778,17 @@ "node": ">=0.10.0" } }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/statuses": { @@ -25946,6 +27799,18 @@ "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/stream-buffers": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", @@ -25971,15 +27836,15 @@ "dev": true }, "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", "dev": true }, "node_modules/streamroller": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", - "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", "dev": true, "dependencies": { "date-format": "^4.0.14", @@ -26023,13 +27888,17 @@ } }, "node_modules/streamx": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", - "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dev": true, "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" } }, "node_modules/strict-event-emitter": { @@ -26077,6 +27946,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -26086,38 +27956,84 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "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.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "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.19.5" + "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.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "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.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "dev": true, "dependencies": { "character-entities-html4": "^2.0.0", @@ -26129,15 +28045,18 @@ } }, "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-ansi-cjs": { @@ -26146,6 +28065,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -26153,6 +28073,18 @@ "node": ">=8" } }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -26193,9 +28125,9 @@ } }, "node_modules/strip-json-comments": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", - "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", + "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", "dev": true, "engines": { "node": ">=14.16" @@ -26236,10 +28168,32 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/synckit": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.0.tgz", + "integrity": "sha512-7RnqIMq572L8PeEzKeBINYEJDDxpcH8JEgLwUqBd3TkofhFRbkq4QLR0u+36avGAhCRbk2nnmjcW9SE531hPDg==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/synckit/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dev": true, "dependencies": { "ajv": "^8.0.1", @@ -26253,15 +28207,15 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -26274,6 +28228,18 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -26284,45 +28250,25 @@ } }, "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dev": true, "dependencies": { - "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^3.1.5" } }, "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "node_modules/temp-fs": { @@ -26337,10 +28283,32 @@ "node": ">=0.8.0" } }, + "node_modules/temp-fs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/temp-fs/node_modules/rimraf": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", "integrity": "sha512-Lw7SHMjssciQb/rRz7JyPIy9+bbUshEucPoLRvWqy09vC5zQixl8Uet+Zl+SROBB/JMWHJRdCk1qdxNWHNMvlQ==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.0.5" @@ -26372,13 +28340,13 @@ } }, "node_modules/terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.31.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", + "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -26390,16 +28358,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -26440,9 +28408,9 @@ } }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -26457,10 +28425,19 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/terser/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -26502,6 +28479,36 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -26556,9 +28563,9 @@ } }, "node_modules/through2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -26579,13 +28586,16 @@ } }, "node_modules/timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", "dev": true, "dependencies": { - "es5-ext": "~0.10.46", - "next-tick": "1" + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.12" } }, "node_modules/tiny-hashes": { @@ -26617,15 +28627,12 @@ } }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, "engines": { - "node": ">=0.6.0" + "node": ">=14.14" } }, "node_modules/to-absolute-glob": { @@ -26750,9 +28757,9 @@ } }, "node_modules/totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "engines": { "node": ">=6" @@ -26815,9 +28822,9 @@ } }, "node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "dev": true, "funding": { "type": "github", @@ -26830,21 +28837,21 @@ "integrity": "sha512-6C5h3CE+0qjGp+YKYTs74xR0k/Nw/ePtl/Lp6CCf44hqBQ66qnH1sDFR5mV/Gc48EsrHLB53lCFSffQCkka3kg==" }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "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" @@ -26878,9 +28885,9 @@ "dev": true }, "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", "dev": true }, "node_modules/type-check": { @@ -26928,27 +28935,85 @@ "node": ">= 0.6" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "node_modules/typed-array-buffer": { + "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.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } }, - "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "node_modules/typed-array-byte-length": { + "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, - "optional": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" }, "engines": { - "node": ">=4.2.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "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.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-array-length": { + "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.7", + "for-each": "^0.3.3", + "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": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, "node_modules/typescript-compare": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", @@ -26971,9 +29036,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.7.33", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz", - "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==", + "version": "0.7.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", + "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==", "dev": true, "funding": [ { @@ -26983,6 +29048,10 @@ { "type": "paypal", "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" } ], "engines": { @@ -26990,9 +29059,9 @@ } }, "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==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", "dev": true, "optional": true, "bin": { @@ -27099,9 +29168,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "engines": { "node": ">=4" } @@ -27177,9 +29246,9 @@ } }, "node_modules/unist-builder": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-3.0.0.tgz", - "integrity": "sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-3.0.1.tgz", + "integrity": "sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ==", "dev": true, "dependencies": { "@types/unist": "^2.0.0" @@ -27190,9 +29259,9 @@ } }, "node_modules/unist-util-generated": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.0.tgz", - "integrity": "sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", + "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", "dev": true, "funding": { "type": "opencollective", @@ -27200,19 +29269,22 @@ } }, "node_modules/unist-util-is": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", - "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-position": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.3.tgz", - "integrity": "sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", "dev": true, "dependencies": { "@types/unist": "^2.0.0" @@ -27223,9 +29295,9 @@ } }, "node_modules/unist-util-stringify-position": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", - "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", "dev": true, "dependencies": { "@types/unist": "^2.0.0" @@ -27236,9 +29308,9 @@ } }, "node_modules/unist-util-visit": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.1.tgz", - "integrity": "sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", "dev": true, "dependencies": { "@types/unist": "^2.0.0", @@ -27251,9 +29323,9 @@ } }, "node_modules/unist-util-visit-parents": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz", - "integrity": "sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", "dev": true, "dependencies": { "@types/unist": "^2.0.0", @@ -27265,9 +29337,9 @@ } }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "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" @@ -27352,6 +29424,12 @@ "setimmediate": "~1.0.4" } }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "dev": true + }, "node_modules/unzipper/node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -27372,9 +29450,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "funding": [ { "type": "opencollective", @@ -27383,14 +29461,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -27413,13 +29495,13 @@ "dev": true }, "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", "dev": true, "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" + "punycode": "^1.4.1", + "qs": "^6.11.2" } }, "node_modules/url-parse": { @@ -27439,11 +29521,26 @@ "dev": true }, "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", "dev": true }, + "node_modules/url/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/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -27489,13 +29586,16 @@ } }, "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/uvu": { @@ -27517,9 +29617,9 @@ } }, "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", "dev": true }, "node_modules/v8flags": { @@ -27582,9 +29682,9 @@ "dev": true }, "node_modules/vfile": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", - "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", "dev": true, "dependencies": { "@types/unist": "^2.0.0", @@ -27597,10 +29697,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", - "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", "dev": true, "dependencies": { "@types/unist": "^2.0.0", @@ -27612,15 +29726,17 @@ } }, "node_modules/vfile-reporter": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-7.0.4.tgz", - "integrity": "sha512-4cWalUnLrEnbeUQ+hARG5YZtaHieVK3Jp4iG5HslttkVl+MHunSGNAIrODOTLbtjWsNZJRMCkL66AhvZAYuJ9A==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-7.0.5.tgz", + "integrity": "sha512-NdWWXkv6gcd7AZMvDomlQbK3MqFWL1RlGzMn++/O2TI+68+nqxCPTvLugdOtfSzXmjh+xUyhp07HhlrbJjT+mw==", "dev": true, "dependencies": { "@types/supports-color": "^8.0.0", "string-width": "^5.0.0", "supports-color": "^9.0.0", "unist-util-stringify-position": "^3.0.0", + "vfile": "^5.0.0", + "vfile-message": "^3.0.0", "vfile-sort": "^3.0.0", "vfile-statistics": "^2.0.0" }, @@ -27629,18 +29745,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-reporter/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/vfile-reporter/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -27664,25 +29768,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vfile-reporter/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/vfile-reporter/node_modules/supports-color": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.3.tgz", - "integrity": "sha512-aszYUX/DVK/ed5rFLb/dDinVJrQjG/vmU433wtqVSD800rYsJNWxh2R3USV90aLSU+UsyQkbNeffVLzc6B6foA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", "dev": true, "engines": { "node": ">=12" @@ -27692,11 +29781,12 @@ } }, "node_modules/vfile-sort": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-3.0.0.tgz", - "integrity": "sha512-fJNctnuMi3l4ikTVcKpxTbzHeCgvDhnI44amA3NVDvA6rTC6oKCFpCVyT5n2fFMr3ebfr+WVQZedOCd73rzSxg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-3.0.1.tgz", + "integrity": "sha512-1os1733XY6y0D5x0ugqSeaVJm9lYgj0j5qdcZQFyxlZOSy1jYarL77lLyb5gK4Wqr1d5OxmuyflSO3zKyFnTFw==", "dev": true, "dependencies": { + "vfile": "^5.0.0", "vfile-message": "^3.0.0" }, "funding": { @@ -27705,11 +29795,12 @@ } }, "node_modules/vfile-statistics": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-2.0.0.tgz", - "integrity": "sha512-foOWtcnJhKN9M2+20AOTlWi2dxNfAoeNIoxD5GXcO182UJyId4QrXa41fWrgcfV3FWTjdEDy3I4cpLVcQscIMA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-2.0.1.tgz", + "integrity": "sha512-W6dkECZmP32EG/l+dp2jCLdYzmnDBIw6jwiLZSER81oR5AHRcVqL+k3Z+pfH1R73le6ayDkJRMk0sutj1bMVeg==", "dev": true, "dependencies": { + "vfile": "^5.0.0", "vfile-message": "^3.0.0" }, "funding": { @@ -27718,24 +29809,24 @@ } }, "node_modules/video.js": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.20.3.tgz", - "integrity": "sha512-JMspxaK74LdfWcv69XWhX4rILywz/eInOVPdKefpQiZJSMD5O8xXYueqACP2Q5yqKstycgmmEKlJzZ+kVmDciw==", + "version": "7.21.6", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.6.tgz", + "integrity": "sha512-m41TbODrUCToVfK1aljVd296CwDQnCRewpIm5tTXMuV87YYSGw1H+VDOaV45HlpcWSsTWWLF++InDgGJfthfUw==", "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/http-streaming": "2.14.3", + "@videojs/http-streaming": "2.16.3", "@videojs/vhs-utils": "^3.0.4", "@videojs/xhr": "2.6.0", "aes-decrypter": "3.1.3", "global": "^4.4.0", "keycode": "^2.2.0", - "m3u8-parser": "4.7.1", - "mpd-parser": "0.21.1", + "m3u8-parser": "4.8.0", + "mpd-parser": "0.22.1", "mux.js": "6.0.1", "safe-json-parse": "4.0.0", "videojs-font": "3.2.0", - "videojs-vtt.js": "^0.15.4" + "videojs-vtt.js": "^0.15.5" } }, "node_modules/video.js/node_modules/safe-json-parse": { @@ -27788,22 +29879,22 @@ } }, "node_modules/videojs-playlist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/videojs-playlist/-/videojs-playlist-5.0.0.tgz", - "integrity": "sha512-TM9bytwKqkE05wdWPEKDpkwMGhS/VgMCIsEuNxmX1J1JO9zaTIl4Wm3egf5j1dhIw19oWrqGUV/nK0YNIelCpA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/videojs-playlist/-/videojs-playlist-5.1.2.tgz", + "integrity": "sha512-8YgNq/iL17RLTXpfWAkuhM0Sq4w/x5YPVaNbUycjfqqGL/bp3Nrmc2W0qkPfh0ryB7r4cHfJbtHYP7zlW3ZkdQ==", "dev": true, "dependencies": { "global": "^4.3.2", - "video.js": "^6 || ^7" + "video.js": "^6 || ^7 || ^8" }, "engines": { "node": ">=4.4.0" } }, "node_modules/videojs-vtt.js": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.4.tgz", - "integrity": "sha512-r6IhM325fcLb1D6pgsMkTQT1PpFdUdYZa1iqk7wJEu+QlibBwATPfPc9Bg8Jiym0GE5yP1AG2rMLu+QMVWkYtA==", + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz", + "integrity": "sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==", "dev": true, "dependencies": { "global": "^4.3.1" @@ -27890,6 +29981,12 @@ "node": ">= 0.10" } }, + "node_modules/vinyl-sourcemap/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/vinyl-sourcemap/node_modules/normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -27930,9 +30027,9 @@ } }, "node_modules/vue-template-compiler": { - "version": "2.7.13", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.13.tgz", - "integrity": "sha512-jYM6TClwDS9YqP48gYrtAtaOhRKkbYmbzE+Q51gX5YDr777n7tNI/IZk4QV4l/PjQPNh/FVa/E92sh/RqKMrog==", + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, "optional": true, "dependencies": { @@ -28046,9 +30143,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -28067,6 +30164,16 @@ "defaults": "^1.0.3" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/web-streams-polyfill": { "version": "4.0.0-beta.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", @@ -28077,18 +30184,19 @@ } }, "node_modules/webdriver": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.29.1.tgz", - "integrity": "sha512-D3gkbDUxFKBJhNHRfMriWclooLbNavVQC1MRvmENAgPNKaHnFn+M+WtP9K2sEr0XczLGNlbOzT7CKR9K5UXKXA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.39.0.tgz", + "integrity": "sha512-Kc3+SfiH4ufyrIht683VT2vnJocx0pfH8rYdyPvEh1b2OYewtFTHK36k9rBDHZiBmk6jcSXs4M2xeFgOuon9Lg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "deepmerge-ts": "^5.1.0", "got": "^12.6.1", "ky": "^0.33.0", @@ -28098,220 +30206,125 @@ "node": "^16.13 || >=18" } }, - "node_modules/webdriver/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/webdriver/node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/webdriver/node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "dev": true, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/webdriver/node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/webdriver/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/webdriver/node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "node_modules/webdriver/node_modules/@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, + "license": "MIT", "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/webdriver/node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/webdriver/node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/webdriver/node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/webdriver/node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "dev": true, - "engines": { - "node": ">=14.16" + "@types/node": "^20.1.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/webdriver/node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true, "engines": { - "node": ">=12.20" + "node": "^16.13 || >=18" } }, - "node_modules/webdriver/node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "node_modules/webdriver/node_modules/@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, + "license": "MIT", "dependencies": { - "lowercase-keys": "^3.0.0" + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" }, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^16.13 || >=18" } }, "node_modules/webdriverio": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.25.4.tgz", - "integrity": "sha512-agkgwn2SIk5cAJ03uue1GnGZcUZUDN3W4fUMY9/VfO8bVJrPEgWg31bPguEWPu+YhEB/aBJD8ECxJ3OEKdy4qQ==", + "version": "7.36.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.36.0.tgz", + "integrity": "sha512-OTYmKBF7eFKBX39ojUIEzw7AlE1ZRJiFoMTtEQaPMuPzZCP2jUBq6Ey38nuZrYXLkXn3/le9a14pNnKSM0n56w==", "dev": true, "dependencies": { "@types/aria-query": "^5.0.0", "@types/node": "^18.0.0", - "@wdio/config": "7.25.4", - "@wdio/logger": "7.19.0", - "@wdio/protocols": "7.22.0", - "@wdio/repl": "7.25.4", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@wdio/config": "7.33.0", + "@wdio/logger": "7.26.0", + "@wdio/protocols": "7.27.0", + "@wdio/repl": "7.33.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "archiver": "^5.0.0", - "aria-query": "^5.0.0", + "aria-query": "^5.2.1", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools": "7.25.4", - "devtools-protocol": "^0.0.1061995", - "fs-extra": "^10.0.0", + "devtools": "7.35.0", + "devtools-protocol": "^0.0.1260888", + "fs-extra": "^11.1.1", "grapheme-splitter": "^1.0.2", "lodash.clonedeep": "^4.5.0", "lodash.isobject": "^3.0.2", "lodash.isplainobject": "^4.0.6", "lodash.zip": "^4.2.0", - "minimatch": "^5.0.0", + "minimatch": "^6.0.4", "puppeteer-core": "^13.1.3", "query-selector-shadow-dom": "^1.0.0", "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^8.0.0", - "webdriver": "7.25.4" + "webdriver": "7.33.0" }, "engines": { "node": ">=12.0.0" } }, + "node_modules/webdriverio/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/webdriverio/node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/webdriverio/node_modules/@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", - "dev": true + "version": "18.19.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", + "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/webdriverio/node_modules/@wdio/config": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.25.4.tgz", - "integrity": "sha512-vb0emDtD9FbFh/yqW6oNdo2iuhQp8XKj6GX9fyy9v4wZgg3B0HPMVJxhIfcoHz7LMBWlHSo9YdvhFI5EQHRLBA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.33.0.tgz", + "integrity": "sha512-SaCZNKrDtBghf7ujyaxTiU4pBW+1Kms32shSoXpJ/wFop6/MiA7nb19qpUPoJtEDw5/NOKevUKz8nBMBXphiew==", "dev": true, "dependencies": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@types/glob": "^8.1.0", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "deepmerge": "^4.0.0", "glob": "^8.0.3" }, @@ -28320,9 +30333,9 @@ } }, "node_modules/webdriverio/node_modules/@wdio/logger": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.19.0.tgz", - "integrity": "sha512-xR7SN/kGei1QJD1aagzxs3KMuzNxdT/7LYYx+lt6BII49+fqL/SO+5X0FDCZD0Ds93AuQvvz9eGyzrBI2FFXmQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", + "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, "dependencies": { "chalk": "^4.0.0", @@ -28335,30 +30348,30 @@ } }, "node_modules/webdriverio/node_modules/@wdio/protocols": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.22.0.tgz", - "integrity": "sha512-8EXRR+Ymdwousm/VGtW3H1hwxZ/1g1H99A1lF0U4GuJ5cFWHCd0IVE5H31Z52i8ZruouW8jueMkGZPSo2IIUSQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", + "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", "dev": true, "engines": { "node": ">=12.0.0" } }, "node_modules/webdriverio/node_modules/@wdio/repl": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.25.4.tgz", - "integrity": "sha512-kYhj9gLsUk4HmlXLqkVre+gwbfvw9CcnrHjqIjrmMS4mR9D8zvBb5CItb3ZExfPf9jpFzIFREbCAYoE9x/kMwg==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.33.0.tgz", + "integrity": "sha512-17KM9NCg+UVpZNbS8koT/917vklF5M8IQnw0kGwmJEo444ifTMxmLwQymbS2ovQKAKAQxlfdM7bpqMeI15kzsQ==", "dev": true, "dependencies": { - "@wdio/utils": "7.25.4" + "@wdio/utils": "7.33.0" }, "engines": { "node": ">=12.0.0" } }, "node_modules/webdriverio/node_modules/@wdio/types": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.25.4.tgz", - "integrity": "sha512-muvNmq48QZCvocctnbe0URq2FjJjUPIG4iLoeMmyF0AQgdbjaUkMkw3BHYNHVTbSOU9WMsr2z8alhj/I2H6NRQ==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.33.0.tgz", + "integrity": "sha512-tNcuN5Kl+i5CffaeTYV1omzAo4rVjiI1m9raIA8ph6iVteWdCzYv2/ImpGgFiBPb7Mf6VokU3+q9Slh5Jitaww==", "dev": true, "dependencies": { "@types/node": "^18.0.0", @@ -28377,13 +30390,13 @@ } }, "node_modules/webdriverio/node_modules/@wdio/utils": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.25.4.tgz", - "integrity": "sha512-8iwQDk+foUqSzKZKfhLxjlCKOkfRJPNHaezQoevNgnrTq/t0ek+ldZCATezb9B8jprAuP4mgS9xi22akc6RkzA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.33.0.tgz", + "integrity": "sha512-4kQQ86EvEN6fBY5+u7M08cT6LfJtpk1rHd203xyxmbmV9lpNv/OCl4CsC+SD0jGT0aZZqYSIJ/Pil07pAh5K0g==", "dev": true, "dependencies": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", "p-iteration": "^1.1.8" }, "engines": { @@ -28414,6 +30427,33 @@ "balanced-match": "^1.0.0" } }, + "node_modules/webdriverio/node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/webdriverio/node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/webdriverio/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -28448,10 +30488,40 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/webdriverio/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/webdriverio/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/webdriverio/node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -28467,6 +30537,43 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/webdriverio/node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/webdriverio/node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/webdriverio/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -28476,6 +30583,31 @@ "node": ">=8" } }, + "node_modules/webdriverio/node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/webdriverio/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/webdriverio/node_modules/ky": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz", @@ -28488,16 +30620,73 @@ "url": "https://github.com/sindresorhus/ky?sponsor=1" } }, + "node_modules/webdriverio/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/webdriverio/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", + "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/webdriverio/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webdriverio/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webdriverio/node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webdriverio/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/webdriverio/node_modules/supports-color": { @@ -28513,17 +30702,17 @@ } }, "node_modules/webdriverio/node_modules/webdriver": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.25.4.tgz", - "integrity": "sha512-6nVDwenh0bxbtUkHASz9B8T9mB531Fn1PcQjUGj2t5dolLPn6zuK1D7XYVX40hpn6r3SlYzcZnEBs4X0az5Txg==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.33.0.tgz", + "integrity": "sha512-cyMRAVUHgQhEBHojOeNet2e8GkfyvvjpioNCPcF6qUtT+URdagr8Mh0t4Fs+Jr0tpuMqFnw70xZexAcV/6I/jg==", "dev": true, "dependencies": { "@types/node": "^18.0.0", - "@wdio/config": "7.25.4", - "@wdio/logger": "7.19.0", - "@wdio/protocols": "7.22.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@wdio/config": "7.33.0", + "@wdio/logger": "7.26.0", + "@wdio/protocols": "7.27.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "got": "^11.0.2", "ky": "0.30.0", "lodash.merge": "^4.6.1" @@ -28539,34 +30728,34 @@ "dev": true }, "node_modules/webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.92.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.0.tgz", + "integrity": "sha512-Bsw2X39MYIgxouNATyVpCNVWBCuUwDgWtN78g6lSdPJRLaQ/PUVm/oXcaRAyY/sMFoKFQrsPeqvTizWtq7QPCA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -28586,19 +30775,22 @@ } }, "node_modules/webpack-bundle-analyzer": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz", - "integrity": "sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", "dev": true, "dependencies": { + "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", - "lodash": "^4.17.20", + "html-escaper": "^2.0.2", "opener": "^1.5.2", - "sirv": "^1.0.7", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", "ws": "^7.3.1" }, "bin": { @@ -28609,9 +30801,9 @@ } }, "node_modules/webpack-bundle-analyzer/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -28620,55 +30812,6 @@ "node": ">=0.4.0" } }, - "node_modules/webpack-bundle-analyzer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/webpack-bundle-analyzer/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/webpack-bundle-analyzer/node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -28678,32 +30821,24 @@ "node": ">= 10" } }, - "node_modules/webpack-bundle-analyzer/node_modules/has-flag": { + "node_modules/webpack-bundle-analyzer/node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" + "node": ">=10" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -28881,9 +31016,9 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -28892,10 +31027,10 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "node_modules/webpack/node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -28917,10 +31052,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/webpack/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/webpack/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -28969,18 +31110,18 @@ } }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/which-boxed-primitive": { @@ -29000,15 +31141,18 @@ } }, "node_modules/which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "dependencies": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -29021,17 +31165,16 @@ "dev": true }, "node_modules/which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "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", - "es-abstract": "^1.20.0", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -29041,9 +31184,9 @@ } }, "node_modules/winston-transport": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", - "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", "dev": true, "dependencies": { "logform": "^2.3.2", @@ -29069,9 +31212,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -29090,9 +31233,9 @@ "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==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", @@ -29100,10 +31243,7 @@ "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/wrap-ansi-cjs": { @@ -29112,6 +31252,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -29129,6 +31270,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -29144,6 +31286,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -29155,7 +31298,21 @@ "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 + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", @@ -29190,6 +31347,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -29208,29 +31377,18 @@ "node": ">=4" } }, - "node_modules/write/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/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -29260,10 +31418,9 @@ } }, "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 + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yargs": { "version": "1.3.3", @@ -29307,6 +31464,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yargs-unparser/node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -29317,45 +31486,90 @@ } }, "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.3.tgz", + "integrity": "sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw==", "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, "dependencies": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", "readable-stream": "^3.6.0" }, "engines": { "node": ">= 10" } }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "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/zip-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -29367,9 +31581,9 @@ } }, "node_modules/zwitch": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", - "integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "dev": true, "funding": { "type": "github", @@ -29385,481 +31599,345 @@ }, "dependencies": { "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==" + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==" }, "@babel/core": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz", - "integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==", - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.6", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helpers": "^7.19.4", - "@babel/parser": "^7.19.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4", - "convert-source-map": "^1.7.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" } }, "@babel/eslint-parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", - "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.7.tgz", + "integrity": "sha512-SO5E3bVxDuxyNxM5agFv480YA2HO6ohZbGxbazZdIk3KQOPOGVNw6q78I9/lbviIf95eq6tPozeYnJLbjnC8IA==", "dev": true, "requires": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" + "semver": "^6.3.1" } }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "requires": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } } }, "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", "requires": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", - "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", + "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" } }, "@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "requires": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" } }, "@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==" - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" } }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", "requires": { - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "requires": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-module-transforms": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz", - "integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.19.4", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.6", - "@babel/types": "^7.19.4" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" } }, "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" } }, "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==" + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==" }, "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", + "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-wrap-function": "^7.24.7" } }, "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" } }, "@babel/helper-simple-access": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", - "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "requires": { - "@babel/types": "^7.19.4" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "requires": { - "@babel/types": "^7.20.0" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" } }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==" }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" }, "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==" }, "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", + "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-function-name": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "requires": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" } }, "@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==" }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", + "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", - "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", - "requires": { - "@babel/compat-data": "^7.19.4", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", + "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.24.7" } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" } }, - "@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", + "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "requires": {} }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -29902,11 +31980,27 @@ } }, "@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-json-strings": { @@ -29981,333 +32075,485 @@ "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-transform-arrow-functions": { + "@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" } }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", + "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", + "requires": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.0.tgz", - "integrity": "sha512-sXOohbpHZSk7GjxK9b3dKB7CfqUD5DwOH+DggKzOQ7TXYP+RCSbRykfjQmn/zq+rBjycVRtLf9pYhAaEJA786w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", + "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-transform-classes": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", - "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.19.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", + "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" } }, "@babel/plugin-transform-destructuring": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.0.tgz", - "integrity": "sha512-1dIhvZfkDVx/zn2S1aFwlruspTt4189j7fEkH0Y0VyuDM6bQt7bD6kLcz3l4IlLG+e5OReaBz9ROAbttRtUHqA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", + "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" } }, "@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", + "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", + "requires": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", "requires": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", + "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", "requires": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "requires": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" } }, "@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", + "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-transform-parameters": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.1.tgz", - "integrity": "sha512-nDvKLrAvl+kf6BOy1UJ3MGwzzfTMgppxwiD2Jb4LO3xjYyZq30oQzDNJbCQpMdG9+j2IXHoiMrw5Cm/L6ZoxXQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "requires": { + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", - "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "semver": "^6.3.0" + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "requires": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", + "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + } + }, + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" } }, "@babel/preset-env": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz", - "integrity": "sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==", - "requires": { - "@babel/compat-data": "^7.19.4", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.19.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.19.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", + "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", + "requires": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -30317,101 +32563,120 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.19.4", - "@babel/plugin-transform-classes": "^7.19.0", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.19.4", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.18.6", - "@babel/plugin-transform-modules-commonjs": "^7.18.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.0", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.18.8", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.19.4", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" } }, "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" } }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, "@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "requires": { - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.14.0" } }, "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", - "requires": { - "@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", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", "globals": "^11.1.0" } }, "@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.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" } }, @@ -30421,15 +32686,24 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, "@es-joy/jsdoccomment": { - "version": "0.22.2", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.22.2.tgz", - "integrity": "sha512-pM6WQKcuAtdYoqCsXSvVSu3Ij8K0HY50L8tIheOKHDl0wH1uA4zbP88etY8SIeP16NVCMCTFU+Q2DahSKheGGQ==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "requires": { - "comment-parser": "1.3.1", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~2.2.5" + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", + "comment-parser": "1.4.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" } }, "@eslint/eslintrc": { @@ -30462,9 +32736,9 @@ } }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -30623,12 +32897,6 @@ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, "ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", @@ -30652,15 +32920,6 @@ "strip-ansi": "^7.0.1" } }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, "wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -30777,68 +33036,56 @@ } }, "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" }, "@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==" }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@ljharb/through": { - "version": "2.3.12", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz", - "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==", + "version": "2.3.13", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", + "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", "dev": true, "requires": { - "call-bind": "^1.0.5" + "call-bind": "^1.0.7" } }, "@nicolo-ribaudo/eslint-scope-5-internals": { @@ -30857,39 +33104,28 @@ "dev": true }, "@percy/appium-app": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@percy/appium-app/-/appium-app-2.0.3.tgz", - "integrity": "sha512-6INeUJSyK2LzWV4Cc9bszNqKr3/NLcjFelUC2grjPnm6+jLA29inBF4ZE3PeTfLeCSw/0jyCGWV5fr9AyxtzCA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@percy/appium-app/-/appium-app-2.0.6.tgz", + "integrity": "sha512-0NT8xgaq4UOhcqVc4H3D440M7H5Zko8mDpY5j30TRpjOQ3ctLPJalmUVKOCFv4rSzjd2LmyE2F9KXTPA3zqQsw==", "dev": true, "requires": { - "@percy/sdk-utils": "^1.27.0-beta.0", + "@percy/sdk-utils": "^1.28.2", "tmp": "^0.2.1" - }, - "dependencies": { - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - } } }, "@percy/sdk-utils": { - "version": "1.27.7", - "resolved": "https://registry.npmjs.org/@percy/sdk-utils/-/sdk-utils-1.27.7.tgz", - "integrity": "sha512-E21dIEQ9wwGDno41FdMDYf6jJow5scbWGClqKE/ptB+950W4UF5C4hxhVVQoEJxDdLE/Gy/8ZJR7upvPHShWDg==", + "version": "1.28.7", + "resolved": "https://registry.npmjs.org/@percy/sdk-utils/-/sdk-utils-1.28.7.tgz", + "integrity": "sha512-LIhfHnkcS0fyIdo3gvKn7rwodZjbEtyLkgiDRSRulcBOatI2mhn2Bh269sXXiiFTyAW2BDQjyE3DWc4hkGbsbQ==", "dev": true }, "@percy/selenium-webdriver": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@percy/selenium-webdriver/-/selenium-webdriver-2.0.3.tgz", - "integrity": "sha512-JfLJVRkwNfqVofe7iGKtoQbOcKSSj9t4pWFbSUk95JfwAA7b9/c+dlBsxgIRrdrMYzLRjnJkYAFSZkJ4F4A19A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@percy/selenium-webdriver/-/selenium-webdriver-2.0.5.tgz", + "integrity": "sha512-bNj52xQm02dY872loFa+8OwyuGcdYHYvCKflmSEsF9EDRiSDj0Wr+XP+DDIgDAl9xXschA7OOdXCLTWV4zEQWA==", "dev": true, "requires": { - "@percy/sdk-utils": "^1.27.2", + "@percy/sdk-utils": "^1.28.0", "node-request-interceptor": "^0.6.3" } }, @@ -30900,12 +33136,29 @@ "dev": true, "optional": true }, + "@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true + }, "@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "version": "1.0.0-next.25", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", + "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "dev": true }, + "@promptbook/utils": { + "version": "0.50.0-10", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.50.0-10.tgz", + "integrity": "sha512-Z94YoY/wcZb5m1QoXgmIC1rVeDguGK5bWmUTYdWCqh/LHVifRdJ1C+tBzS0h+HMOD0XzMjZhBQ/mBgTZ/QNW/g==", + "dev": true, + "requires": { + "moment": "2.30.1", + "prettier": "2.8.1", + "spacetrim": "0.11.25" + } + }, "@puppeteer/browsers": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.9.1.tgz", @@ -30921,26 +33174,13 @@ "yargs": "17.7.2" }, "dependencies": { - "tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "requires": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "ms": "2.1.2" } }, "yargs": { @@ -30967,15 +33207,15 @@ "dev": true }, "@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==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", "dev": true }, "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -31008,18 +33248,18 @@ "dev": true }, "@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", "dev": true }, "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, "requires": { - "defer-to-connect": "^2.0.0" + "defer-to-connect": "^2.0.1" } }, "@tootallnate/once": { @@ -31037,21 +33277,21 @@ "dev": true }, "@types/aria-query": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", - "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true }, "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "dev": true, "requires": { "@types/http-cache-semantics": "*", - "@types/keyv": "*", + "@types/keyv": "^3.1.4", "@types/node": "*", - "@types/responselike": "*" + "@types/responselike": "^1.0.0" } }, "@types/cookie": { @@ -31061,27 +33301,27 @@ "dev": true }, "@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, "requires": { "@types/node": "*" } }, "@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, "requires": { "@types/ms": "*" } }, "@types/eslint": { - "version": "8.4.9", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.9.tgz", - "integrity": "sha512-jFCSo4wJzlHQLCpceUhUnXdrPuCNOjGFMQ8Eg6JXxlz3QaCKOb7eGi2cephQdM4XTYsNej69P9JDJ1zqNIbncQ==", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, "requires": { "@types/estree": "*", @@ -31089,9 +33329,9 @@ } }, "@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "requires": { "@types/eslint": "*", @@ -31099,9 +33339,9 @@ } }, "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@types/expect": { @@ -31111,9 +33351,9 @@ "dev": true }, "@types/extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.1.tgz", - "integrity": "sha512-R1g/VyKFFI2HLC1QGAeTtCBWCo6n75l41OnsVYNbmKG+kempOESaodf6BeJyUM3Q0rKa/NQcTHbB2+66lNnxLw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.4.tgz", + "integrity": "sha512-ArMouDUTJEz1SQRpFsT2rIw7DeqICFv5aaVzLSIYMYQSLcwcGOfT3VyglQs/p7K3F7fT4zxr0NWxYZIdifD6dA==", "dev": true }, "@types/gitconfiglocal": { @@ -31122,19 +33362,23 @@ "integrity": "sha512-W6hyZux6TrtKfF2I9XNLVcsFr4xRr0T+S6hrJ9nDkhA2vzsFPIEAbnY4vgb6v2yKXQ9MJVcbLsARNlMfg4EVtQ==", "dev": true }, - "@types/github-slugger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/github-slugger/-/github-slugger-1.3.0.tgz", - "integrity": "sha512-J/rMZa7RqiH/rT29TEVZO4nBoDP9XJOjnbbIofg7GQKs4JIduEO3WLpte+6WeUz/TcrXKlY+bM7FYrp8yFB+3g==", - "dev": true + "@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "requires": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } }, "@types/hast": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", - "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", "dev": true, "requires": { - "@types/unist": "*" + "@types/unist": "^2" } }, "@types/http-cache-semantics": { @@ -31168,9 +33412,9 @@ } }, "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/json5": { @@ -31180,23 +33424,29 @@ "dev": true }, "@types/keyv": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-4.2.0.tgz", - "integrity": "sha512-xoBtGl5R9jeKUhc8ZqeYaRDx04qqJ10yhhXYGmJ4Jr8qKpvMsDQQrNUvF/wUJ4klOtmJeJM+p2Xo3zp9uaC3tw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dev": true, "requires": { - "keyv": "*" + "@types/node": "*" } }, "@types/mdast": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", - "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", "dev": true, "requires": { - "@types/unist": "*" + "@types/unist": "^2" } }, + "@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, "@types/mocha": { "version": "10.0.6", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", @@ -31204,30 +33454,36 @@ "dev": true }, "@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", "dev": true }, "@types/node": { - "version": "20.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", - "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "dev": true, "requires": { "undici-types": "~5.26.4" } }, "@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==", + "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 + }, + "@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==", "dev": true }, "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, "requires": { "@types/node": "*" @@ -31240,9 +33496,9 @@ "dev": true }, "@types/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.3.tgz", + "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==", "dev": true }, "@types/triple-beam": { @@ -31252,21 +33508,21 @@ "dev": true }, "@types/ua-parser-js": { - "version": "0.7.36", - "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", - "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==", "dev": true }, "@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", "dev": true }, "@types/vinyl": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.6.tgz", - "integrity": "sha512-ayJ0iOCDNHnKpKTgBG6Q6JOnHTj9zFta+3j2b8Ejza0e4cvRyMn0ZoLEmbPrTHe5YYRlDYPvPWVdV4cTaRyH7g==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.12.tgz", + "integrity": "sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==", "dev": true, "requires": { "@types/expect": "^1.20.4", @@ -31274,9 +33530,9 @@ } }, "@types/which": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", - "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", + "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", "dev": true }, "@types/ws": { @@ -31304,27 +33560,33 @@ "dev": true }, "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "optional": true, "requires": { "@types/node": "*" } }, + "@typescript-eslint/types": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", + "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", + "dev": true + }, "@videojs/http-streaming": { - "version": "2.14.3", - "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.14.3.tgz", - "integrity": "sha512-2tFwxCaNbcEZzQugWf8EERwNMyNtspfHnvxRGRABQs09W/5SqmkWFuGWfUAm4wQKlXGfdPyAJ1338ASl459xAA==", + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "3.0.5", "aes-decrypter": "3.1.3", "global": "^4.4.0", - "m3u8-parser": "4.7.1", - "mpd-parser": "0.21.1", + "m3u8-parser": "4.8.0", + "mpd-parser": "^0.22.1", "mux.js": "6.0.1", "video.js": "^6 || ^7" } @@ -31352,138 +33614,89 @@ } }, "@vitest/snapshot": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.1.tgz", - "integrity": "sha512-Tmp/IcYEemKaqAYCS08sh0vORLJkMr0NRV76Gl8sHGxXT5151cITJCET20063wk0Yr/1koQ6dnmP6eEqezmd/Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, "requires": { "magic-string": "^0.30.5", "pathe": "^1.1.1", "pretty-format": "^29.7.0" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - } } }, "@vue/compiler-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz", - "integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz", + "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==", "dev": true, "optional": true, "requires": { - "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.41", + "@babel/parser": "^7.24.4", + "@vue/shared": "3.4.27", + "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } + "source-map-js": "^1.2.0" } }, "@vue/compiler-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz", - "integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz", + "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==", "dev": true, "optional": true, "requires": { - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-core": "3.4.27", + "@vue/shared": "3.4.27" } }, "@vue/compiler-sfc": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz", - "integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz", + "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==", "dev": true, "optional": true, "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-ssr": "3.2.41", - "@vue/reactivity-transform": "3.2.41", - "@vue/shared": "3.2.41", + "@babel/parser": "^7.24.4", + "@vue/compiler-core": "3.4.27", + "@vue/compiler-dom": "3.4.27", + "@vue/compiler-ssr": "3.4.27", + "@vue/shared": "3.4.27", "estree-walker": "^2.0.2", - "magic-string": "^0.25.7", - "postcss": "^8.1.10", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } + "magic-string": "^0.30.10", + "postcss": "^8.4.38", + "source-map-js": "^1.2.0" } }, "@vue/compiler-ssr": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz", - "integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz", + "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==", "dev": true, "optional": true, "requires": { - "@vue/compiler-dom": "3.2.41", - "@vue/shared": "3.2.41" - } - }, - "@vue/reactivity-transform": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz", - "integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==", - "dev": true, - "optional": true, - "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7" + "@vue/compiler-dom": "3.4.27", + "@vue/shared": "3.4.27" } }, "@vue/shared": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz", - "integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", + "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==", "dev": true, "optional": true }, "@wdio/browserstack-service": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/browserstack-service/-/browserstack-service-8.29.1.tgz", - "integrity": "sha512-dLEJcdVF0Cu+2REByVOfLUzx9FvMias1VsxSCZpKXeIAGAIWBBdNdooK6Vdc9QdS36S5v/mk0/rTTQhYn4nWjQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/browserstack-service/-/browserstack-service-8.39.0.tgz", + "integrity": "sha512-EEbmg9hBk0FAf9b2oHEL0w8aIscKPy3ms0/zSaLp+jDMuWHllpVQ83GCW9qHIJbKUzTNUlF031fRdPzq+GQaVg==", "dev": true, "requires": { "@percy/appium-app": "^2.0.1", "@percy/selenium-webdriver": "^2.0.3", "@types/gitconfiglocal": "^2.0.1", - "@wdio/logger": "8.28.0", - "@wdio/reporter": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/reporter": "8.39.0", + "@wdio/types": "8.39.0", "browserstack-local": "^1.5.1", "chalk": "^5.3.0", "csv-writer": "^1.6.0", @@ -31492,80 +33705,82 @@ "gitconfiglocal": "^2.1.0", "got": "^12.6.1", "uuid": "^9.0.0", - "webdriverio": "8.29.1", + "webdriverio": "8.39.0", "winston-transport": "^4.5.0", - "yauzl": "^2.10.0" + "yauzl": "^3.0.0" }, "dependencies": { - "@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "@wdio/reporter": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.39.0.tgz", + "integrity": "sha512-XahXhmaA1okdwg4/ThHFSqy/41KywxhbtszPcTzyXB+9INaqFNHA1b1vvWs0mrD5+tTtKbg4caTcEHVJU4iv0w==", "dev": true, - "optional": true, - "peer": true, "requires": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" + "@types/node": "^20.1.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "diff": "^5.0.0", + "object-inspect": "^1.12.0" } }, - "@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, "requires": { - "defer-to-connect": "^2.0.1" + "@types/node": "^20.1.0" } }, - "@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true, - "optional": true, - "peer": true + "@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", + "dev": true, + "requires": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + } }, "archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, "requires": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" } }, "archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, "requires": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "async": { @@ -31583,27 +33798,22 @@ "balanced-match": "^1.0.0" } }, - "cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "dev": true - }, - "cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "requires": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, + "buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true + }, "chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -31611,9 +33821,9 @@ "dev": true }, "chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, "optional": true, "peer": true, @@ -31625,25 +33835,26 @@ } }, "compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, "requires": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, "requires": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" } }, "cross-fetch": { @@ -31657,41 +33868,39 @@ "node-fetch": "^2.6.11" } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, "devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, "optional": true, "peer": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" - }, - "dependencies": { - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "isexe": "^3.1.1" - } - } } }, "devtools-protocol": { @@ -31702,18 +33911,6 @@ "optional": true, "peer": true }, - "edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -31722,55 +33919,6 @@ "optional": true, "peer": true }, - "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 - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "dependencies": { - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dev": true, - "requires": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - } - }, "http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -31782,25 +33930,34 @@ "@tootallnate/once": "2", "agent-base": "6", "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, - "http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - } - }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "optional": true, - "peer": true + "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 }, "lighthouse-logger": { "version": "2.0.1", @@ -31812,43 +33969,18 @@ "requires": { "debug": "^2.6.9", "marky": "^1.2.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "ms": "2.0.0" - } - } } }, - "lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true - }, "lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true }, - "mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "dev": true - }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -31871,18 +34003,6 @@ "whatwg-url": "^5.0.0" } }, - "normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "dev": true - }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true - }, "proxy-agent": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz", @@ -31900,18 +34020,27 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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, "requires": { "agent-base": "^7.1.0", @@ -31919,14 +34048,20 @@ } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "requires": { "agent-base": "^7.0.2", "debug": "4" } + }, + "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 } } }, @@ -31944,26 +34079,59 @@ "debug": "4.3.4", "devtools-protocol": "0.0.1120988", "ws": "8.13.0" + }, + "dependencies": { + "@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dev": true, - "requires": { - "lowercase-keys": "^3.0.0" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" } }, "serialize-error": { @@ -31975,15 +34143,57 @@ "type-fest": "^2.12.2" } }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "safe-buffer": "~5.2.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "type-fest": { @@ -31993,40 +34203,35 @@ "dev": true }, "ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "optional": true, "peer": true }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true - }, "webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -32035,7 +34240,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "dependencies": { "@puppeteer/browsers": { @@ -32071,10 +34276,25 @@ "node-fetch": "^2.6.12" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true + }, + "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 }, "puppeteer-core": { @@ -32135,32 +34355,32 @@ } }, "zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, "requires": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" } } } }, "@wdio/cli": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.29.1.tgz", - "integrity": "sha512-WWRTf0g0O+ovTTvS1kEhZ/svX32M7jERuuMF1MaldKCi7rZwHsQqOyJD+fO1UDjuxqS96LHSGsZn0auwUfCTXA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.39.0.tgz", + "integrity": "sha512-kAd+8TYjJWRN6gZaRGiSu6Yj3k4+ULRt2NWAgNtGhnr0/Rwlr3j9bjAIhXGL574VqrH+rSnrevDdeGuLcZa1xg==", "dev": true, "requires": { "@types/node": "^20.1.1", "@vitest/snapshot": "^1.2.1", - "@wdio/config": "8.29.1", - "@wdio/globals": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/globals": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "async-exit-hook": "^2.0.1", "chalk": "^5.2.0", "chokidar": "^3.5.3", @@ -32173,85 +34393,78 @@ "lodash.flattendeep": "^4.4.0", "lodash.pickby": "^4.6.0", "lodash.union": "^4.6.0", - "read-pkg-up": "^10.0.0", + "read-pkg-up": "10.0.0", "recursive-readdir": "^2.2.3", - "webdriverio": "8.29.1", + "webdriverio": "8.39.0", "yargs": "^17.7.2" }, "dependencies": { - "@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, - "optional": true, - "peer": true, "requires": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" - }, - "dependencies": { - "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "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" - } - } + "@types/node": "^20.1.0" } }, - "@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true, - "optional": true, - "peer": true + "@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", + "dev": true, + "requires": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + } }, "archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, "requires": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" } }, "archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, "requires": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" + }, + "dependencies": { + "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 + } } }, "async": { @@ -32269,6 +34482,22 @@ "balanced-match": "^1.0.0" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true + }, "chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -32276,9 +34505,9 @@ "dev": true }, "chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, "optional": true, "peer": true, @@ -32290,25 +34519,34 @@ } }, "compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, "requires": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" + }, + "dependencies": { + "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 + } } }, "crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, "requires": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" } }, "cross-fetch": { @@ -32322,41 +34560,39 @@ "node-fetch": "^2.6.11" } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, "devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, "optional": true, "peer": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" - }, - "dependencies": { - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "isexe": "^3.1.1" - } - } } }, "devtools-protocol": { @@ -32367,18 +34603,6 @@ "optional": true, "peer": true }, - "edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -32404,63 +34628,12 @@ "strip-final-newline": "^3.0.0" } }, - "find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "requires": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - } - }, "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 }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "dependencies": { - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", - "dev": true, - "requires": { - "lru-cache": "^10.0.1" - }, - "dependencies": { - "lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true - } - } - }, "http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -32472,6 +34645,27 @@ "@tootallnate/once": "2", "agent-base": "6", "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, "is-stream": { @@ -32480,20 +34674,6 @@ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "optional": true, - "peer": true - }, - "json-parse-even-better-errors": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", - "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", - "dev": true - }, "lighthouse-logger": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.1.tgz", @@ -32504,36 +34684,14 @@ "requires": { "debug": "^2.6.9", "marky": "^1.2.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "ms": "2.0.0" - } - } } }, - "lines-and-columns": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", - "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "requires": { - "p-locate": "^6.0.0" - } - }, "mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -32541,9 +34699,9 @@ "dev": true }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -32566,22 +34724,10 @@ "whatwg-url": "^5.0.0" } }, - "normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", - "dev": true, - "requires": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - } - }, "npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "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, "requires": { "path-key": "^4.0.0" @@ -32596,51 +34742,6 @@ "mimic-fn": "^4.0.0" } }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "requires": { - "p-limit": "^4.0.0" - } - }, - "parse-json": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", - "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "error-ex": "^1.3.2", - "json-parse-even-better-errors": "^3.0.0", - "lines-and-columns": "^2.0.3", - "type-fest": "^3.8.0" - }, - "dependencies": { - "type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true - } - } - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true - }, "path-key": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", @@ -32664,18 +34765,27 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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, "requires": { "agent-base": "^7.1.0", @@ -32683,19 +34793,19 @@ } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "requires": { "agent-base": "^7.0.2", "debug": "4" } }, - "lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "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 } } @@ -32714,49 +34824,76 @@ "debug": "4.3.4", "devtools-protocol": "0.0.1120988", "ws": "8.13.0" - } - }, - "read-pkg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", - "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.1", - "normalize-package-data": "^6.0.0", - "parse-json": "^7.0.0", - "type-fest": "^4.2.0" - } - }, - "read-pkg-up": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz", - "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", - "dev": true, - "requires": { - "find-up": "^6.3.0", - "read-pkg": "^8.1.0", - "type-fest": "^4.2.0" + }, + "dependencies": { + "@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + }, + "yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "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" + } + } } }, "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "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==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" } }, "serialize-error": { @@ -32766,14 +34903,6 @@ "dev": true, "requires": { "type-fest": "^2.12.2" - }, - "dependencies": { - "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 - } } }, "signal-exit": { @@ -32782,60 +34911,95 @@ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, + "optional": true, + "peer": true, "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "type-fest": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.1.tgz", - "integrity": "sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true }, "ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", - "dev": true, - "optional": true, - "peer": true - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "optional": true, "peer": true }, "webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -32844,7 +35008,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "dependencies": { "@puppeteer/browsers": { @@ -32880,10 +35044,25 @@ "node-fetch": "^2.6.12" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true + }, + "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 }, "puppeteer-core": { @@ -32958,33 +35137,27 @@ "yargs-parser": "^21.1.1" } }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true - }, "zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, "requires": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" } } } }, "@wdio/concise-reporter": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/concise-reporter/-/concise-reporter-8.29.1.tgz", - "integrity": "sha512-dUhClWeq1naL1Qa1nSMDeH8aCVViOKiEzhBhQjgrMOz1Mh3l6O/woqbK2iKDVZDRhfGghtGcV0vpoEUvt8ZKOA==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/concise-reporter/-/concise-reporter-8.38.2.tgz", + "integrity": "sha512-wE36By4Z9iCtRzihpYrmCehsmNc8t3gHviBsUxV4tmYh/SQr+WX/dysWnojer6KWIJ2rT0rOzyQPmrwhdFKAFg==", "dev": true, "requires": { - "@wdio/reporter": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/reporter": "8.38.2", + "@wdio/types": "8.38.2", "chalk": "^5.0.1", "pretty-ms": "^7.0.1" }, @@ -32998,125 +35171,124 @@ } }, "@wdio/config": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.29.1.tgz", - "integrity": "sha512-zNUac4lM429HDKAitO+fdlwUH1ACQU8lww+DNVgUyuEb86xgVdTqHeiJr/3kOMJAq9IATeE7mDtYyyn6HPm1JA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.39.0.tgz", + "integrity": "sha512-yNuGPMPibY91s936gnJCHWlStvIyDrwLwGfLC/NCdTin4F7HL4Gp5iJnHWkJFty1/DfFi8jjoIUBNLM8HEez+A==", "dev": true, "requires": { - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "decamelize": "^6.0.0", "deepmerge-ts": "^5.0.0", "glob": "^10.2.2", "import-meta-resolve": "^4.0.0" }, "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true - }, - "glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "@types/node": "^20.1.0" } }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" + "@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", + "dev": true, + "requires": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" } } } }, "@wdio/globals": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.29.1.tgz", - "integrity": "sha512-F+fPnX75f44/crZDfQ2FYSino/IMIdbnQGLIkaH0VnoljVJIHuxnX4y5Zqr4yRgurL9DsZaH22cLHrPXaHUhPg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.39.0.tgz", + "integrity": "sha512-qZo6JjRCIOtdvba6fdSqj6b91TnWXD6rmamyud93FTqbcspnhBvr8lmgOs5wnslTKeeTTigCjpsT310b4/AyHA==", "dev": true, "requires": { - "expect-webdriverio": "^4.9.3", - "webdriverio": "8.29.1" + "expect-webdriverio": "^4.11.2", + "webdriverio": "8.39.0" }, "dependencies": { - "@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, "optional": true, - "peer": true, "requires": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" + "@types/node": "^20.1.0" } }, - "@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, "optional": true, - "peer": true + "requires": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + } }, "archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, "optional": true, "requires": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" } }, "archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, "optional": true, "requires": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "async": { @@ -33136,10 +35308,28 @@ "balanced-match": "^1.0.0" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "optional": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "optional": true + }, "chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, "optional": true, "peer": true, @@ -33151,27 +35341,28 @@ } }, "compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, "optional": true, "requires": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, "optional": true, "requires": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" } }, "cross-fetch": { @@ -33185,41 +35376,39 @@ "node-fetch": "^2.6.11" } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, "devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, "optional": true, "peer": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" - }, - "dependencies": { - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "isexe": "^3.1.1" - } - } } }, "devtools-protocol": { @@ -33230,18 +35419,6 @@ "optional": true, "peer": true }, - "edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -33250,32 +35427,6 @@ "optional": true, "peer": true }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "dependencies": { - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, "http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -33287,15 +35438,35 @@ "@tootallnate/once": "2", "agent-base": "6", "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "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, - "optional": true, - "peer": true + "optional": true }, "lighthouse-logger": { "version": "2.0.1", @@ -33307,19 +35478,6 @@ "requires": { "debug": "^2.6.9", "marky": "^1.2.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "ms": "2.0.0" - } - } } }, "lru-cache": { @@ -33330,9 +35488,9 @@ "optional": true }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "optional": true, "requires": { @@ -33375,19 +35533,29 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "optional": true, "requires": { "debug": "^4.3.4" } }, + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.1.2" + } + }, "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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, "optional": true, "requires": { @@ -33396,15 +35564,22 @@ } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "optional": true, "requires": { "agent-base": "^7.0.2", "debug": "4" } + }, + "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, + "optional": true } } }, @@ -33422,18 +35597,60 @@ "debug": "4.3.4", "devtools-protocol": "0.0.1120988", "ws": "8.13.0" + }, + "dependencies": { + "@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "optional": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" } }, "serialize-error": { @@ -33446,16 +35663,58 @@ "type-fest": "^2.12.2" } }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "optional": true, + "peer": true, "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "type-fest": { @@ -33466,43 +35725,36 @@ "optional": true }, "ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", - "dev": true, - "optional": true, - "peer": true - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "optional": true, "peer": true }, "webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, "optional": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -33511,7 +35763,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "dependencies": { "@puppeteer/browsers": { @@ -33550,10 +35802,27 @@ "node-fetch": "^2.6.12" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.1.2" + } + }, "devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true, + "optional": true + }, + "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, "optional": true }, @@ -33620,39 +35889,50 @@ } }, "zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, "optional": true, "requires": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" } } } }, "@wdio/local-runner": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.29.1.tgz", - "integrity": "sha512-Z3QAgxe1uQ97C7NS1CdMhgmHaLu/sbb47HTbw1yuuLk+SwsBIQGhNpTSA18QVRSUXq70G3bFvjACwqyap1IEQg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.39.0.tgz", + "integrity": "sha512-TSGJVVWqshH7IO13OKw7G/364q3FczZDEh4h6bYe+GAs91KpZrEhZanyALgjh5F3crWtlffX+GA2HUwpi8X0sA==", "dev": true, "requires": { "@types/node": "^20.1.0", - "@wdio/logger": "8.28.0", + "@wdio/logger": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/runner": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/runner": "8.39.0", + "@wdio/types": "8.39.0", "async-exit-hook": "^2.0.1", "split2": "^4.1.0", "stream-buffers": "^3.0.2" + }, + "dependencies": { + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", + "dev": true, + "requires": { + "@types/node": "^20.1.0" + } + } } }, "@wdio/logger": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.28.0.tgz", - "integrity": "sha512-/s6zNCqwy1hoc+K4SJypis0Ud0dlJ+urOelJFO1x0G0rwDRWyFiUP6ijTaCcFxAm29jYEcEPWijl2xkVIHwOyA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.38.0.tgz", + "integrity": "sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==", "dev": true, "requires": { "chalk": "^5.1.2", @@ -33661,47 +35941,32 @@ "strip-ansi": "^7.1.0" }, "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, "chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } } } }, "@wdio/mocha-framework": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.29.1.tgz", - "integrity": "sha512-R9dKMNqWgtUvZo33ORjUQV8Z/WLX5h/pg9u/xIvZSGXuNSw1h+5DWF6UiNFscxBFblL9UvBi6V9ila2LHgE4ew==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.38.2.tgz", + "integrity": "sha512-qJmRL5E6/ypjCUACH4hvCAAmTdU4YUrUlp9o/IKvTIAHMnZPE0/HgUFixCeu8Mop+rdzTPVBrbqxpRDdSnraYA==", "dev": true, "requires": { "@types/mocha": "^10.0.0", "@types/node": "^20.1.0", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.38.2", + "@wdio/utils": "8.38.2", "mocha": "^10.0.0" } }, "@wdio/protocols": { - "version": "8.24.12", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.24.12.tgz", - "integrity": "sha512-QnVj3FkapmVD3h2zoZk+ZQ8gevSj9D9MiIQIy8eOnY4FAneYZ9R9GvoW+mgNcCZO8S8++S/jZHetR8n+8Q808g==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.38.0.tgz", + "integrity": "sha512-7BPi7aXwUtnXZPeWJRmnCNFjyDvGrXlBmN9D4Pi58nILkyjVRQKEY9/qv/pcdyB0cvmIvw++Kl/1Lg+RxG++UA==", "dev": true }, "@wdio/repl": { @@ -33714,91 +35979,95 @@ } }, "@wdio/reporter": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.29.1.tgz", - "integrity": "sha512-LZeYHC+HHJRYiFH9odaotDazZh0zNhu4mTuL/T/e3c/Q3oPSQjLvfQYhB3Ece1QA9PKjP1VPmr+g9CvC0lMixA==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.38.2.tgz", + "integrity": "sha512-R78UdAtAnkaV22NYlCCcbPPhmYweiDURiw64LYhlVIQrKNuXUQcafR2kRlWKy31rZc9thSLs5LzrZDReENUlFQ==", "dev": true, "requires": { "@types/node": "^20.1.0", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.38.2", "diff": "^5.0.0", "object-inspect": "^1.12.0" } }, "@wdio/runner": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.29.1.tgz", - "integrity": "sha512-MvYFf4RgRmzxjAzy6nxvaDG1ycBRvoz772fT06csjxuaVYm57s8mlB8X+U1UQMx/IzujAb53fSeAmNcyU3FNEA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.39.0.tgz", + "integrity": "sha512-M1ixrrCtuwxHVzwsOKGMWBZCteafV0ztoS9+evMWGQtj0ZEsmhjAhWR3n2nZftt24vWOs+eNLGe2p+IO9Sm9bA==", "dev": true, "requires": { - "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/globals": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "deepmerge-ts": "^5.0.0", - "expect-webdriverio": "^4.9.3", - "gaze": "^1.1.2", - "webdriver": "8.29.1", - "webdriverio": "8.29.1" + "@types/node": "^20.11.28", + "@wdio/config": "8.39.0", + "@wdio/globals": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "deepmerge-ts": "^5.1.0", + "expect-webdriverio": "^4.12.0", + "gaze": "^1.1.3", + "webdriver": "8.39.0", + "webdriverio": "8.39.0" }, "dependencies": { - "@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, - "optional": true, - "peer": true, "requires": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" + "@types/node": "^20.1.0" } }, - "@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true, - "optional": true, - "peer": true + "@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", + "dev": true, + "requires": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + } }, "archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, "requires": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" } }, "archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, "requires": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "async": { @@ -33816,10 +36085,26 @@ "balanced-match": "^1.0.0" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true + }, "chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, "optional": true, "peer": true, @@ -33831,25 +36116,26 @@ } }, "compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, "requires": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, "requires": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" } }, "cross-fetch": { @@ -33863,41 +36149,39 @@ "node-fetch": "^2.6.11" } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, "devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, "optional": true, "peer": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" - }, - "dependencies": { - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "isexe": "^3.1.1" - } - } } }, "devtools-protocol": { @@ -33908,18 +36192,6 @@ "optional": true, "peer": true }, - "edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -33928,30 +36200,6 @@ "optional": true, "peer": true }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "dependencies": { - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, "http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -33963,15 +36211,34 @@ "@tootallnate/once": "2", "agent-base": "6", "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "optional": true, - "peer": true + "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 }, "lighthouse-logger": { "version": "2.0.1", @@ -33983,19 +36250,6 @@ "requires": { "debug": "^2.6.9", "marky": "^1.2.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "ms": "2.0.0" - } - } } }, "lru-cache": { @@ -34005,9 +36259,9 @@ "dev": true }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -34047,18 +36301,27 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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, "requires": { "agent-base": "^7.1.0", @@ -34066,14 +36329,20 @@ } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "requires": { "agent-base": "^7.0.2", "debug": "4" } + }, + "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 } } }, @@ -34091,17 +36360,59 @@ "debug": "4.3.4", "devtools-protocol": "0.0.1120988", "ws": "8.13.0" + }, + "dependencies": { + "@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" } }, "serialize-error": { @@ -34113,15 +36424,57 @@ "type-fest": "^2.12.2" } }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "safe-buffer": "~5.2.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "type-fest": { @@ -34131,42 +36484,35 @@ "dev": true }, "ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", - "dev": true, - "optional": true, - "peer": true - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "optional": true, "peer": true }, "webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -34175,7 +36521,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "dependencies": { "@puppeteer/browsers": { @@ -34211,10 +36557,25 @@ "node-fetch": "^2.6.12" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true + }, + "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 }, "puppeteer-core": { @@ -34275,26 +36636,26 @@ } }, "zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, "requires": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" } } } }, "@wdio/spec-reporter": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.29.1.tgz", - "integrity": "sha512-tuDHihrTjCxFCbSjT0jMvAarLA1MtatnCnhv0vguu3ZWXELR1uESX2KzBmpJ+chGZz3oCcKszT8HOr6Pg2a1QA==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.38.2.tgz", + "integrity": "sha512-Dntk+lmrp+0I3HRRWkkXED+smshvgsW5cdLKwJhEJ1liI48MdBpdNGf9IHTVckE6nfxcWDyFI4icD9qYv/5bFA==", "dev": true, "requires": { - "@wdio/reporter": "8.29.1", - "@wdio/types": "8.29.1", + "@wdio/reporter": "8.38.2", + "@wdio/types": "8.38.2", "chalk": "^5.1.2", "easy-table": "^1.2.0", "pretty-ms": "^7.0.0" @@ -34309,193 +36670,185 @@ } }, "@wdio/types": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.29.1.tgz", - "integrity": "sha512-rZYzu+sK8zY1PjCEWxNu4ELJPYKDZRn7HFcYNgR122ylHygfldwkb5TioI6Pn311hQH/S+663KEeoq//Jb0f8A==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.38.2.tgz", + "integrity": "sha512-+wj1c1OSLdnN4WO5b44Ih4263dTl/eSwMGSI4/pCgIyXIuYQH38JQ+6WRa+c8vJEskUzboq2cSgEQumVZ39ozQ==", "dev": true, "requires": { "@types/node": "^20.1.0" } }, "@wdio/utils": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.29.1.tgz", - "integrity": "sha512-Dm91DKL/ZKeZ2QogWT8Twv0p+slEgKyB/5x9/kcCG0Q2nNa+tZedTjOhryzrsPiWc+jTSBmjGE4katRXpJRFJg==", + "version": "8.38.2", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.38.2.tgz", + "integrity": "sha512-y5AnBwsGcu/XuCBGCgKmlvKdwEIFyzLA+Cr+denySxY3jbWDONtPUcGaVdFALwsIa5jcIjcATqGmZcCPGnkd7g==", "dev": true, "requires": { "@puppeteer/browsers": "^1.6.0", - "@wdio/logger": "8.28.0", - "@wdio/types": "8.29.1", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.38.2", "decamelize": "^6.0.0", "deepmerge-ts": "^5.1.0", - "edgedriver": "^5.3.5", - "geckodriver": "^4.2.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", "get-port": "^7.0.0", "import-meta-resolve": "^4.0.0", "locate-app": "^2.1.0", "safaridriver": "^0.1.0", "split2": "^4.2.0", "wait-port": "^1.0.4" - }, - "dependencies": { - "decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true - } } }, "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, "@xmldom/xmldom": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.8.tgz", - "integrity": "sha512-PrJx38EfpitFhwmILRl37jAdBlsww6AZ6rRVK4QS7T7RHLhX7mSs647sTmgr9GIxe3qjXdesmomEgbgaokrVFg==", + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", "dev": true }, "@xtuc/ieee754": { @@ -34510,12 +36863,27 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "@zip.js/zip.js": { + "version": "2.7.45", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.45.tgz", + "integrity": "sha512-Mm2EXF33DJQ/3GWWEWeP1UCqzpQ5+fiMvT3QWspsXY05DyqqxWu7a9awSzU4/spHMHVFrTjani1PR0vprgZpow==", + "dev": true + }, "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", "dev": true }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -34539,9 +36907,9 @@ "requires": {} }, "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true }, "aes-decrypter": { @@ -34653,9 +37021,9 @@ "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==" }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -34672,36 +37040,49 @@ } }, "archiver": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", - "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, "requires": { "archiver-utils": "^2.1.0", - "async": "^3.2.3", + "async": "^3.2.4", "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", + "readdir-glob": "^1.1.2", "tar-stream": "^2.2.0", "zip-stream": "^4.1.0" }, "dependencies": { "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "dev": true }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } } } }, @@ -34721,6 +37102,22 @@ "lodash.union": "^4.6.0", "normalize-path": "^3.0.0", "readable-stream": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + } } }, "archy": { @@ -34729,6 +37126,12 @@ "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, + "are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -34738,12 +37141,12 @@ } }, "aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "requires": { - "deep-equal": "^2.0.5" + "dequal": "^2.0.3" } }, "arr-diff": { @@ -34794,6 +37197,16 @@ "integrity": "sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA==", "dev": true }, + "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, + "requires": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + } + }, "array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", @@ -34818,15 +37231,16 @@ "dev": true }, "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" } }, @@ -34894,18 +37308,60 @@ "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true }, + "array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + } + }, "array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, + "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, + "requires": { + "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" + } + }, "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -34916,15 +37372,16 @@ } }, "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", "dev": true, "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" } }, "assert-plus": { @@ -34954,9 +37411,9 @@ }, "dependencies": { "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true } } @@ -34986,9 +37443,9 @@ } }, "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", "dev": true }, "async-exit-hook": { @@ -35019,10 +37476,13 @@ "dev": true }, "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 + "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, + "requires": { + "possible-typed-array-names": "^1.0.0" + } }, "aws-sign2": { "version": "0.7.0", @@ -35031,15 +37491,15 @@ "dev": true }, "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", "dev": true }, "b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", "dev": true }, "babel-code-frame": { @@ -35128,6 +37588,12 @@ "source-map": "^0.5.7" }, "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -35186,9 +37652,9 @@ } }, "babel-loader": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", - "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "dev": true, "requires": { "find-cache-dir": "^3.3.1", @@ -35220,30 +37686,30 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" } }, "babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.6.2" } }, "babel-register": { @@ -35266,15 +37732,6 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", "dev": true - }, - "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, - "requires": { - "minimist": "^1.2.6" - } } } }, @@ -35410,6 +37867,52 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true + }, + "bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "dev": true, + "optional": true, + "requires": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "bare-os": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.3.0.tgz", + "integrity": "sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg==", + "dev": true, + "optional": true + }, + "bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "requires": { + "bare-os": "^2.1.0" + } + }, + "bare-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", + "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "dev": true, + "optional": true, + "requires": { + "streamx": "^2.18.0" + } + }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", @@ -35466,9 +37969,9 @@ } }, "basic-ftp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.4.tgz", - "integrity": "sha512-8PzkB0arJFV4jJWSGOYR+OEic6aeKMu/osRhBULN6RY0ykby6LKhbmuQ5ublvaas5BOwboah5D87nrHyuh8PPA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true }, "batch": { @@ -35493,9 +37996,9 @@ "dev": true }, "big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", "dev": true }, "big.js": { @@ -35515,9 +38018,9 @@ } }, "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true }, "binaryextensions": { @@ -35548,9 +38051,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -35561,9 +38064,9 @@ } }, "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "body": { "version": "5.1.0", @@ -35652,12 +38155,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-stdout": { @@ -35667,14 +38170,14 @@ "dev": true }, "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" } }, "browserstack": { @@ -35717,9 +38220,9 @@ } }, "browserstack-local": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.1.tgz", - "integrity": "sha512-T/wxyWDzvBHbDvl7fZKpFU7mYze6nrUkBhNy+d+8bXBqgQX10HTYvajIGO0wb49oGSLCPM0CMZTV/s7e6LF0sA==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.5.tgz", + "integrity": "sha512-jKne7yosrMcptj3hqxp36TP9k0ZW2sCqhyurX24rUL4G3eT7OLgv+CSQN8iq5dtkv5IK+g+v8fWvsiC/S9KxMg==", "dev": true, "requires": { "agent-base": "^6.0.2", @@ -35863,45 +38366,44 @@ } }, "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "dev": true }, "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", "dev": true, "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" }, "dependencies": { "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "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 } } }, "call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -35923,9 +38425,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001429", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz", - "integrity": "sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg==" + "version": "1.0.30001633", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001633.tgz", + "integrity": "sha512-6sT0yf/z5jqf8tISAgpJDrmwOpLsrpnyCdD/lOZKvKkkJK4Dn0X5i7KF7THEZhOq+30bmhwBlNEaqPUiHiKtZg==" }, "caseless": { "version": "0.12.0", @@ -35940,18 +38442,18 @@ "dev": true }, "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "requires": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" } }, "chainsaw": { @@ -35998,15 +38500,18 @@ "dev": true }, "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "requires": { + "get-func-name": "^2.0.2" + } }, "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -36026,9 +38531,9 @@ "dev": true }, "chrome-launcher": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.1.tgz", - "integrity": "sha512-UugC8u59/w2AyX5sHLZUHoxBAiSiunUhZa3zZwMH6zPVis0C3dDKiRWyUGIo14tTbZHGVviWxv3PQWZ7taZ4fg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", "dev": true, "requires": { "@types/node": "*", @@ -36046,9 +38551,9 @@ } }, "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true }, "chromium-bidi": { @@ -36095,61 +38600,14 @@ "is-descriptor": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } } } @@ -36170,9 +38628,9 @@ "dev": true }, "cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true }, "cliui": { @@ -36184,6 +38642,52 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } } }, "clone": { @@ -36205,6 +38709,14 @@ "dev": true, "requires": { "mimic-response": "^1.0.0" + }, + "dependencies": { + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + } } }, "clone-stats": { @@ -36286,9 +38798,9 @@ } }, "comma-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", - "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "dev": true }, "commander": { @@ -36298,9 +38810,9 @@ "dev": true }, "comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true }, "commondir": { @@ -36310,15 +38822,15 @@ "dev": true }, "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true }, "compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, "requires": { "buffer-crc32": "^0.2.13", @@ -36328,9 +38840,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -36468,9 +38980,9 @@ "dev": true }, "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "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==" }, "cookie": { "version": "0.6.0", @@ -36499,22 +39011,22 @@ } }, "core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==" + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==" }, "core-js-compat": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", - "integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "requires": { - "browserslist": "^4.21.4" + "browserslist": "^4.23.0" } }, "core-js-pure": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.0.tgz", - "integrity": "sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==" + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", + "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==" }, "core-util-is": { "version": "1.0.3", @@ -36551,9 +39063,9 @@ "dev": true }, "crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, "requires": { "crc-32": "^1.2.0", @@ -36561,9 +39073,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -36573,11 +39085,6 @@ } } }, - "criteo-direct-rsa-validate": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/criteo-direct-rsa-validate/-/criteo-direct-rsa-validate-1.1.0.tgz", - "integrity": "sha512-7gQ3zX+d+hS/vOxzLrZ4aRAceB7qNJ0VzaGNpcWjDCmtOpASB50USJDupTik/H2nHgiSAA3VNZ3SFuONs8LR9Q==" - }, "cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", @@ -36585,6 +39092,17 @@ "dev": true, "requires": { "node-fetch": "2.6.7" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + } } }, "cross-spawn": { @@ -36596,6 +39114,23 @@ "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "crypto-js": { @@ -36666,13 +39201,13 @@ "dev": true }, "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", "dev": true, "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "es5-ext": "^0.10.64", + "type": "^2.7.2" } }, "dashdash": { @@ -36685,11 +39220,44 @@ } }, "data-uri-to-buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz", - "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true }, + "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, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "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, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "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, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, "date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -36709,10 +39277,16 @@ "dev": true, "optional": true }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "requires": { "ms": "2.1.2" } @@ -36740,9 +39314,9 @@ } }, "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", "dev": true }, "decode-named-character-reference": { @@ -36778,35 +39352,38 @@ } }, "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "requires": { "type-detect": "^4.0.0" } }, "deep-equal": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz", - "integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "es-get-iterator": "^1.1.1", - "get-intrinsic": "^1.0.1", - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.2", - "is-regex": "^1.1.1", + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", "isarray": "^2.0.5", - "object-is": "^1.1.4", + "object-is": "^1.1.5", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3", - "which-boxed-primitive": "^1.0.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", "which-collection": "^1.0.1", - "which-typed-array": "^1.1.2" + "which-typed-array": "^1.1.13" } }, "deep-is": { @@ -36816,9 +39393,9 @@ "dev": true }, "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, "deepmerge-ts": { @@ -36866,21 +39443,22 @@ "dev": true }, "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "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==", "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" } }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "requires": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } @@ -36983,49 +39561,74 @@ "dev": true }, "devtools": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.25.4.tgz", - "integrity": "sha512-R6/S/dCqxoX4Y6PxIGM9JFAuSRZzUeV5r+CoE/frhmno6mTe7dEEgwkJlfit3LkKRoul8n4DsL2A3QtWOvq5IA==", + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.35.0.tgz", + "integrity": "sha512-7HMZMcJSCK/PaBCWVs4n4ZhtBNdUQj10iPwXvj/JDkqPreEXN/XW9GJAoMuLPFmCEKfxe+LrIbgs8ocGJ6rp/A==", "dev": true, "requires": { "@types/node": "^18.0.0", "@types/ua-parser-js": "^0.7.33", - "@wdio/config": "7.25.4", - "@wdio/logger": "7.19.0", - "@wdio/protocols": "7.22.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@wdio/config": "7.33.0", + "@wdio/logger": "7.26.0", + "@wdio/protocols": "7.27.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "chrome-launcher": "^0.15.0", "edge-paths": "^2.1.0", - "puppeteer-core": "^13.1.3", + "puppeteer-core": "13.1.3", "query-selector-shadow-dom": "^1.0.0", "ua-parser-js": "^1.0.1", "uuid": "^9.0.0" }, "dependencies": { + "@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 + }, + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, "@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "version": "18.19.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", + "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/which": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", + "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", "dev": true }, "@wdio/config": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.25.4.tgz", - "integrity": "sha512-vb0emDtD9FbFh/yqW6oNdo2iuhQp8XKj6GX9fyy9v4wZgg3B0HPMVJxhIfcoHz7LMBWlHSo9YdvhFI5EQHRLBA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.33.0.tgz", + "integrity": "sha512-SaCZNKrDtBghf7ujyaxTiU4pBW+1Kms32shSoXpJ/wFop6/MiA7nb19qpUPoJtEDw5/NOKevUKz8nBMBXphiew==", "dev": true, "requires": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@types/glob": "^8.1.0", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "deepmerge": "^4.0.0", "glob": "^8.0.3" } }, "@wdio/logger": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.19.0.tgz", - "integrity": "sha512-xR7SN/kGei1QJD1aagzxs3KMuzNxdT/7LYYx+lt6BII49+fqL/SO+5X0FDCZD0Ds93AuQvvz9eGyzrBI2FFXmQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", + "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -37035,15 +39638,15 @@ } }, "@wdio/protocols": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.22.0.tgz", - "integrity": "sha512-8EXRR+Ymdwousm/VGtW3H1hwxZ/1g1H99A1lF0U4GuJ5cFWHCd0IVE5H31Z52i8ZruouW8jueMkGZPSo2IIUSQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", + "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", "dev": true }, "@wdio/types": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.25.4.tgz", - "integrity": "sha512-muvNmq48QZCvocctnbe0URq2FjJjUPIG4iLoeMmyF0AQgdbjaUkMkw3BHYNHVTbSOU9WMsr2z8alhj/I2H6NRQ==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.33.0.tgz", + "integrity": "sha512-tNcuN5Kl+i5CffaeTYV1omzAo4rVjiI1m9raIA8ph6iVteWdCzYv2/ImpGgFiBPb7Mf6VokU3+q9Slh5Jitaww==", "dev": true, "requires": { "@types/node": "^18.0.0", @@ -37051,13 +39654,13 @@ } }, "@wdio/utils": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.25.4.tgz", - "integrity": "sha512-8iwQDk+foUqSzKZKfhLxjlCKOkfRJPNHaezQoevNgnrTq/t0ek+ldZCATezb9B8jprAuP4mgS9xi22akc6RkzA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.33.0.tgz", + "integrity": "sha512-4kQQ86EvEN6fBY5+u7M08cT6LfJtpk1rHd203xyxmbmV9lpNv/OCl4CsC+SD0jGT0aZZqYSIJ/Pil07pAh5K0g==", "dev": true, "requires": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", "p-iteration": "^1.1.8" } }, @@ -37079,6 +39682,27 @@ "balanced-match": "^1.0.0" } }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true + }, + "cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -37104,10 +39728,44 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "devtools-protocol": { + "version": "0.0.948846", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.948846.tgz", + "integrity": "sha512-5fGyt9xmMqUl2VI7+rnUkKCiAQIpLns8sfQtTENy5L70ktbNw0Z3TFJ1JoFNYdx/jffz4YXU45VF75wKZD7sZQ==", + "dev": true + }, + "edge-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", + "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", + "dev": true, + "requires": { + "@types/which": "^1.3.2", + "which": "^2.0.2" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -37117,21 +39775,142 @@ "once": "^1.3.0" } }, + "got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + } + }, "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 }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true + }, + "puppeteer-core": { + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.1.3.tgz", + "integrity": "sha512-96pzvVBzq5lUGt3L/QrIH3mxn3NfZylHeusNhq06xBAHPI0Upc0SC/9u7tXjL0oRnmcExeVRJivr1lj7Ah/yDQ==", + "dev": true, + "requires": { + "debug": "4.3.2", + "devtools-protocol": "0.0.948846", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "node-fetch": "2.6.7", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.2.3" + } + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -37141,24 +39920,59 @@ "has-flag": "^4.0.0" } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "ua-parser-js": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", - "integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true }, - "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "dev": true, + "requires": {} } } }, "devtools-protocol": { - "version": "0.0.1061995", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1061995.tgz", - "integrity": "sha512-pKZZWTjWa/IF4ENCg6GN8bu/AxSZgdhjSa26uc23wz38Blt2Tnm9icOPcSG3Cht55rMq35in1w3rWVPcZ60ArA==", + "version": "0.0.1260888", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1260888.tgz", + "integrity": "sha512-9rTIZ4ZjWwalCPiaY+kPiALLfOKgAz5CTi/Zb1L+qSZ8PH3zVo1T8JcgXIIqg1iM3pZ6hF+n9xO5r2jZ/SF+jg==", "dev": true }, "di": { @@ -37168,9 +39982,9 @@ "dev": true }, "diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true }, "diff-sequences": { @@ -37203,9 +40017,9 @@ } }, "documentation": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/documentation/-/documentation-14.0.1.tgz", - "integrity": "sha512-Y/brACCE3sNnDJPFiWlhXrqGY+NelLYVZShLGse5bT1KdohP4JkPf5T2KNq1YWhIEbDYl/1tebRLC0WYbPQxVw==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/documentation/-/documentation-14.0.3.tgz", + "integrity": "sha512-B7cAviVKN9Rw7Ofd+9grhVuxiHwly6Ieh+d/ceMw8UdBOv/irkuwnDEJP8tq0wgdLJDUVuIkovV+AX9mTrZFxg==", "dev": true, "requires": { "@babel/core": "^7.18.10", @@ -37265,15 +40079,25 @@ } }, "chalk": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", - "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true }, + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -37283,6 +40107,15 @@ "once": "^1.3.0" } }, + "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, + "requires": { + "lru-cache": "^6.0.0" + } + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -37292,19 +40125,138 @@ "argparse": "^2.0.1" } }, + "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 + }, + "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 + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "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, + "requires": { + "yallist": "^4.0.0" + } + }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } }, + "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, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "read-pkg": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-7.1.0.tgz", + "integrity": "sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.1", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-9.1.0.tgz", + "integrity": "sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==", + "dev": true, + "requires": { + "find-up": "^6.3.0", + "read-pkg": "^7.1.0", + "type-fest": "^2.5.0" + } + }, + "semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + }, + "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 + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { "cliui": "^8.0.1", @@ -37313,7 +40265,7 @@ "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" } } } @@ -37374,9 +40326,9 @@ } }, "dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "dev": true }, "dset": { @@ -37426,21 +40378,21 @@ } }, "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "dev": true, "requires": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "stream-shift": "^1.0.2" }, "dependencies": { "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -37495,128 +40447,57 @@ "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" + }, + "dependencies": { + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + } } }, "edge-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", - "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", + "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", "dev": true, "requires": { - "@types/which": "^1.3.2", + "@types/which": "^2.0.1", "which": "^2.0.2" - } - }, - "edgedriver": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.3.9.tgz", - "integrity": "sha512-G0wNgFMFRDnFfKaXG2R6HiyVHqhKwdQ3EgoxW3wPlns2wKqem7F+HgkWBcevN7Vz0nN4AXtskID7/6jsYDXcKw==", - "dev": true, - "requires": { - "@wdio/logger": "^8.16.17", - "decamelize": "^6.0.0", - "edge-paths": "^3.0.5", - "node-fetch": "^3.3.2", - "unzipper": "^0.10.14", - "which": "^4.0.0" }, "dependencies": { - "@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true - }, - "data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true - }, - "decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "requires": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, - "unzipper": { - "version": "0.10.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", - "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", - "dev": true, - "requires": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "isexe": "^3.1.1" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true - } + "isexe": "^2.0.0" } } } }, + "edgedriver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.6.0.tgz", + "integrity": "sha512-IeJXEczG+DNYBIa9gFgVYTqrawlxmc9SUqUsWU2E98jOsO/amA7wzabKOS8Bwgr/3xWoyXCJ6yGFrbFKrilyyQ==", + "dev": true, + "requires": { + "@wdio/logger": "^8.28.0", + "@zip.js/zip.js": "^2.7.44", + "decamelize": "^6.0.0", + "edge-paths": "^3.0.5", + "node-fetch": "^3.3.2", + "which": "^4.0.0" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -37632,9 +40513,9 @@ } }, "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + "version": "1.4.802", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.802.tgz", + "integrity": "sha512-TnTMUATbgNdPXVSHsxvNVSG0uEd6cSZsANjm8c9HbvflZVVn1yTRcmVXYT1Ma95/ssB/Dcd30AHweH2TE+dNpA==" }, "emoji-regex": { "version": "8.0.0", @@ -37663,9 +40544,9 @@ } }, "engine.io": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", - "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -37676,8 +40557,8 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.11.0" + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" }, "dependencies": { "cookie": { @@ -37689,15 +40570,15 @@ } }, "engine.io-parser": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", - "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", "dev": true }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -37705,12 +40586,24 @@ } }, "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, "requires": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "ent": { @@ -37753,66 +40646,122 @@ } }, "es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", + "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, + "requires": { + "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-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "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", - "internal-slot": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "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.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "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" + } + }, + "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==", + "requires": { + "get-intrinsic": "^1.2.4" } }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, "es-get-iterator": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", - "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.0", - "has-symbols": "^1.0.1", - "is-arguments": "^1.1.0", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", "is-map": "^2.0.2", "is-set": "^2.0.2", - "is-string": "^1.0.5", - "isarray": "^2.0.5" + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" } }, "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", + "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", "dev": true }, - "es-shim-unscopables": { + "es-object-atoms": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" + } + }, + "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, + "requires": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + } + }, + "es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "es-to-primitive": { @@ -37827,13 +40776,14 @@ } }, "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "dev": true, "requires": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" } }, @@ -37854,12 +40804,6 @@ "es6-symbol": "^3.1.1" } }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -37875,13 +40819,13 @@ } }, "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", "dev": true, "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" + "d": "^1.0.2", + "ext": "^1.7.0" } }, "es6-weak-map": { @@ -37897,9 +40841,9 @@ } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" }, "escape-html": { "version": "1.0.3", @@ -38079,9 +41023,9 @@ "dev": true }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -38094,12 +41038,18 @@ "dev": true }, "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==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "ansi-regex": "^5.0.1" } }, "strip-json-comments": { @@ -38133,13 +41083,14 @@ "requires": {} }, "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "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, "requires": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" }, "dependencies": { "debug": { @@ -38154,9 +41105,9 @@ } }, "eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "requires": { "debug": "^3.2.7" @@ -38184,33 +41135,37 @@ } }, "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "doctrine": { @@ -38221,29 +41176,25 @@ "requires": { "esutils": "^2.0.2" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true } } }, "eslint-plugin-jsdoc": { - "version": "38.1.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-38.1.6.tgz", - "integrity": "sha512-n4s95oYlg0L43Bs8C0dkzIldxYf8pLCutC/tCbjIdF7VDiobuzPI+HZn9Q0BvgOvgPNgh5n7CSStql25HUG4Tw==", + "version": "48.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.5.0.tgz", + "integrity": "sha512-ukXPNpGby3KjCveCizIS8t1EbuJEHYEu/tBg8GCbn/YbHcXwphyvYCdvRZ/oMRfTscGSSzfsWoZ+ZkAP0/6YMQ==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "~0.22.1", - "comment-parser": "1.3.1", + "@es-joy/jsdoccomment": "~0.43.1", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", - "regextras": "^0.8.0", - "semver": "^7.3.5", - "spdx-expression-parse": "^3.0.1" + "esquery": "^1.5.0", + "parse-imports": "^2.1.0", + "semver": "^7.6.2", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.0" }, "dependencies": { "escape-string-regexp": { @@ -38253,12 +41204,19 @@ "dev": true }, "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==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + }, + "spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } } } @@ -38278,9 +41236,9 @@ }, "dependencies": { "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true } } @@ -38335,6 +41293,18 @@ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, + "esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + } + }, "espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -38361,9 +41331,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -38450,6 +41420,12 @@ } } }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true + }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -38490,6 +41466,12 @@ "which": "^1.2.9" } }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -38570,61 +41552,14 @@ "is-extendable": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } }, "is-extendable": { @@ -38664,76 +41599,82 @@ } }, "expect-webdriverio": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-4.9.3.tgz", - "integrity": "sha512-ASHsFc/QaK5ipF4ct3e8hd3elm8wNXk/Qa3EemtYDmfUQ4uzwqDf75m/QFQpwVNCjEpkNP7Be/6X9kz7bN0P9Q==", + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-4.15.1.tgz", + "integrity": "sha512-xtBSidt7Whs1fsUC+utxVzfmkmaStXWW17b+BcMCiCltx0Yku6l7BTv1Y14DEKX8L6rttaDQobYyRtBKbi4ssg==", "dev": true, "requires": { - "@vitest/snapshot": "^1.2.1", - "@wdio/globals": "^8.27.0", - "@wdio/logger": "^8.24.12", + "@vitest/snapshot": "^1.2.2", + "@wdio/globals": "^8.29.3", + "@wdio/logger": "^8.28.0", "expect": "^29.7.0", "jest-matcher-utils": "^29.7.0", "lodash.isequal": "^4.5.0", - "webdriverio": "^8.27.0" + "webdriverio": "^8.29.3" }, "dependencies": { - "@puppeteer/browsers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", - "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, "optional": true, - "peer": true, "requires": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "http-proxy-agent": "5.0.0", - "https-proxy-agent": "5.0.1", - "progress": "2.0.3", - "proxy-from-env": "1.1.0", - "tar-fs": "2.1.1", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.1" + "@types/node": "^20.1.0" } }, - "@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", + "@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", "dev": true, "optional": true, - "peer": true + "requires": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + } }, "archiver": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", - "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "dev": true, "optional": true, "requires": { - "archiver-utils": "^4.0.1", + "archiver-utils": "^5.0.2", "async": "^3.2.4", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", - "zip-stream": "^5.0.1" + "zip-stream": "^6.0.1" } }, "archiver-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", - "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "dev": true, "optional": true, "requires": { - "glob": "^8.0.0", + "glob": "^10.0.0", "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "async": { @@ -38753,10 +41694,28 @@ "balanced-match": "^1.0.0" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "optional": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "optional": true + }, "chrome-launcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.0.tgz", - "integrity": "sha512-rJYWeEAERwWIr3c3mEVXwNiODPEdMRlRxHc47B1qHPOolHZnkj7rMv1QSUfPoG6MgatWj5AxSpnKKR4QEwEQIQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz", + "integrity": "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw==", "dev": true, "optional": true, "peer": true, @@ -38768,27 +41727,28 @@ } }, "compress-commons": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", - "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, "optional": true, "requires": { "crc-32": "^1.2.0", - "crc32-stream": "^5.0.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" + "readable-stream": "^4.0.0" } }, "crc32-stream": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", - "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, "optional": true, "requires": { "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" + "readable-stream": "^4.0.0" } }, "cross-fetch": { @@ -38802,41 +41762,39 @@ "node-fetch": "^2.6.11" } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, "devtools": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.29.1.tgz", - "integrity": "sha512-fbH0Z7CPK4OZSgUw2QcAppczowxtSyvFztPUmiFyi99cUadjEOwlg0aL3pBVlIDo67olYjGb8GD1M5Z4yI/P6w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.39.0.tgz", + "integrity": "sha512-QNbvNTNQMlU5gZqbmqzF92vfMOP/Eaa8KcvRj87M0jbn3dfwOeBC7WiECPFQ0MAfmynfarK7G7Ec+TfbAAEyNQ==", "dev": true, "optional": true, "peer": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "chrome-launcher": "^1.0.0", "edge-paths": "^3.0.5", "import-meta-resolve": "^4.0.0", "puppeteer-core": "20.3.0", "query-selector-shadow-dom": "^1.0.0", - "ua-parser-js": "^1.0.1", + "ua-parser-js": "^1.0.37", "uuid": "^9.0.0", "which": "^4.0.0" - }, - "dependencies": { - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "isexe": "^3.1.1" - } - } } }, "devtools-protocol": { @@ -38847,18 +41805,6 @@ "optional": true, "peer": true }, - "edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@types/which": "^2.0.1", - "which": "^2.0.2" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -38867,32 +41813,6 @@ "optional": true, "peer": true }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "dependencies": { - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, "http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -38904,15 +41824,35 @@ "@tootallnate/once": "2", "agent-base": "6", "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "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, - "optional": true, - "peer": true + "optional": true }, "lighthouse-logger": { "version": "2.0.1", @@ -38924,19 +41864,6 @@ "requires": { "debug": "^2.6.9", "marky": "^1.2.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "ms": "2.0.0" - } - } } }, "lru-cache": { @@ -38947,9 +41874,9 @@ "optional": true }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "optional": true, "requires": { @@ -38992,19 +41919,29 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "optional": true, "requires": { "debug": "^4.3.4" } }, + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.1.2" + } + }, "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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, "optional": true, "requires": { @@ -39013,15 +41950,22 @@ } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "optional": true, "requires": { "agent-base": "^7.0.2", "debug": "4" } + }, + "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, + "optional": true } } }, @@ -39039,18 +41983,60 @@ "debug": "4.3.4", "devtools-protocol": "0.0.1120988", "ws": "8.13.0" + }, + "dependencies": { + "@puppeteer/browsers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.3.0.tgz", + "integrity": "sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "http-proxy-agent": "5.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "ms": "2.1.2" + } + }, + "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, + "optional": true, + "peer": true + } } }, "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "optional": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" } }, "serialize-error": { @@ -39063,16 +42049,58 @@ "type-fest": "^2.12.2" } }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dev": true, "optional": true, + "peer": true, "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "type-fest": { @@ -39083,43 +42111,36 @@ "optional": true }, "ua-parser-js": { - "version": "1.0.37", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz", - "integrity": "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==", - "dev": true, - "optional": true, - "peer": true - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", "dev": true, "optional": true, "peer": true }, "webdriverio": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.29.1.tgz", - "integrity": "sha512-NZK95ivXCqdPraB3FHMw6ByxnCvtgFXkjzG2l3Oq5z0IuJS2aMow3AKFIyiuG6is/deGCe+Tb8eFTCqak7UV+w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.0.tgz", + "integrity": "sha512-pDpGu0V+TL1LkXPode67m3s+IPto4TcmcOzMpzFgu2oeLMBornoLN3yQSFR1fjZd1gK4UfnG3lJ4poTGOfbWfw==", "dev": true, "optional": true, "requires": { "@types/node": "^20.1.0", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", "@wdio/repl": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", - "archiver": "^6.0.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", + "archiver": "^7.0.0", "aria-query": "^5.0.0", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1249869", + "devtools-protocol": "^0.0.1302984", "grapheme-splitter": "^1.0.2", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", + "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "minimatch": "^9.0.0", @@ -39128,7 +42149,7 @@ "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^11.0.1", - "webdriver": "8.29.1" + "webdriver": "8.39.0" }, "dependencies": { "@puppeteer/browsers": { @@ -39167,10 +42188,27 @@ "node-fetch": "^2.6.12" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.1.2" + } + }, "devtools-protocol": { - "version": "0.0.1249869", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", - "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==", + "version": "0.0.1302984", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", + "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "dev": true, + "optional": true + }, + "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, "optional": true }, @@ -39237,15 +42275,15 @@ } }, "zip-stream": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", - "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, "optional": true, "requires": { - "archiver-utils": "^4.0.1", - "compress-commons": "^5.0.1", - "readable-stream": "^3.6.0" + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" } } } @@ -39310,14 +42348,6 @@ "dev": true, "requires": { "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } } }, "extend": { @@ -39352,6 +42382,17 @@ "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + } } }, "extglob": { @@ -39416,6 +42457,16 @@ "requires": { "pump": "^3.0.0" } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } } } }, @@ -39502,20 +42553,29 @@ }, "dependencies": { "web-streams-polyfill": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", - "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true } } }, "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + }, + "dependencies": { + "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 + } } }, "file-entry-cache": { @@ -39564,9 +42624,9 @@ } }, "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==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -39632,151 +42692,6 @@ "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - } - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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 - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } } }, "fined": { @@ -39816,19 +42731,20 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "flush-write-stream": { @@ -39878,9 +42794,9 @@ "dev": true }, "foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -39975,14 +42891,29 @@ "dev": true }, "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz", + "integrity": "sha512-5rU898vl/Z948L+kkJedbmo/iltzmiF5bn/eEk0j/SgrPpI+Ydau9xlJPicV7Av2CHYBGz5LAlwTnBU80j1zPQ==", "dev": true, "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "jsonfile": "~1.0.1", + "mkdirp": "0.3.x", + "ncp": "~0.4.2", + "rimraf": "~2.2.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha512-8OCq0De/h9ZxseqzCH8Kw/Filf5pF/vMI6+BH7Lu0jXz2pqYCjTAQRolSxRIi+Ax+oCCjlxoJMP0YQ4XlrQNHg==", + "dev": true + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha512-R5KMKHnPAQaZMqLOsyuyUmcIjSeDm+73eoqQpaXA7AZ22BL+6C+1mcUscgOsNd8WVlJuvlgAPsegcx7pjlV0Dg==", + "dev": true + } } }, "fs-mkdirp-stream": { @@ -40026,35 +42957,11 @@ "walk": "^2.3.9" }, "dependencies": { - "fs-extra": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz", - "integrity": "sha512-5rU898vl/Z948L+kkJedbmo/iltzmiF5bn/eEk0j/SgrPpI+Ydau9xlJPicV7Av2CHYBGz5LAlwTnBU80j1zPQ==", - "dev": true, - "requires": { - "jsonfile": "~1.0.1", - "mkdirp": "0.3.x", - "ncp": "~0.4.2", - "rimraf": "~2.2.0" - } - }, - "jsonfile": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz", - "integrity": "sha512-KbsDJNRfRPF5v49tMNf9sqyyGqGLBcz1v5kZT01kG5ns5mQSltwxCKVmUzVKtEinkUnTDtSrp6ngWpV7Xw0ZlA==", - "dev": true - }, "mkdirp": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", "integrity": "sha512-8OCq0De/h9ZxseqzCH8Kw/Filf5pF/vMI6+BH7Lu0jXz2pqYCjTAQRolSxRIi+Ax+oCCjlxoJMP0YQ4XlrQNHg==", "dev": true - }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha512-R5KMKHnPAQaZMqLOsyuyUmcIjSeDm+73eoqQpaXA7AZ22BL+6C+1mcUscgOsNd8WVlJuvlgAPsegcx7pjlV0Dg==", - "dev": true } } }, @@ -40065,9 +42972,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, "fstream": { @@ -40082,13 +42989,18 @@ "rimraf": "2" }, "dependencies": { - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { - "minimist": "^1.2.6" + "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" } }, "rimraf": { @@ -40116,15 +43028,15 @@ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "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, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" } }, "functional-red-black-tree": { @@ -40149,126 +43061,51 @@ } }, "geckodriver": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.3.1.tgz", - "integrity": "sha512-ol7JLsj55o5k+z7YzeSy2mdJROXMAxIa+uzr3A1yEMr5HISqQOTslE3ZeARcxR4jpAY3fxmHM+sq32qbe/eXfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.1.tgz", + "integrity": "sha512-nnAdIrwLkMcDu4BitWXF23pEMeZZ0Cj7HaWWFdSpeedBP9z6ft150JYiGO2mwzw6UiR823Znk1JeIf07RyzloA==", "dev": true, "requires": { - "@wdio/logger": "^8.24.12", + "@wdio/logger": "^8.28.0", + "@zip.js/zip.js": "^2.7.44", "decamelize": "^6.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", "node-fetch": "^3.3.2", - "tar-fs": "^3.0.4", - "unzipper": "^0.10.14", + "tar-fs": "^3.0.6", "which": "^4.0.0" }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, - "data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true - }, - "decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "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, "requires": { "agent-base": "^7.0.2", "debug": "4" } }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true - }, - "node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, "tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, "requires": { - "mkdirp-classic": "^0.5.2", + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0", "pump": "^3.0.0", "tar-stream": "^3.1.5" } - }, - "tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "unzipper": { - "version": "0.10.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", - "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", - "dev": true, - "requires": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "requires": { - "isexe": "^3.1.1" - } } } }, @@ -40284,16 +43121,17 @@ "dev": true }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "requires": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", @@ -40307,9 +43145,9 @@ "dev": true }, "get-port": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.0.0.tgz", - "integrity": "sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", "dev": true }, "get-stream": { @@ -40322,52 +43160,54 @@ } }, "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==", + "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, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" } }, "get-uri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz", - "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", "dev": true, "requires": { "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.0", + "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4", - "fs-extra": "^8.1.0" + "fs-extra": "^11.2.0" }, "dependencies": { + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true + }, "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "requires": { "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true } } }, @@ -40403,9 +43243,9 @@ } }, "git-url-parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.1.tgz", + "integrity": "sha512-PCFJyeSSdtnbfhSNRw9Wk96dDCNx+sogTe4YNXeXSJxt7xz5hvXekuRn9JX7m+Mf4OscCu8h+mtAl3+h5Fo8lQ==", "dev": true, "requires": { "git-up": "^7.0.0" @@ -40435,17 +43275,37 @@ "dev": true }, "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, "requires": { - "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" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "glob-parent": { @@ -40475,6 +43335,20 @@ "unique-stream": "^2.0.2" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -40538,12 +43412,6 @@ } } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -40671,15 +43539,6 @@ "kind-of": "^3.0.2" } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -40689,54 +43548,6 @@ "is-buffer": "^1.1.5" } }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "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 - } - } - }, "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", @@ -40800,6 +43611,12 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -40822,6 +43639,16 @@ "integrity": "sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==", "dev": true }, + "globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "requires": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + } + }, "globule": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", @@ -40876,28 +43703,36 @@ } }, "got": { - "version": "11.8.5", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", - "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", "dev": true, "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "dependencies": { + "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 + } } }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "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==" }, "grapheme-splitter": { "version": "1.0.4", @@ -40930,6 +43765,20 @@ "vinyl": "^2.1.0" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -41324,12 +44173,6 @@ "ansi-wrap": "^0.1.0" } }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -41348,6 +44191,12 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -41433,17 +44282,6 @@ "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } } }, "eslint-utils": { @@ -41482,6 +44320,15 @@ "is-extendable": "^1.0.1" } }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -41508,6 +44355,20 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -41562,6 +44423,15 @@ "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } } } }, @@ -41571,6 +44441,12 @@ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -41581,14 +44457,11 @@ "type-check": "~0.3.2" } }, - "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, - "requires": { - "minimist": "^1.2.6" - } + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true }, "optionator": { "version": "0.8.3", @@ -41643,6 +44516,21 @@ "glob": "^7.1.3" } }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -41669,6 +44557,23 @@ "is-fullwidth-code-point": "^2.0.0" } }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + } + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -41706,15 +44611,6 @@ "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } } } }, @@ -41828,24 +44724,16 @@ "dev": true }, "gulp-replace": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.1.3.tgz", - "integrity": "sha512-HcPHpWY4XdF8zxYkDODHnG2+7a3nD/Y8Mfu3aBgMiCFDW3X2GiOKXllsAmILcxe3KZT2BXoN18WrpEFm48KfLQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.1.4.tgz", + "integrity": "sha512-SVSF7ikuWKhpAW4l4wapAqPPSToJoiNKsbDoUnRrSgwZHH7lH8pbPeQj1aOVYQrbZKhfSVBxVW+Py7vtulRktw==", "dev": true, "requires": { - "@types/node": "^14.14.41", + "@types/node": "*", "@types/vinyl": "^2.0.4", "istextorbinary": "^3.0.0", "replacestream": "^4.0.3", "yargs-parser": ">=5.0.0-security.0" - }, - "dependencies": { - "@types/node": { - "version": "14.18.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.33.tgz", - "integrity": "sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==", - "dev": true - } } }, "gulp-shell": { @@ -41991,6 +44879,12 @@ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -42285,13 +45179,13 @@ } }, "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "requires": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" @@ -42322,12 +45216,9 @@ } }, "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==" }, "has-ansi": { "version": "2.0.0", @@ -42367,17 +45258,17 @@ } }, "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "requires": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" } }, "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==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" }, "has-symbols": { "version": "1.0.3", @@ -42385,12 +45276,12 @@ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "requires": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" } }, "has-value": { @@ -42452,56 +45343,117 @@ } }, "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "requires": { "function-bind": "^1.1.2" } }, - "hast-util-is-element": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.2.tgz", - "integrity": "sha512-thjnlGAnwP8ef/GSO1Q8BfVk2gundnc2peGQqEg2kUt/IqesiGg/5mSwN2fE7nLzy61pg88NG6xV+UrGOrx9EA==", + "hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", "dev": true, "requires": { "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0" + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + } + }, + "hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dev": true, + "requires": { + "@types/hast": "^2.0.0" + } + }, + "hast-util-raw": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "dev": true, + "requires": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" } }, "hast-util-sanitize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-4.0.0.tgz", - "integrity": "sha512-pw56+69jq+QSr/coADNvWTmBPDy+XsmwaF5KnUys4/wM1jt/fZdl7GPxhXXXYdXnz3Gj3qMkbUCH2uKjvX0MgQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-4.1.0.tgz", + "integrity": "sha512-Hd9tU0ltknMGRDv+d6Ro/4XKzBqQnP/EZrpiTbpFYfXv/uOhWeKc+2uajcbEvAEH98VZd7eII2PiXm13RihnLw==", "dev": true, "requires": { "@types/hast": "^2.0.0" } }, "hast-util-to-html": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.3.tgz", - "integrity": "sha512-/D/E5ymdPYhHpPkuTHOUkSatxr4w1ZKrZsG0Zv/3C2SRVT0JFJG53VS45AMrBtYk0wp5A7ksEhiC8QaOZM95+A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", + "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", "dev": true, "requires": { "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", - "hast-util-is-element": "^2.0.0", + "hast-util-raw": "^7.0.0", "hast-util-whitespace": "^2.0.0", "html-void-elements": "^2.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.2", - "unist-util-is": "^5.0.0" + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + } + }, + "hast-util-to-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "dev": true, + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" } }, "hast-util-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz", - "integrity": "sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", "dev": true }, + "hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dev": true, + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -42515,9 +45467,9 @@ "dev": true }, "highlight.js": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.6.0.tgz", - "integrity": "sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw==", + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", + "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", "dev": true }, "home-or-tmp": { @@ -42540,12 +45492,20 @@ } }, "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==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "lru-cache": "^10.0.1" + }, + "dependencies": { + "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 + } } }, "html-escaper": { @@ -42596,9 +45556,9 @@ } }, "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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, "requires": { "agent-base": "^7.1.0", @@ -42606,9 +45566,9 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" @@ -42628,13 +45588,13 @@ } }, "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "dev": true, "requires": { "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" + "resolve-alpn": "^1.2.0" } }, "https-proxy-agent": { @@ -42673,6 +45633,12 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -42692,9 +45658,9 @@ } }, "import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "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 }, "imurmurhash": { @@ -42753,112 +45719,31 @@ "wrap-ansi": "^6.2.0" }, "dependencies": { - "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, - "requires": { - "color-convert": "^2.0.1" - } - }, "chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true }, - "cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true - }, - "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, - "requires": { - "color-name": "~1.1.4" - } - }, - "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 - }, - "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 - }, - "figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "requires": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - } - }, - "is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true - }, - "mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true - }, - "run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true - }, - "rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-regex": "^5.0.1" } } } }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "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, "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" } }, @@ -42883,11 +45768,23 @@ "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", "dev": true }, - "ip": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", - "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", - "dev": true + "ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "requires": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + } + } }, "ipaddr.js": { "version": "1.9.1", @@ -42910,20 +45807,12 @@ } }, "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", "dev": true, "requires": { - "kind-of": "^6.0.0" - }, - "dependencies": { - "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 - } + "hasown": "^2.0.0" } }, "is-arguments": { @@ -42936,6 +45825,16 @@ "has-tostringtag": "^1.0.0" } }, + "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, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -42983,28 +45882,29 @@ "dev": true }, "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", "dev": true, "requires": { - "kind-of": "^6.0.0" - }, - "dependencies": { - "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 - } + "hasown": "^2.0.0" + } + }, + "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, + "requires": { + "is-typed-array": "^1.1.13" } }, "is-date-object": { @@ -43017,22 +45917,13 @@ } }, "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "dependencies": { - "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 - } + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } }, "is-docker": { @@ -43108,9 +45999,9 @@ "dev": true }, "is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true }, "is-nan": { @@ -43130,9 +46021,9 @@ "dev": true }, "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==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true }, "is-number": { @@ -43194,18 +46085,18 @@ "dev": true }, "is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true }, "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==", + "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, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" } }, "is-ssh": { @@ -43242,16 +46133,12 @@ } }, "is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "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, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.14" } }, "is-typedarray": { @@ -43270,9 +46157,9 @@ } }, "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true }, "is-utf8": { @@ -43288,9 +46175,9 @@ "dev": true }, "is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true }, "is-weakref": { @@ -43303,13 +46190,13 @@ } }, "is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" } }, "is-windows": { @@ -43340,9 +46227,9 @@ "dev": true }, "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true }, "isobject": { @@ -43397,14 +46284,11 @@ "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", "dev": true }, - "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, - "requires": { - "minimist": "^1.2.6" - } + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "resolve": { "version": "1.1.7", @@ -43433,9 +46317,9 @@ } }, "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "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 }, "istanbul-lib-instrument": { @@ -43452,13 +46336,13 @@ } }, "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "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, "requires": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "dependencies": { @@ -43468,6 +46352,21 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "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, + "requires": { + "semver": "^7.5.3" + } + }, + "semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -43499,9 +46398,9 @@ } }, "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -43519,9 +46418,9 @@ } }, "jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", "dev": true, "requires": { "@isaacs/cliui": "^8.0.2", @@ -43529,9 +46428,9 @@ } }, "jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dev": true, "requires": { "async": "^3.2.3", @@ -43786,6 +46685,16 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "requires": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -43918,15 +46827,15 @@ } }, "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", "dev": true }, "jsdoc-type-pratt-parser": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.5.tgz", - "integrity": "sha512-2a6eRxSxp1BW040hFvaJxhsCMI9lT8QB8t14t+NY5tC5rckIR0U9cr2tjOeaFirmEOy6MHvmJnY7zTBHq431Lw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true }, "jsesc": { @@ -43941,9 +46850,9 @@ "dev": true }, "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==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", "dev": true }, "json-schema": { @@ -43971,19 +46880,15 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz", + "integrity": "sha512-KbsDJNRfRPF5v49tMNf9sqyyGqGLBcz1v5kZT01kG5ns5mQSltwxCKVmUzVKtEinkUnTDtSrp6ngWpV7Xw0ZlA==", + "dev": true }, "jsprim": { "version": "1.4.2", @@ -43997,6 +46902,18 @@ "verror": "1.10.0" } }, + "jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "just-debounce": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", @@ -44010,9 +46927,9 @@ "dev": true }, "karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.3.tgz", + "integrity": "sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==", "dev": true, "requires": { "@colors/colors": "1.5.0", @@ -44034,13 +46951,22 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^4.4.1", + "socket.io": "^4.7.2", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.30", "yargs": "^16.1.1" }, "dependencies": { + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -44052,13 +46978,33 @@ "wrap-ansi": "^7.0.0" } }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { - "minimist": "^1.2.6" + "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" } }, "source-map": { @@ -44067,13 +47013,24 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "rimraf": "^3.0.0" + "ansi-regex": "^5.0.1" + } + }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, "yargs": { @@ -44125,14 +47082,20 @@ "requires": {} }, "karma-chrome-launcher": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", - "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, "requires": { "which": "^1.2.1" }, "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -44145,9 +47108,9 @@ } }, "karma-coverage": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.0.tgz", - "integrity": "sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", "dev": true, "requires": { "istanbul-lib-coverage": "^3.2.0", @@ -44171,6 +47134,20 @@ "minimatch": "^3.0.4" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, "istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", @@ -44241,13 +47218,30 @@ } }, "karma-firefox-launcher": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz", - "integrity": "sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", + "integrity": "sha512-LMM2bseebLbYjODBOVt7TCPP9OI2vZIXCavIXhkO9m+10Uj5l7u/SKoeRmYx8FYHTVGZSpk6peX+3BMHC1WwNw==", "dev": true, "requires": { "is-wsl": "^2.2.0", - "which": "^2.0.1" + "which": "^3.0.0" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "karma-ie-launcher": { @@ -44343,14 +47337,61 @@ } }, "karma-webpack": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0.tgz", - "integrity": "sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.1.tgz", + "integrity": "sha512-oo38O+P3W2mSPCSUrQdySSPv1LvPpXP+f+bBimNomS5sW+1V4SuhCuW8TfJzV+rDv921w2fDSDw0xJbPe6U+kQ==", "dev": true, "requires": { "glob": "^7.1.3", - "minimatch": "^3.0.4", + "minimatch": "^9.0.3", "webpack-merge": "^4.1.5" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + } + } + } } }, "keycode": { @@ -44454,6 +47495,15 @@ "type-check": "~0.4.0" } }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -44482,9 +47532,9 @@ } }, "lighthouse-logger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz", - "integrity": "sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, "requires": { "debug": "^2.6.9", @@ -44509,9 +47559,9 @@ } }, "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==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", "dev": true }, "listenercount": { @@ -44597,12 +47647,12 @@ } }, "locate-app": { - "version": "2.2.13", - "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.2.13.tgz", - "integrity": "sha512-1jp6iRFrHKBj9vq6Idb0cSjly+KnCIMbxZ2BBKSEzIC4ZJosv47wnLoiJu2EgOAdjhGvNcy/P2fbDCS/WziI8g==", + "version": "2.4.15", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.4.15.tgz", + "integrity": "sha512-oAGHATXPUHSQ74Om+3dXBRNYtCzU7Wzuhlj/WIZchqHb/5/TGJRzLEtHipMDOak0UZG9U365RMXyBzgV/fhOww==", "dev": true, "requires": { - "n12": "1.8.16", + "@promptbook/utils": "0.50.0-10", "type-fest": "2.13.0", "userhome": "1.0.0" }, @@ -44857,16 +47907,16 @@ } }, "log4js": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", - "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", "dev": true, "requires": { "date-format": "^4.0.14", "debug": "^4.3.4", "flatted": "^3.2.7", "rfdc": "^1.3.0", - "streamroller": "^3.1.3" + "streamroller": "^3.1.5" } }, "logform": { @@ -44892,9 +47942,9 @@ } }, "loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", "dev": true }, "loglevel-plugin-prefix": { @@ -44910,9 +47960,9 @@ "dev": true }, "longest-streak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.1.tgz", - "integrity": "sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "dev": true }, "loose-envify": { @@ -44925,27 +47975,26 @@ } }, "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "requires": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true }, "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, + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "lru-queue": { @@ -44958,9 +48007,9 @@ } }, "m3u8-parser": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.7.1.tgz", - "integrity": "sha512-pbrQwiMiq+MmI9bl7UjtPT3AK603PV9bogNlr83uC+X9IoxqL5E4k7kU7fMQ0dpRgxgeSMygqUa0IMLQNXLBNA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.8.0.tgz", + "integrity": "sha512-UqA2a/Pw3liR6Df3gwxrqghCP17OpPlQj6RBPLYygf/ZSQ4MoSgvdvhvt35qV+3NaaA0FSZx93Ix+2brT1U7cA==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", @@ -44969,13 +48018,12 @@ } }, "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, - "optional": true, "requires": { - "sourcemap-codec": "^1.4.8" + "@jridgewell/sourcemap-codec": "^1.4.15" } }, "make-dir": { @@ -45026,9 +48074,9 @@ } }, "markdown-table": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz", - "integrity": "sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", "dev": true }, "marky": { @@ -45049,86 +48097,6 @@ "stack-trace": "0.0.10" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - } - } - }, "findup-sync": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", @@ -45141,12 +48109,6 @@ "resolve-dir": "^1.0.1" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", @@ -45155,70 +48117,13 @@ "requires": { "is-extglob": "^2.1.0" } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "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 - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } } } }, "mdast-util-definitions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz", - "integrity": "sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", + "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -45227,11 +48132,12 @@ } }, "mdast-util-find-and-replace": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.1.tgz", - "integrity": "sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", + "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", "dev": true, "requires": { + "@types/mdast": "^3.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.0.0" @@ -45246,9 +48152,9 @@ } }, "mdast-util-from-markdown": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz", - "integrity": "sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -45266,17 +48172,20 @@ }, "dependencies": { "mdast-util-to-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", - "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", - "dev": true + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0" + } } } }, "mdast-util-gfm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.1.tgz", - "integrity": "sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", + "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", "dev": true, "requires": { "mdast-util-from-markdown": "^1.0.0", @@ -45289,9 +48198,9 @@ } }, "mdast-util-gfm-autolink-literal": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.2.tgz", - "integrity": "sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", + "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -45301,9 +48210,9 @@ } }, "mdast-util-gfm-footnote": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.1.tgz", - "integrity": "sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", + "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -45312,9 +48221,9 @@ } }, "mdast-util-gfm-strikethrough": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.1.tgz", - "integrity": "sha512-zKJbEPe+JP6EUv0mZ0tQUyLQOC+FADt0bARldONot/nefuISkaZFlmVK4tU6JgfyZGrky02m/I6PmehgAgZgqg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", + "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -45322,9 +48231,9 @@ } }, "mdast-util-gfm-table": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.6.tgz", - "integrity": "sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", + "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -45334,9 +48243,9 @@ } }, "mdast-util-gfm-task-list-item": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.1.tgz", - "integrity": "sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", + "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -45352,10 +48261,20 @@ "mdast-util-to-string": "^1.0.0" } }, + "mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + } + }, "mdast-util-to-hast": { - "version": "12.2.4", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.4.tgz", - "integrity": "sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", + "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", "dev": true, "requires": { "@types/hast": "^2.0.0", @@ -45363,21 +48282,21 @@ "mdast-util-definitions": "^5.0.0", "micromark-util-sanitize-uri": "^1.1.0", "trim-lines": "^3.0.0", - "unist-builder": "^3.0.0", "unist-util-generated": "^2.0.0", "unist-util-position": "^4.0.0", "unist-util-visit": "^4.0.0" } }, "mdast-util-to-markdown": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz", - "integrity": "sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", "dev": true, "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", "mdast-util-to-string": "^3.0.0", "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", @@ -45385,10 +48304,13 @@ }, "dependencies": { "mdast-util-to-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", - "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", - "dev": true + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0" + } } } }, @@ -45399,46 +48321,33 @@ "dev": true }, "mdast-util-toc": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-6.1.0.tgz", - "integrity": "sha512-0PuqZELXZl4ms1sF7Lqigrqik4Ll3UhbI+jdTrfw7pZ9QPawgl7LD4GQ8MkU7bT/EwiVqChNTbifa2jLLKo76A==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-6.1.1.tgz", + "integrity": "sha512-Er21728Kow8hehecK2GZtb7Ny3omcoPUVrmObiSUwmoRYVZaXLR751QROEFjR8W/vAQdHMLj49Lz20J55XaNpw==", "dev": true, "requires": { "@types/extend": "^3.0.0", - "@types/github-slugger": "^1.0.0", "@types/mdast": "^3.0.0", "extend": "^3.0.0", - "github-slugger": "^1.0.0", + "github-slugger": "^2.0.0", "mdast-util-to-string": "^3.1.0", "unist-util-is": "^5.0.0", - "unist-util-visit": "^3.0.0" + "unist-util-visit": "^4.0.0" }, "dependencies": { - "mdast-util-to-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz", - "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==", + "github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", "dev": true }, - "unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - } - }, - "unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", + "mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", "dev": true, "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" + "@types/mdast": "^3.0.0" } } } @@ -45449,13 +48358,13 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", "dev": true, "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", + "d": "^1.0.2", + "es5-ext": "^0.10.64", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", @@ -45491,9 +48400,9 @@ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromark": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", - "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", "dev": true, "requires": { "@types/debug": "^4.0.0", @@ -45516,9 +48425,9 @@ } }, "micromark-core-commonmark": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz", - "integrity": "sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", "dev": true, "requires": { "decode-named-character-reference": "^1.0.0", @@ -45540,9 +48449,9 @@ } }, "micromark-extension-gfm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.1.tgz", - "integrity": "sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", + "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", "dev": true, "requires": { "micromark-extension-gfm-autolink-literal": "^1.0.0", @@ -45556,22 +48465,21 @@ } }, "micromark-extension-gfm-autolink-literal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.3.tgz", - "integrity": "sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", + "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", "dev": true, "requires": { "micromark-util-character": "^1.0.0", "micromark-util-sanitize-uri": "^1.0.0", "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "micromark-util-types": "^1.0.0" } }, "micromark-extension-gfm-footnote": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.4.tgz", - "integrity": "sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", + "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", "dev": true, "requires": { "micromark-core-commonmark": "^1.0.0", @@ -45585,9 +48493,9 @@ } }, "micromark-extension-gfm-strikethrough": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.4.tgz", - "integrity": "sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", + "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", "dev": true, "requires": { "micromark-util-chunked": "^1.0.0", @@ -45599,9 +48507,9 @@ } }, "micromark-extension-gfm-table": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.5.tgz", - "integrity": "sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", + "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", "dev": true, "requires": { "micromark-factory-space": "^1.0.0", @@ -45612,18 +48520,18 @@ } }, "micromark-extension-gfm-tagfilter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.1.tgz", - "integrity": "sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", + "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", "dev": true, "requires": { "micromark-util-types": "^1.0.0" } }, "micromark-extension-gfm-task-list-item": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.3.tgz", - "integrity": "sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", + "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", "dev": true, "requires": { "micromark-factory-space": "^1.0.0", @@ -45634,9 +48542,9 @@ } }, "micromark-factory-destination": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz", - "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", "dev": true, "requires": { "micromark-util-character": "^1.0.0", @@ -45645,9 +48553,9 @@ } }, "micromark-factory-label": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz", - "integrity": "sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", "dev": true, "requires": { "micromark-util-character": "^1.0.0", @@ -45657,9 +48565,9 @@ } }, "micromark-factory-space": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz", - "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", "dev": true, "requires": { "micromark-util-character": "^1.0.0", @@ -45667,22 +48575,21 @@ } }, "micromark-factory-title": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz", - "integrity": "sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", "dev": true, "requires": { "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "micromark-util-types": "^1.0.0" } }, "micromark-factory-whitespace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz", - "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", "dev": true, "requires": { "micromark-factory-space": "^1.0.0", @@ -45692,9 +48599,9 @@ } }, "micromark-util-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz", - "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", "dev": true, "requires": { "micromark-util-symbol": "^1.0.0", @@ -45702,18 +48609,18 @@ } }, "micromark-util-chunked": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz", - "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", "dev": true, "requires": { "micromark-util-symbol": "^1.0.0" } }, "micromark-util-classify-character": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz", - "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", "dev": true, "requires": { "micromark-util-character": "^1.0.0", @@ -45722,9 +48629,9 @@ } }, "micromark-util-combine-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz", - "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", "dev": true, "requires": { "micromark-util-chunked": "^1.0.0", @@ -45732,18 +48639,18 @@ } }, "micromark-util-decode-numeric-character-reference": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz", - "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", "dev": true, "requires": { "micromark-util-symbol": "^1.0.0" } }, "micromark-util-decode-string": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz", - "integrity": "sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", "dev": true, "requires": { "decode-named-character-reference": "^1.0.0", @@ -45753,39 +48660,39 @@ } }, "micromark-util-encode": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz", - "integrity": "sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", "dev": true }, "micromark-util-html-tag-name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz", - "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", "dev": true }, "micromark-util-normalize-identifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz", - "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", "dev": true, "requires": { "micromark-util-symbol": "^1.0.0" } }, "micromark-util-resolve-all": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz", - "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", "dev": true, "requires": { "micromark-util-types": "^1.0.0" } }, "micromark-util-sanitize-uri": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", - "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", "dev": true, "requires": { "micromark-util-character": "^1.0.0", @@ -45794,9 +48701,9 @@ } }, "micromark-util-subtokenize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz", - "integrity": "sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", "dev": true, "requires": { "micromark-util-chunked": "^1.0.0", @@ -45806,25 +48713,160 @@ } }, "micromark-util-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz", - "integrity": "sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", "dev": true }, "micromark-util-types": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.2.tgz", - "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "dev": true }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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 + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "mime": { @@ -45853,9 +48895,9 @@ "dev": true }, "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "dev": true }, "min-document": { @@ -45877,15 +48919,15 @@ } }, "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true }, "mitt": { @@ -45904,6 +48946,15 @@ "is-extendable": "^1.0.1" } }, + "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, + "requires": { + "minimist": "^1.2.6" + } + }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -45911,9 +48962,9 @@ "dev": true }, "mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -45923,13 +48974,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -45960,6 +49010,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -45981,6 +49040,22 @@ } } }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -46007,6 +49082,23 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "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 + } + } + }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -46030,28 +49122,16 @@ } }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } + "minimatch": "^5.0.1", + "once": "^1.3.0" } }, "has-flag": { @@ -46060,6 +49140,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -46095,17 +49181,6 @@ "dev": true, "requires": { "brace-expansion": "^2.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - } } }, "ms": { @@ -46132,6 +49207,15 @@ "p-limit": "^3.0.2" } }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -46147,6 +49231,17 @@ "has-flag": "^4.0.0" } }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -46167,9 +49262,21 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } }, + "moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "dev": true + }, "morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -46210,14 +49317,14 @@ } }, "mpd-parser": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.21.1.tgz", - "integrity": "sha512-BxlSXWbKE1n7eyEPBnTEkrzhS3PdmkkKdM1pgKbPnPOH0WFZIc0sPOWi7m0Uo3Wd2a4Or8Qf4ZbS7+ASqQ49fw==", + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", "@videojs/vhs-utils": "^3.0.5", - "@xmldom/xmldom": "^0.7.2", + "@xmldom/xmldom": "^0.8.3", "global": "^4.4.0" } }, @@ -46228,9 +49335,9 @@ "dev": true }, "mrmime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true }, "ms": { @@ -46254,9 +49361,9 @@ "dev": true }, "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true }, "mux.js": { @@ -46269,24 +49376,19 @@ "global": "^4.4.0" } }, - "n12": { - "version": "1.8.16", - "resolved": "https://registry.npmjs.org/n12/-/n12-1.8.16.tgz", - "integrity": "sha512-CZqHAqbzS0UsaUGkMsL+lMaYLyFr1+/ea+pD8dMziqSjkcuWVWDtgWx9phyfT7C3llqQ2+LwnStSb5afggBMfA==", - "dev": true - }, "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", "dev": true, "optional": true }, "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "optional": true }, "nanomatch": { "version": "1.2.13", @@ -46428,18 +49530,20 @@ "dev": true }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, "requires": { - "whatwg-url": "^5.0.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" } }, "node-html-parser": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.6.tgz", - "integrity": "sha512-C/MGDQ2NjdjzUq41bW9kW00MPZecAe/oo89vZEFLDfWoQVDk/DdML1yuxVVKLDMFIFax2VTq6Vpfzyn7z5yYgQ==", + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.13.tgz", + "integrity": "sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==", "dev": true, "requires": { "css-select": "^5.1.0", @@ -46447,9 +49551,9 @@ } }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node-request-interceptor": { "version": "0.6.3", @@ -46482,25 +49586,22 @@ } }, "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==", + "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, "requires": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" }, "dependencies": { "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, - "requires": { - "lru-cache": "^6.0.0" - } + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true } } }, @@ -46511,9 +49612,9 @@ "dev": true }, "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", "dev": true }, "now-and-later": { @@ -46589,47 +49690,20 @@ "is-descriptor": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } }, "kind-of": { @@ -46644,18 +49718,18 @@ } }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" }, "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" } }, "object-keys": { @@ -46674,13 +49748,13 @@ } }, "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, "requires": { - "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" } @@ -46697,6 +49771,29 @@ "isobject": "^3.0.0" } }, + "object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + } + }, + "object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + } + }, "object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", @@ -46727,14 +49824,14 @@ } }, "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "on-finished": { @@ -46793,9 +49890,9 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { "deep-is": "^0.1.3", @@ -46803,7 +49900,7 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" } }, "ora": { @@ -46863,6 +49960,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -46873,6 +49976,15 @@ "is-unicode-supported": "^0.1.0" } }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -46915,9 +50027,9 @@ "dev": true }, "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true }, "p-finally": { @@ -46973,18 +50085,18 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "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, "requires": { "agent-base": "^7.0.2", @@ -46994,16 +50106,27 @@ } }, "pac-resolver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", - "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, "requires": { "degenerator": "^5.0.0", - "ip": "^1.1.8", "netmask": "^2.0.2" } }, + "package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -47024,16 +50147,35 @@ "path-root": "^0.1.1" } }, + "parse-imports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.0.tgz", + "integrity": "sha512-JQWgmK2o4w8leUkZeZPatWdAny6vXGU/3siIUvMF6J2rDCud9aTt8h/px9oZJ6U3EcfhngBJ635uPFI0q0VAeA==", + "dev": true, + "requires": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + } + }, "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@babel/code-frame": "^7.21.4", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^3.0.0", + "lines-and-columns": "^2.0.3", + "type-fest": "^3.8.0" + }, + "dependencies": { + "type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true + } } }, "parse-ms": { @@ -47072,6 +50214,12 @@ "parse-path": "^7.0.0" } }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -47128,19 +50276,19 @@ "dev": true }, "path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { "lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", "dev": true } } @@ -47203,9 +50351,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "picomatch": { "version": "2.3.1", @@ -47271,25 +50419,22 @@ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "dev": true }, + "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 + }, "postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "optional": true, "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "dependencies": { - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true, - "optional": true - } + "source-map-js": "^1.2.0" } }, "prelude-ls": { @@ -47298,6 +50443,12 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "prettier": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", + "dev": true + }, "pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -47356,9 +50507,9 @@ "dev": true }, "property-information": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", - "integrity": "sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "dev": true }, "protocols": { @@ -47393,18 +50544,18 @@ }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "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, "requires": { "agent-base": "^7.0.2", @@ -47492,9 +50643,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "puppeteer-core": { @@ -47517,12 +50668,57 @@ "ws": "8.5.0" }, "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "devtools-protocol": { "version": "0.0.981744", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.981744.tgz", "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", "dev": true }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", @@ -47553,15 +50749,15 @@ } }, "query-selector-shadow-dom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.0.tgz", - "integrity": "sha512-bK0/0cCI+R8ZmOF1QjT7HupDUYCxbf/9TJgAmSXQxZpftXmTAeil9DRoCnTDkWbvOyZzhcMBwKpptWcdkGFIMg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", + "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", "dev": true }, "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", "dev": true }, "querystringify": { @@ -47608,40 +50804,40 @@ } }, "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, "read-pkg": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-7.1.0.tgz", - "integrity": "sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", + "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", "dev": true, "requires": { "@types/normalize-package-data": "^2.4.1", - "normalize-package-data": "^3.0.2", - "parse-json": "^5.2.0", - "type-fest": "^2.0.0" + "normalize-package-data": "^6.0.0", + "parse-json": "^7.0.0", + "type-fest": "^4.2.0" }, "dependencies": { "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.0.tgz", + "integrity": "sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw==", "dev": true } } }, "read-pkg-up": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-9.1.0.tgz", - "integrity": "sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.0.0.tgz", + "integrity": "sha512-jgmKiS//w2Zs+YbX039CorlkOp8FIVbSAN8r8GJHDsGlmNPXo+VeHkqAwCiQVTTx5/LwLZTcEw59z3DvcLbr0g==", "dev": true, "requires": { "find-up": "^6.3.0", - "read-pkg": "^7.1.0", - "type-fest": "^2.5.0" + "read-pkg": "^8.0.0", + "type-fest": "^3.12.0" }, "dependencies": { "find-up": { @@ -47655,9 +50851,9 @@ } }, "locate-path": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.1.1.tgz", - "integrity": "sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, "requires": { "p-locate": "^6.0.0" @@ -47688,23 +50884,17 @@ "dev": true }, "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 - }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", "dev": true } } }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -47728,9 +50918,9 @@ } }, "readdir-glob": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.2.tgz", - "integrity": "sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, "requires": { "minimatch": "^5.1.0" @@ -47746,9 +50936,9 @@ } }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -47789,22 +50979,22 @@ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "requires": { "regenerate": "^1.4.2" } }, "regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "requires": { "@babel/runtime": "^7.8.4" } @@ -47832,14 +51022,15 @@ } }, "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "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, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" } }, "regexpp": { @@ -47849,29 +51040,18 @@ "dev": true }, "regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "requires": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" } }, - "regextras": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", - "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", - "dev": true - }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" - }, "regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", @@ -47888,9 +51068,9 @@ } }, "remark": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.2.tgz", - "integrity": "sha512-A3ARm2V4BgiRXaUo5K0dRvJ1lbogrbXnhkJRmD0yw092/Yl0kOCZt1k9ZeElEwkZsWGsMumz6qL5MfNJH9nOBA==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.3.tgz", + "integrity": "sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -47912,9 +51092,9 @@ } }, "remark-html": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-15.0.1.tgz", - "integrity": "sha512-7ta5UPRqj8nP0GhGMYUAghZ/DRno7dgq7alcW90A7+9pgJsXzGJlFgwF8HOP1b1tMgT3WwbeANN+CaTimMfyNQ==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-15.0.2.tgz", + "integrity": "sha512-/CIOI7wzHJzsh48AiuIyIe1clxVkUtreul73zcCXLub0FmnevQE0UMFDQm7NUx8/3rl/4zCshlMfqBdWScQthw==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -47925,9 +51105,9 @@ } }, "remark-parse": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz", - "integrity": "sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", + "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -47947,9 +51127,9 @@ } }, "remark-stringify": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.2.tgz", - "integrity": "sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.3.tgz", + "integrity": "sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==", "dev": true, "requires": { "@types/mdast": "^3.0.0", @@ -48097,6 +51277,12 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, @@ -48125,11 +51311,11 @@ "dev": true }, "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "requires": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -48172,18 +51358,18 @@ "dev": true }, "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dev": true, "requires": { - "lowercase-keys": "^2.0.0" + "lowercase-keys": "^3.0.0" } }, "resq": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.2.tgz", - "integrity": "sha512-HmgVS3j+FLrEDBTDYysPdPVF9/hioDMJ/otOiQDKqk77YfZeeLOj0qi34yObumcud1gBpk+wpBTEg4kMicD++A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", + "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1" @@ -48214,9 +51400,9 @@ "dev": true }, "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "rgb2hex": { @@ -48232,12 +51418,28 @@ "dev": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + } } }, "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "dev": true }, "rust-result": { @@ -48250,12 +51452,20 @@ } }, "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "requires": { - "tslib": "^1.9.0" + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + } } }, "sade": { @@ -48273,6 +51483,18 @@ "integrity": "sha512-4R309+gWflJktzPXBQCobbWEHlzC4aK3a+Ov3tz2Ib2aBxiwd11phkdIBH1l0EO22x24CJMUQkpKFumRriCSRg==", "dev": true }, + "safe-array-concat": { + "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, + "requires": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -48294,13 +51516,13 @@ } }, "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, "requires": { - "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" } }, @@ -48519,15 +51741,28 @@ "dev": true }, "set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "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==", "requires": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" + } + }, + "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, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" } }, "set-value": { @@ -48595,13 +51830,14 @@ "dev": true }, "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==", "requires": { - "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" } }, "signal-exit": { @@ -48634,14 +51870,14 @@ } }, "sirv": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", - "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dev": true, "requires": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.0" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" } }, "slash": { @@ -48650,6 +51886,12 @@ "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true }, + "slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, "slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -48736,61 +51978,14 @@ "is-extendable": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } }, "is-extendable": { @@ -48869,32 +52064,34 @@ } }, "socket.io": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", - "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", + "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.4.1", + "engine.io": "~6.5.2", "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.1" + "socket.io-parser": "~4.2.4" } }, "socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, "requires": { - "ws": "~8.11.0" + "debug": "~4.3.4", + "ws": "~8.17.1" } }, "socket.io-parser": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz", - "integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "requires": { "@socket.io/component-emitter": "~3.1.0", @@ -48902,38 +52099,30 @@ } }, "socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, "requires": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" - }, - "dependencies": { - "ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "dev": true - } } }, "socks-proxy-agent": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", - "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", "dev": true, "requires": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.1", "debug": "^4.3.4", "socks": "^2.7.1" }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "requires": { "debug": "^4.3.4" @@ -48954,9 +52143,9 @@ "dev": true }, "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, "optional": true }, @@ -48985,17 +52174,16 @@ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true, - "optional": true - }, "space-separated-tokens": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", - "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true + }, + "spacetrim": { + "version": "0.11.25", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.25.tgz", + "integrity": "sha512-SWxXDROciuJs9YEYXUBjot5k/cqNGPPbT3QmkInFne4AGc1y+76It+jqU8rfsXKt57RRiunzZn1m9+KfuuNklw==", "dev": true }, "sparkles": { @@ -49005,9 +52193,9 @@ "dev": true }, "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -49015,9 +52203,9 @@ } }, "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, "spdx-expression-parse": { @@ -49031,9 +52219,9 @@ } }, "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, "split": { @@ -49078,9 +52266,9 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -49092,6 +52280,14 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" + }, + "dependencies": { + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + } } }, "stack-trace": { @@ -49136,61 +52332,14 @@ "is-descriptor": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } } } @@ -49200,6 +52349,15 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "requires": { + "internal-slot": "^1.0.4" + } + }, "stream-buffers": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", @@ -49222,15 +52380,15 @@ "dev": true }, "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", "dev": true }, "streamroller": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", - "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", "dev": true, "requires": { "date-format": "^4.0.14", @@ -49267,13 +52425,15 @@ } }, "streamx": { - "version": "2.15.6", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", - "integrity": "sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dev": true, "requires": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" + "bare-events": "^2.2.0", + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" } }, "strict-event-emitter": { @@ -49312,6 +52472,17 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "string-width-cjs": { @@ -49323,34 +52494,57 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "string.prototype.trim": { + "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, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "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, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "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, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "dev": true, "requires": { "character-entities-html4": "^2.0.0", @@ -49358,12 +52552,20 @@ } }, "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "requires": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + } } }, "strip-ansi-cjs": { @@ -49400,9 +52602,9 @@ "dev": true }, "strip-json-comments": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.0.tgz", - "integrity": "sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", + "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", "dev": true }, "supports-color": { @@ -49428,10 +52630,28 @@ "es6-symbol": "^3.1.1" } }, + "synckit": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.0.tgz", + "integrity": "sha512-7RnqIMq572L8PeEzKeBINYEJDDxpcH8JEgLwUqBd3TkofhFRbkq4QLR0u+36avGAhCRbk2nnmjcW9SE531hPDg==", + "dev": true, + "requires": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + } + } + }, "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -49442,15 +52662,15 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" } }, "json-schema-traverse": { @@ -49458,6 +52678,15 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } } } }, @@ -49468,41 +52697,25 @@ "dev": true }, "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dev": true, "requires": { - "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^3.1.5" } }, "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "temp-fs": { @@ -49514,6 +52727,20 @@ "rimraf": "~2.5.2" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, "rimraf": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", @@ -49550,21 +52777,21 @@ } }, "terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.31.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", + "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "dependencies": { "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "source-map": { @@ -49586,16 +52813,16 @@ } }, "terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "dependencies": { "ajv": { @@ -49611,15 +52838,24 @@ } }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } } } }, @@ -49632,6 +52868,31 @@ "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + } + } + }, + "text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dev": true, + "requires": { + "b4a": "^1.6.4" } }, "text-table": { @@ -49662,9 +52923,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -49703,13 +52964,13 @@ "dev": true }, "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", "dev": true, "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" } }, "tiny-hashes": { @@ -49743,13 +53004,10 @@ } }, "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true }, "to-absolute-glob": { "version": "2.0.2", @@ -49852,9 +53110,9 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true }, "tough-cookie": { @@ -49898,9 +53156,9 @@ "dev": true }, "trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "dev": true }, "tryit": { @@ -49909,21 +53167,21 @@ "integrity": "sha512-6C5h3CE+0qjGp+YKYTs74xR0k/Nw/ePtl/Lp6CCf44hqBQ66qnH1sDFR5mV/Gc48EsrHLB53lCFSffQCkka3kg==" }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "requires": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -49953,9 +53211,9 @@ "dev": true }, "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", "dev": true }, "type-check": { @@ -49988,20 +53246,64 @@ "mime-types": "~2.1.24" } }, + "typed-array-buffer": { + "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, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-length": { + "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, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-offset": { + "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, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-length": { + "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, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, - "optional": true, - "peer": true - }, "typescript-compare": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", @@ -50024,15 +53326,15 @@ } }, "ua-parser-js": { - "version": "0.7.33", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz", - "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==", + "version": "0.7.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.38.tgz", + "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==", "dev": true }, "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==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", "dev": true, "optional": true }, @@ -50117,9 +53419,9 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" }, "unicode-property-aliases-ecmascript": { "version": "2.1.0", @@ -50178,48 +53480,51 @@ } }, "unist-builder": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-3.0.0.tgz", - "integrity": "sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-3.0.1.tgz", + "integrity": "sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ==", "dev": true, "requires": { "@types/unist": "^2.0.0" } }, "unist-util-generated": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.0.tgz", - "integrity": "sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", + "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", "dev": true }, "unist-util-is": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", - "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==", - "dev": true + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0" + } }, "unist-util-position": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.3.tgz", - "integrity": "sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", "dev": true, "requires": { "@types/unist": "^2.0.0" } }, "unist-util-stringify-position": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", - "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", "dev": true, "requires": { "@types/unist": "^2.0.0" } }, "unist-util-visit": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.1.tgz", - "integrity": "sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -50228,9 +53533,9 @@ } }, "unist-util-visit-parents": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz", - "integrity": "sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -50238,9 +53543,9 @@ } }, "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true }, "unpipe": { @@ -50311,6 +53616,12 @@ "setimmediate": "~1.0.4" }, "dependencies": { + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "dev": true + }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -50329,12 +53640,12 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" } }, "uri-js": { @@ -50353,20 +53664,29 @@ "dev": true }, "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", "dev": true, "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" + "punycode": "^1.4.1", + "qs": "^6.11.2" }, "dependencies": { "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", "dev": true + }, + "qs": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.6" + } } } }, @@ -50422,9 +53742,9 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true }, "uvu": { @@ -50440,9 +53760,9 @@ } }, "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", "dev": true }, "v8flags": { @@ -50495,9 +53815,9 @@ } }, "vfile": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", - "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -50506,10 +53826,20 @@ "vfile-message": "^3.0.0" } }, + "vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + } + }, "vfile-message": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", - "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -50517,25 +53847,21 @@ } }, "vfile-reporter": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-7.0.4.tgz", - "integrity": "sha512-4cWalUnLrEnbeUQ+hARG5YZtaHieVK3Jp4iG5HslttkVl+MHunSGNAIrODOTLbtjWsNZJRMCkL66AhvZAYuJ9A==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-7.0.5.tgz", + "integrity": "sha512-NdWWXkv6gcd7AZMvDomlQbK3MqFWL1RlGzMn++/O2TI+68+nqxCPTvLugdOtfSzXmjh+xUyhp07HhlrbJjT+mw==", "dev": true, "requires": { "@types/supports-color": "^8.0.0", "string-width": "^5.0.0", "supports-color": "^9.0.0", "unist-util-stringify-position": "^3.0.0", + "vfile": "^5.0.0", + "vfile-message": "^3.0.0", "vfile-sort": "^3.0.0", "vfile-statistics": "^2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -50553,60 +53879,53 @@ "strip-ansi": "^7.0.1" } }, - "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, "supports-color": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.3.tgz", - "integrity": "sha512-aszYUX/DVK/ed5rFLb/dDinVJrQjG/vmU433wtqVSD800rYsJNWxh2R3USV90aLSU+UsyQkbNeffVLzc6B6foA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", "dev": true } } }, "vfile-sort": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-3.0.0.tgz", - "integrity": "sha512-fJNctnuMi3l4ikTVcKpxTbzHeCgvDhnI44amA3NVDvA6rTC6oKCFpCVyT5n2fFMr3ebfr+WVQZedOCd73rzSxg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-3.0.1.tgz", + "integrity": "sha512-1os1733XY6y0D5x0ugqSeaVJm9lYgj0j5qdcZQFyxlZOSy1jYarL77lLyb5gK4Wqr1d5OxmuyflSO3zKyFnTFw==", "dev": true, "requires": { + "vfile": "^5.0.0", "vfile-message": "^3.0.0" } }, "vfile-statistics": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-2.0.0.tgz", - "integrity": "sha512-foOWtcnJhKN9M2+20AOTlWi2dxNfAoeNIoxD5GXcO182UJyId4QrXa41fWrgcfV3FWTjdEDy3I4cpLVcQscIMA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-2.0.1.tgz", + "integrity": "sha512-W6dkECZmP32EG/l+dp2jCLdYzmnDBIw6jwiLZSER81oR5AHRcVqL+k3Z+pfH1R73le6ayDkJRMk0sutj1bMVeg==", "dev": true, "requires": { + "vfile": "^5.0.0", "vfile-message": "^3.0.0" } }, "video.js": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.20.3.tgz", - "integrity": "sha512-JMspxaK74LdfWcv69XWhX4rILywz/eInOVPdKefpQiZJSMD5O8xXYueqACP2Q5yqKstycgmmEKlJzZ+kVmDciw==", + "version": "7.21.6", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.6.tgz", + "integrity": "sha512-m41TbODrUCToVfK1aljVd296CwDQnCRewpIm5tTXMuV87YYSGw1H+VDOaV45HlpcWSsTWWLF++InDgGJfthfUw==", "dev": true, "requires": { "@babel/runtime": "^7.12.5", - "@videojs/http-streaming": "2.14.3", + "@videojs/http-streaming": "2.16.3", "@videojs/vhs-utils": "^3.0.4", "@videojs/xhr": "2.6.0", "aes-decrypter": "3.1.3", "global": "^4.4.0", "keycode": "^2.2.0", - "m3u8-parser": "4.7.1", - "mpd-parser": "0.21.1", + "m3u8-parser": "4.8.0", + "mpd-parser": "0.22.1", "mux.js": "6.0.1", "safe-json-parse": "4.0.0", "videojs-font": "3.2.0", - "videojs-vtt.js": "^0.15.4" + "videojs-vtt.js": "^0.15.5" }, "dependencies": { "safe-json-parse": { @@ -50651,19 +53970,19 @@ } }, "videojs-playlist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/videojs-playlist/-/videojs-playlist-5.0.0.tgz", - "integrity": "sha512-TM9bytwKqkE05wdWPEKDpkwMGhS/VgMCIsEuNxmX1J1JO9zaTIl4Wm3egf5j1dhIw19oWrqGUV/nK0YNIelCpA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/videojs-playlist/-/videojs-playlist-5.1.2.tgz", + "integrity": "sha512-8YgNq/iL17RLTXpfWAkuhM0Sq4w/x5YPVaNbUycjfqqGL/bp3Nrmc2W0qkPfh0ryB7r4cHfJbtHYP7zlW3ZkdQ==", "dev": true, "requires": { "global": "^4.3.2", - "video.js": "^6 || ^7" + "video.js": "^6 || ^7 || ^8" } }, "videojs-vtt.js": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.4.tgz", - "integrity": "sha512-r6IhM325fcLb1D6pgsMkTQT1PpFdUdYZa1iqk7wJEu+QlibBwATPfPc9Bg8Jiym0GE5yP1AG2rMLu+QMVWkYtA==", + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz", + "integrity": "sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==", "dev": true, "requires": { "global": "^4.3.1" @@ -50751,6 +54070,12 @@ "vinyl": "^2.0.0" }, "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -50778,9 +54103,9 @@ "dev": true }, "vue-template-compiler": { - "version": "2.7.13", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.13.tgz", - "integrity": "sha512-jYM6TClwDS9YqP48gYrtAtaOhRKkbYmbzE+Q51gX5YDr777n7tNI/IZk4QV4l/PjQPNh/FVa/E92sh/RqKMrog==", + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, "optional": true, "requires": { @@ -50866,9 +54191,9 @@ } }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -50884,6 +54209,12 @@ "defaults": "^1.0.3" } }, + "web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "dev": true + }, "web-streams-polyfill": { "version": "4.0.0-beta.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", @@ -50891,188 +54222,133 @@ "dev": true }, "webdriver": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.29.1.tgz", - "integrity": "sha512-D3gkbDUxFKBJhNHRfMriWclooLbNavVQC1MRvmENAgPNKaHnFn+M+WtP9K2sEr0XczLGNlbOzT7CKR9K5UXKXA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.39.0.tgz", + "integrity": "sha512-Kc3+SfiH4ufyrIht683VT2vnJocx0pfH8rYdyPvEh1b2OYewtFTHK36k9rBDHZiBmk6jcSXs4M2xeFgOuon9Lg==", "dev": true, "requires": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", - "@wdio/config": "8.29.1", - "@wdio/logger": "8.28.0", - "@wdio/protocols": "8.24.12", - "@wdio/types": "8.29.1", - "@wdio/utils": "8.29.1", + "@wdio/config": "8.39.0", + "@wdio/logger": "8.38.0", + "@wdio/protocols": "8.38.0", + "@wdio/types": "8.39.0", + "@wdio/utils": "8.39.0", "deepmerge-ts": "^5.1.0", "got": "^12.6.1", "ky": "^0.33.0", "ws": "^8.8.0" }, "dependencies": { - "@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.1" - } - }, - "cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "dev": true - }, - "cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - } - }, - "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 - }, - "got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dev": true, - "requires": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - } - }, - "http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "@wdio/types": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", + "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", "dev": true, "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" + "@types/node": "^20.1.0" } }, - "lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "dev": true - }, - "mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "dev": true - }, - "normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "dev": true - }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "dev": true - }, - "responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dev": true, - "requires": { - "lowercase-keys": "^3.0.0" + "@wdio/utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", + "dev": true, + "requires": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.38.0", + "@wdio/types": "8.39.0", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.5.0", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" } } } }, "webdriverio": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.25.4.tgz", - "integrity": "sha512-agkgwn2SIk5cAJ03uue1GnGZcUZUDN3W4fUMY9/VfO8bVJrPEgWg31bPguEWPu+YhEB/aBJD8ECxJ3OEKdy4qQ==", + "version": "7.36.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.36.0.tgz", + "integrity": "sha512-OTYmKBF7eFKBX39ojUIEzw7AlE1ZRJiFoMTtEQaPMuPzZCP2jUBq6Ey38nuZrYXLkXn3/le9a14pNnKSM0n56w==", "dev": true, "requires": { "@types/aria-query": "^5.0.0", "@types/node": "^18.0.0", - "@wdio/config": "7.25.4", - "@wdio/logger": "7.19.0", - "@wdio/protocols": "7.22.0", - "@wdio/repl": "7.25.4", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@wdio/config": "7.33.0", + "@wdio/logger": "7.26.0", + "@wdio/protocols": "7.27.0", + "@wdio/repl": "7.33.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "archiver": "^5.0.0", - "aria-query": "^5.0.0", + "aria-query": "^5.2.1", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools": "7.25.4", - "devtools-protocol": "^0.0.1061995", - "fs-extra": "^10.0.0", + "devtools": "7.35.0", + "devtools-protocol": "^0.0.1260888", + "fs-extra": "^11.1.1", "grapheme-splitter": "^1.0.2", "lodash.clonedeep": "^4.5.0", "lodash.isobject": "^3.0.2", "lodash.isplainobject": "^4.0.6", "lodash.zip": "^4.2.0", - "minimatch": "^5.0.0", + "minimatch": "^6.0.4", "puppeteer-core": "^13.1.3", "query-selector-shadow-dom": "^1.0.0", "resq": "^1.9.1", "rgb2hex": "0.2.5", "serialize-error": "^8.0.0", - "webdriver": "7.25.4" + "webdriver": "7.33.0" }, "dependencies": { - "@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "@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 }, + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/node": { + "version": "18.19.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.34.tgz", + "integrity": "sha512-eXF4pfBNV5DAMKGbI02NnDtWrQ40hAN558/2vvS4gMpMIxaf6JmD7YjnZbq0Q9TDSSkKBamime8ewRoomHdt4g==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, "@wdio/config": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.25.4.tgz", - "integrity": "sha512-vb0emDtD9FbFh/yqW6oNdo2iuhQp8XKj6GX9fyy9v4wZgg3B0HPMVJxhIfcoHz7LMBWlHSo9YdvhFI5EQHRLBA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.33.0.tgz", + "integrity": "sha512-SaCZNKrDtBghf7ujyaxTiU4pBW+1Kms32shSoXpJ/wFop6/MiA7nb19qpUPoJtEDw5/NOKevUKz8nBMBXphiew==", "dev": true, "requires": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@types/glob": "^8.1.0", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "deepmerge": "^4.0.0", "glob": "^8.0.3" } }, "@wdio/logger": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.19.0.tgz", - "integrity": "sha512-xR7SN/kGei1QJD1aagzxs3KMuzNxdT/7LYYx+lt6BII49+fqL/SO+5X0FDCZD0Ds93AuQvvz9eGyzrBI2FFXmQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", + "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -51082,24 +54358,24 @@ } }, "@wdio/protocols": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.22.0.tgz", - "integrity": "sha512-8EXRR+Ymdwousm/VGtW3H1hwxZ/1g1H99A1lF0U4GuJ5cFWHCd0IVE5H31Z52i8ZruouW8jueMkGZPSo2IIUSQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", + "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", "dev": true }, "@wdio/repl": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.25.4.tgz", - "integrity": "sha512-kYhj9gLsUk4HmlXLqkVre+gwbfvw9CcnrHjqIjrmMS4mR9D8zvBb5CItb3ZExfPf9jpFzIFREbCAYoE9x/kMwg==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.33.0.tgz", + "integrity": "sha512-17KM9NCg+UVpZNbS8koT/917vklF5M8IQnw0kGwmJEo444ifTMxmLwQymbS2ovQKAKAQxlfdM7bpqMeI15kzsQ==", "dev": true, "requires": { - "@wdio/utils": "7.25.4" + "@wdio/utils": "7.33.0" } }, "@wdio/types": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.25.4.tgz", - "integrity": "sha512-muvNmq48QZCvocctnbe0URq2FjJjUPIG4iLoeMmyF0AQgdbjaUkMkw3BHYNHVTbSOU9WMsr2z8alhj/I2H6NRQ==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.33.0.tgz", + "integrity": "sha512-tNcuN5Kl+i5CffaeTYV1omzAo4rVjiI1m9raIA8ph6iVteWdCzYv2/ImpGgFiBPb7Mf6VokU3+q9Slh5Jitaww==", "dev": true, "requires": { "@types/node": "^18.0.0", @@ -51107,13 +54383,13 @@ } }, "@wdio/utils": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.25.4.tgz", - "integrity": "sha512-8iwQDk+foUqSzKZKfhLxjlCKOkfRJPNHaezQoevNgnrTq/t0ek+ldZCATezb9B8jprAuP4mgS9xi22akc6RkzA==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.33.0.tgz", + "integrity": "sha512-4kQQ86EvEN6fBY5+u7M08cT6LfJtpk1rHd203xyxmbmV9lpNv/OCl4CsC+SD0jGT0aZZqYSIJ/Pil07pAh5K0g==", "dev": true, "requires": { - "@wdio/logger": "7.19.0", - "@wdio/types": "7.25.4", + "@wdio/logger": "7.26.0", + "@wdio/types": "7.33.0", "p-iteration": "^1.1.8" } }, @@ -51135,6 +54411,27 @@ "balanced-match": "^1.0.0" } }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true + }, + "cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -51160,10 +54457,30 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "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, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -51171,6 +54488,36 @@ "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" + }, + "dependencies": { + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" } }, "has-flag": { @@ -51179,21 +54526,77 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, "ky": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz", "integrity": "sha512-X/u76z4JtDVq10u1JA5UQfatPxgPaVDMYTrgHyiTpGN2z4TMEJkIHsoSBBSg9SWZEIXTKsi9kHgiQ9o3Y/4yog==", "dev": true }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", + "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true + }, + "responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -51204,17 +54607,17 @@ } }, "webdriver": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.25.4.tgz", - "integrity": "sha512-6nVDwenh0bxbtUkHASz9B8T9mB531Fn1PcQjUGj2t5dolLPn6zuK1D7XYVX40hpn6r3SlYzcZnEBs4X0az5Txg==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.33.0.tgz", + "integrity": "sha512-cyMRAVUHgQhEBHojOeNet2e8GkfyvvjpioNCPcF6qUtT+URdagr8Mh0t4Fs+Jr0tpuMqFnw70xZexAcV/6I/jg==", "dev": true, "requires": { "@types/node": "^18.0.0", - "@wdio/config": "7.25.4", - "@wdio/logger": "7.19.0", - "@wdio/protocols": "7.22.0", - "@wdio/types": "7.25.4", - "@wdio/utils": "7.25.4", + "@wdio/config": "7.33.0", + "@wdio/logger": "7.26.0", + "@wdio/protocols": "7.27.0", + "@wdio/types": "7.33.0", + "@wdio/utils": "7.33.0", "got": "^11.0.2", "ky": "0.30.0", "lodash.merge": "^4.6.1" @@ -51229,47 +54632,47 @@ "dev": true }, "webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.92.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.0.tgz", + "integrity": "sha512-Bsw2X39MYIgxouNATyVpCNVWBCuUwDgWtN78g6lSdPJRLaQ/PUVm/oXcaRAyY/sMFoKFQrsPeqvTizWtq7QPCA==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "requires": {} }, @@ -51285,10 +54688,16 @@ "uri-js": "^4.2.2" } }, + "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 + }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -51299,60 +54708,29 @@ } }, "webpack-bundle-analyzer": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz", - "integrity": "sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", "dev": true, "requires": { + "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", - "lodash": "^4.17.20", + "html-escaper": "^2.0.2", "opener": "^1.5.2", - "sirv": "^1.0.7", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", "ws": "^7.3.1" }, "dependencies": { "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true - }, - "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, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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, - "requires": { - "color-name": "~1.1.4" - } - }, - "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==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "commander": { @@ -51361,25 +54739,16 @@ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true }, - "has-flag": { + "escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "requires": {} } @@ -51532,12 +54901,12 @@ } }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, "requires": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" } }, "which-boxed-primitive": { @@ -51554,15 +54923,15 @@ } }, "which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "requires": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" } }, "which-module": { @@ -51572,23 +54941,22 @@ "dev": true }, "which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "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, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" } }, "winston-transport": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz", - "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", "dev": true, "requires": { "logform": "^2.3.2", @@ -51610,9 +54978,9 @@ } }, "word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wordwrap": { @@ -51628,9 +54996,9 @@ "dev": true }, "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==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -51661,6 +55029,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } } } }, @@ -51698,6 +55075,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } } } }, @@ -51714,23 +55100,12 @@ "dev": true, "requires": { "mkdirp": "^0.5.1" - }, - "dependencies": { - "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, - "requires": { - "minimist": "^1.2.6" - } - } } }, "ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "requires": {} }, @@ -51747,10 +55122,9 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { "version": "1.3.3", @@ -51782,6 +55156,12 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -51791,36 +55171,68 @@ } }, "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.3.tgz", + "integrity": "sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw==", "dev": true, "requires": { "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "pend": "~1.2.0" } }, "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true }, "zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", "readable-stream": "^3.6.0" }, "dependencies": { + "archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "requires": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -51831,9 +55243,9 @@ } }, "zwitch": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", - "integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "dev": true } } diff --git a/package.json b/package.json index 34d1eb4a593..6cbff559615 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,17 @@ { "name": "prebid.js", - "version": "8.52.0-pre", + "version": "9.6.0-pre", "description": "Header Bidding Management Library", - "main": "src/prebid.js", + "main": "src/prebid.public.js", + "exports": { + ".": "./src/prebid.public.js", + "./prebid.js": "./src/prebid.public.js", + "./prebid": "./src/prebid.public.js", + "./.babelrc.js": "./.babelrc.js", + "./babelConfig.js": "./babelConfig.js", + "./modules/*": "./modules/*", + "./modules/*.js": "./modules/*.js" + }, "scripts": { "serve": "gulp serve", "test": "gulp test", @@ -30,10 +39,10 @@ ], "globalVarName": "pbjs", "defineGlobal": true, - "author": "the prebid.js contributors", + "author": "The prebid.js contributors", "license": "Apache-2.0", "engines": { - "node": ">=12.0.0" + "node": ">=20.0.0" }, "devDependencies": { "@babel/eslint-parser": "^7.16.5", @@ -57,7 +66,7 @@ "eslint": "^7.27.0", "eslint-config-standard": "^10.2.1", "eslint-plugin-import": "^2.20.2", - "eslint-plugin-jsdoc": "^38.1.6", + "eslint-plugin-jsdoc": "^48.5.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prebid": "file:./plugins/eslint", "eslint-plugin-promise": "^5.1.0", @@ -65,7 +74,7 @@ "execa": "^1.0.0", "faker": "^5.5.3", "fs.extra": "^1.3.2", - "gulp": "^4.0.0", + "gulp": "^4.0.2", "gulp-clean": "^0.4.0", "gulp-concat": "^2.6.0", "gulp-connect": "^5.7.0", @@ -104,8 +113,9 @@ "morgan": "^1.10.0", "node-html-parser": "^6.1.5", "opn": "^5.4.0", + "querystring": "^0.2.1", "resolve-from": "^5.0.0", - "sinon": "^4.1.3", + "sinon": "^4.5.0", "through2": "^4.0.2", "url": "^0.11.0", "url-parse": "^1.0.5", @@ -121,13 +131,12 @@ "yargs": "^1.3.1" }, "dependencies": { - "@babel/core": "^7.16.7", + "@babel/core": "^7.24.6", "@babel/plugin-transform-runtime": "^7.18.9", "@babel/preset-env": "^7.16.8", "@babel/runtime": "^7.18.9", "core-js": "^3.13.0", "core-js-pure": "^3.13.0", - "criteo-direct-rsa-validate": "^1.1.0", "crypto-js": "^4.2.0", "dlv": "1.1.3", "dset": "3.1.2", diff --git a/plugins/eslint/index.js b/plugins/eslint/index.js new file mode 100644 index 00000000000..f8acf54683b --- /dev/null +++ b/plugins/eslint/index.js @@ -0,0 +1,104 @@ +const _ = require('lodash'); +const { flagErrors } = require('./validateImports.js'); +const noGlobal = require('eslint/lib/rules/no-restricted-globals.js'); + +function getName(node) { + return node.type === 'Literal' ? node.value : node.name; +} + +module.exports = { + rules: { + 'validate-imports': { + meta: { + docs: { + description: 'validates module imports can be found without custom webpack resolvers, are in module whitelist, and not module entry points' + } + }, + create: function(context) { + return { + "CallExpression[callee.name='require']"(node) { + let importPath = _.get(node, ['arguments', 0, 'value']); + if (importPath) { + flagErrors(context, node, importPath); + } + }, + ImportDeclaration(node) { + let importPath = node.source.value.trim(); + flagErrors(context, node, importPath); + }, + 'ExportNamedDeclaration[source]'(node) { + let importPath = node.source.value.trim(); + flagErrors(context, node, importPath); + } + }; + } + }, + 'no-member': { + meta: { + schema: { + type: 'array', + items: { + type: 'object', + properties: { + target: { type: 'string' }, + name: { type: 'string' }, + message: { type: 'string' } + }, + required: ['name', 'message'], + additionalProperties: false + }, + uniqueItems: true, + minItems: 1 + }, + + messages: { + noMember: "Unexpected use of '{{target}}.{{name}}'. {{message}}", + } + }, + + create(context) { + return { + MemberExpression(node) { + context.options.forEach(({name, target, message}) => { + if (target === node.object.name && getName(node.property) === name) { + context.report({ + node, + messageId: 'noMember', + data: { + name, + target: target || '', + message + } + }); + } + }); + } + } + } + }, + 'no-global': Object.assign({}, noGlobal, { + // no-restricted-global that also looks for `window.GLOBAL` + create(context) { + const globals = Object.fromEntries( + context.options.map(option => typeof option === 'string' ? [option, null] : [option.name, option.message]) + ) + return Object.assign(noGlobal.create(context), { + MemberExpression(node) { + const name = getName(node.property); + if (node.object.name === 'window' && globals.hasOwnProperty(name)) { + const customMessage = globals[name]; + context.report({ + node, + messageId: customMessage == null ? 'defaultMessage' : 'customMessage', + data: { + name, + customMessage + } + }) + } + } + }) + } + }), + } +}; diff --git a/plugins/eslint/package.json b/plugins/eslint/package.json index fa18ad83718..446f63945fa 100644 --- a/plugins/eslint/package.json +++ b/plugins/eslint/package.json @@ -2,7 +2,7 @@ "name": "eslint-plugin-prebid", "version": "1.0.0", "description": "validates module imports can be found without custom webpack resolvers, are in module whitelist, and not module entry points", - "main": "validateImports.js", + "main": "index.js", "author": "the prebid.js contributors", "license": "Apache-2.0" } diff --git a/plugins/eslint/validateImports.js b/plugins/eslint/validateImports.js index b936f44aee7..e38f0532238 100644 --- a/plugins/eslint/validateImports.js +++ b/plugins/eslint/validateImports.js @@ -53,31 +53,5 @@ function flagErrors(context, node, importPath) { } module.exports = { - rules: { - 'validate-imports': { - meta: { - docs: { - description: 'validates module imports can be found without custom webpack resolvers, are in module whitelist, and not module entry points' - } - }, - create: function(context) { - return { - "CallExpression[callee.name='require']"(node) { - let importPath = _.get(node, ['arguments', 0, 'value']); - if (importPath) { - flagErrors(context, node, importPath); - } - }, - ImportDeclaration(node) { - let importPath = node.source.value.trim(); - flagErrors(context, node, importPath); - }, - 'ExportNamedDeclaration[source]'(node) { - let importPath = node.source.value.trim(); - flagErrors(context, node, importPath); - } - } - } - } - } -}; + flagErrors +} diff --git a/src/adRendering.js b/src/adRendering.js index 33f7fe9252c..9eb894ec190 100644 --- a/src/adRendering.js +++ b/src/adRendering.js @@ -1,6 +1,15 @@ -import {createIframe, deepAccess, inIframe, insertElement, logError, logWarn, replaceMacros} from './utils.js'; +import { + createIframe, + createInvisibleIframe, + deepAccess, + inIframe, + insertElement, + logError, + logWarn, + replaceMacros +} from './utils.js'; import * as events from './events.js'; -import { AD_RENDER_FAILED_REASON, BID_STATUS, EVENTS, MESSAGES } from './constants.js'; +import {AD_RENDER_FAILED_REASON, BID_STATUS, EVENTS, MESSAGES, PB_LOCATOR} from './constants.js'; import {config} from './config.js'; import {executeRenderer, isRendererRequired} from './Renderer.js'; import {VIDEO} from './mediaTypes.js'; @@ -235,3 +244,21 @@ export function renderAdDirect(doc, adId, options) { fail(EXCEPTION, e.message); } } + +/** + * Insert an invisible, named iframe that can be used by creatives to locate the window Prebid is running in + * (by looking for one that has `.frames[PB_LOCATOR]` defined). + * This is necessary because in some situations creatives may be rendered inside nested iframes - Prebid is not necessarily + * in the immediate parent window. + */ +export function insertLocatorFrame() { + if (!window.frames[PB_LOCATOR]) { + if (!document.body) { + window.requestAnimationFrame(insertLocatorFrame); + } else { + const frame = createInvisibleIframe(); + frame.name = PB_LOCATOR; + document.body.appendChild(frame); + } + } +} diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index dae0902d4cc..ac26883ae99 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -361,18 +361,7 @@ export function newBidder(spec) { } } -// Transition from 'fledge' to 'paapi' -// TODO: remove this in prebid 9 -const PAAPI_PROPS = ['paapi', 'fledgeAuctionConfigs']; -const RESPONSE_PROPS = ['bids'].concat(PAAPI_PROPS); - -function getPaapiConfigs(adapterResponse) { - const [paapi, fledge] = PAAPI_PROPS.map(prop => adapterResponse[prop]); - if (paapi != null && fledge != null) { - throw new Error(`Adapter response should use ${PAAPI_PROPS[0]} over ${PAAPI_PROPS[1]}, not both`); - } - return paapi ?? fledge; -} +const RESPONSE_PROPS = ['bids', 'paapi'] /** * Run a set of bid requests - that entails converting them to HTTP requests, sending @@ -443,7 +432,7 @@ export const processBidderRequests = hook('sync', function (spec, bids, bidderRe let bids, paapiConfigs; if (response && !Object.keys(response).some(key => !RESPONSE_PROPS.includes(key))) { bids = response.bids; - paapiConfigs = getPaapiConfigs(response); + paapiConfigs = response.paapi; } else { bids = response; } diff --git a/src/adloader.js b/src/adloader.js index b746c59a1cc..79ea6e017bb 100644 --- a/src/adloader.js +++ b/src/adloader.js @@ -4,36 +4,39 @@ import { logError, logWarn, insertElement, setScriptAttributes } from './utils.j const _requestCache = new WeakMap(); // The below list contains modules or vendors whom Prebid allows to load external JS. const _approvedLoadExternalJSList = [ + // Prebid maintained modules: 'debugging', - 'adloox', - 'criteo', 'outstream', + // Bid Modules - only exception is on rendering edge cases, to clean up in Prebid 10: + 'improvedigital', + 'showheroes-bs', + // RTD modules: + 'aaxBlockmeter', 'adagio', - 'spotx', + 'adloox', + 'akamaidap', + 'arcspan', + 'airgrid', 'browsi', 'brandmetrics', - 'justtag', - 'tncId', - 'akamaidap', - 'ftrackId', - 'inskin', + 'clean.io', + 'confiant', + 'contxtful', 'hadron', + 'mediafilter', 'medianet', - 'improvedigital', 'azerionedge', - 'aaxBlockmeter', - 'confiant', - 'arcspan', - 'airgrid', - 'clean.io', 'a1Media', 'geoedge', - 'mediafilter', 'qortex', 'dynamicAdBoost', - 'contxtful', - 'id5', '51Degrees', + 'symitridap', + // UserId Submodules + 'justtag', + 'tncId', + 'ftrackId', + 'id5', ]; /** diff --git a/src/ajax.js b/src/ajax.js index 92bff6dd527..7f9857ad18d 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -104,6 +104,7 @@ function toXHR({status, statusText = '', headers, url}, responseText) { return xml; } return { + // eslint-disable-next-line prebid/no-global readyState: XMLHttpRequest.DONE, status, statusText, @@ -130,7 +131,7 @@ export function attachCallbacks(fetchPm, callback) { success: typeof callback === 'function' ? callback : () => null, error: (e, x) => logError('Network error', e, x) }; - fetchPm.then(response => response.text().then((responseText) => [response, responseText])) + return fetchPm.then(response => response.text().then((responseText) => [response, responseText])) .then(([response, responseText]) => { const xhr = toXHR(response, responseText); response.ok || response.status === 304 ? success(responseText, xhr) : error(response.statusText, xhr); @@ -147,5 +148,19 @@ export function ajaxBuilder(timeout = 3000, {request, done} = {}) { }; } +/** + * simple wrapper around sendBeacon such that invocations of navigator.sendBeacon can be centrally maintained. + * verifies that the navigator and sendBeacon are defined for maximum compatibility + * @param {string} url The URL that will receive the data. Can be relative or absolute. + * @param {*} data An ArrayBuffer, a TypedArray, a DataView, a Blob, a string literal or object, a FormData or a URLSearchParams object containing the data to send. + * @returns {boolean} true if the user agent successfully queued the data for transfer. Otherwise, it returns false. + */ +export function sendBeacon(url, data) { + if (!window.navigator || !window.navigator.sendBeacon) { + return false; + } + return window.navigator.sendBeacon(url, data); +} + export const ajax = ajaxBuilder(); export const fetch = fetcherFactory(); diff --git a/src/auction.js b/src/auction.js index 881dee9f2de..b422ffa7333 100644 --- a/src/auction.js +++ b/src/auction.js @@ -82,7 +82,7 @@ import { } from './utils.js'; import {getPriceBucketString} from './cpmBucketManager.js'; import {getNativeTargeting, isNativeResponse, setNativeResponseProperties} from './native.js'; -import {getCacheUrl, store} from './videoCache.js'; +import {batchAndStore} from './videoCache.js'; import {Renderer} from './Renderer.js'; import {config} from './config.js'; import {userSync} from './userSync.js'; @@ -94,7 +94,7 @@ import {auctionManager} from './auctionManager.js'; import {bidderSettings} from './bidderSettings.js'; import * as events from './events.js'; import adapterManager from './adapterManager.js'; -import { EVENTS, GRANULARITY_OPTIONS, JSON_MAPPING, REJECTION_REASON, S2S, TARGETING_KEYS } from './constants.js'; +import {EVENTS, GRANULARITY_OPTIONS, JSON_MAPPING, REJECTION_REASON, S2S, TARGETING_KEYS} from './constants.js'; import {defer, GreedyPromise} from './utils/promise.js'; import {useMetrics} from './utils/perfMetrics.js'; import {adjustCpm} from './utils/cpm.js'; @@ -580,68 +580,10 @@ function tryAddVideoBid(auctionInstance, bidResponse, afterBidAdded, {index = au } } -const _storeInCache = (batch) => { - store(batch.map(entry => entry.bidResponse), function (error, cacheIds) { - cacheIds.forEach((cacheId, i) => { - const { auctionInstance, bidResponse, afterBidAdded } = batch[i]; - if (error) { - logWarn(`Failed to save to the video cache: ${error}. Video bid must be discarded.`); - } else { - if (cacheId.uuid === '') { - logWarn(`Supplied video cache key was already in use by Prebid Cache; caching attempt was rejected. Video bid must be discarded.`); - } else { - bidResponse.videoCacheKey = cacheId.uuid; - if (!bidResponse.vastUrl) { - bidResponse.vastUrl = getCacheUrl(bidResponse.videoCacheKey); - } - addBidToAuction(auctionInstance, bidResponse); - afterBidAdded(); - } - } - }); - }); -}; - -const storeInCache = FEATURES.VIDEO ? _storeInCache : () => {}; - -let batchSize, batchTimeout; -config.getConfig('cache', (cacheConfig) => { - batchSize = typeof cacheConfig.cache.batchSize === 'number' && cacheConfig.cache.batchSize > 0 - ? cacheConfig.cache.batchSize - : 1; - batchTimeout = typeof cacheConfig.cache.batchTimeout === 'number' && cacheConfig.cache.batchTimeout > 0 - ? cacheConfig.cache.batchTimeout - : 0; -}); - -export const batchingCache = (timeout = setTimeout, cache = storeInCache) => { - let batches = [[]]; - let debouncing = false; - const noTimeout = cb => cb(); - - return function(auctionInstance, bidResponse, afterBidAdded) { - const batchFunc = batchTimeout > 0 ? timeout : noTimeout; - if (batches[batches.length - 1].length >= batchSize) { - batches.push([]); - } - - batches[batches.length - 1].push({auctionInstance, bidResponse, afterBidAdded}); - - if (!debouncing) { - debouncing = true; - batchFunc(() => { - batches.forEach(cache); - batches = [[]]; - debouncing = false; - }, batchTimeout); - } - } -}; - -const batchAndStore = batchingCache(); - export const callPrebidCache = hook('async', function(auctionInstance, bidResponse, afterBidAdded, videoMediaType) { - batchAndStore(auctionInstance, bidResponse, afterBidAdded); + if (FEATURES.VIDEO) { + batchAndStore(auctionInstance, bidResponse, afterBidAdded); + } }, 'callPrebidCache'); /** diff --git a/src/config.js b/src/config.js index 21c34cf34d2..e9c37a8d329 100644 --- a/src/config.js +++ b/src/config.js @@ -38,7 +38,7 @@ const DEFAULT_DEVICE_ACCESS = true; const DEFAULT_MAX_NESTED_IFRAMES = 10; const DEFAULT_MAXBID_VALUE = 5000 -const DEFAULT_TIMEOUTBUFFER = 400; +const DEFAULT_IFRAMES_CONFIG = {}; export const RANDOM = 'random'; const FIXED = 'fixed'; @@ -155,15 +155,16 @@ export function newConfig() { */ deviceAccess: DEFAULT_DEVICE_ACCESS, - // timeout buffer to adjust for bidder CDN latency - timeoutBuffer: DEFAULT_TIMEOUTBUFFER, disableAjaxTimeout: DEFAULT_DISABLE_AJAX_TIMEOUT, // default max nested iframes for referer detection maxNestedIframes: DEFAULT_MAX_NESTED_IFRAMES, // default max bid - maxBid: DEFAULT_MAXBID_VALUE + maxBid: DEFAULT_MAXBID_VALUE, + userSync: { + topics: DEFAULT_IFRAMES_CONFIG + } }; Object.defineProperties(newConfig, diff --git a/src/consentHandler.js b/src/consentHandler.js index 19137d9a422..87d1e1a6e23 100644 --- a/src/consentHandler.js +++ b/src/consentHandler.js @@ -10,14 +10,6 @@ import {config} from './config.js'; */ export const VENDORLESS_GVLID = Object.freeze({}); -/** - * Placeholder gvlid for when device.ext.cdep is present (Privacy Sandbox cookie deprecation label). When this value is used as gvlid, the gdpr - * enforcement module will look to see that publisher consent was given. - * - * see https://github.com/prebid/Prebid.js/issues/10516 - */ -export const FIRST_PARTY_GVLID = Object.freeze({}); - export class ConsentHandler { #enabled; #data; @@ -108,7 +100,6 @@ class UspConsentHandler extends ConsentHandler { const consentData = this.getConsentData(); if (consentData && this.generatedTime) { return { - usp: consentData, generatedAt: this.generatedTime }; } diff --git a/src/constants.js b/src/constants.js index 4ca5f6a1b12..bb20f1b66b9 100644 --- a/src/constants.js +++ b/src/constants.js @@ -193,3 +193,5 @@ export const MESSAGES = { NATIVE: 'Prebid Native', EVENT: 'Prebid Event' }; + +export const PB_LOCATOR = '__pb_locator__'; diff --git a/src/debugging.js b/src/debugging.js index f5d13d1a134..045855ccb28 100644 --- a/src/debugging.js +++ b/src/debugging.js @@ -73,6 +73,7 @@ export const reset = ctl.reset; export function loadSession() { let storage = null; try { + // eslint-disable-next-line prebid/no-global storage = window.sessionStorage; } catch (e) {} diff --git a/src/fpd/enrichment.js b/src/fpd/enrichment.js index 65c3db65974..5024a0ee184 100644 --- a/src/fpd/enrichment.js +++ b/src/fpd/enrichment.js @@ -33,7 +33,6 @@ export const enrichFPD = hook('sync', (fpd) => { return GreedyPromise.all(promArr) .then(([ortb2, sua, cdep]) => { const ri = dep.getRefererInfo(); - mergeLegacySetConfigs(ortb2); Object.entries(ENRICHMENTS).forEach(([section, getEnrichments]) => { const data = getEnrichments(ortb2, ri); if (data && Object.keys(data).length > 0) { @@ -64,17 +63,6 @@ export const enrichFPD = hook('sync', (fpd) => { }); }); -function mergeLegacySetConfigs(ortb2) { - // merge in values from "legacy" setConfig({app, site, device}) - // TODO: deprecate these eventually - ['app', 'site', 'device'].forEach(prop => { - const cfg = config.getConfig(prop); - if (cfg != null) { - ortb2[prop] = mergeDeep({}, cfg, ortb2[prop]); - } - }) -} - function winFallback(fn) { try { return fn(dep.getWindowTop()); diff --git a/src/fpd/navigator.js b/src/fpd/navigator.js new file mode 100644 index 00000000000..80025f88640 --- /dev/null +++ b/src/fpd/navigator.js @@ -0,0 +1,29 @@ +export function getHLen(win = window) { + let hLen; + try { + hLen = win.top.history.length; + } catch (error) { + hLen = undefined; + } + return hLen; +} + +export function getHC(win = window) { + let hc; + try { + hc = win.top.navigator.hardwareConcurrency; + } catch (error) { + hc = undefined; + } + return hc; +} + +export function getDM(win = window) { + let dm; + try { + dm = win.top.navigator.deviceMemory; + } catch (error) { + dm = undefined; + } + return dm; +}; diff --git a/src/prebid.js b/src/prebid.js index df8ce019ed1..e91af3e4d04 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -39,7 +39,7 @@ import {newMetrics, useMetrics} from './utils/perfMetrics.js'; import {defer, GreedyPromise} from './utils/promise.js'; import {enrichFPD} from './fpd/enrichment.js'; import {allConsent} from './consentHandler.js'; -import {renderAdDirect} from './adRendering.js'; +import {insertLocatorFrame, renderAdDirect} from './adRendering.js'; import {getHighestCpm} from './utils/reducers.js'; import {fillVideoDefaults} from './video.js'; @@ -138,10 +138,29 @@ function validateVideoMediaType(adUnit) { } function validateNativeMediaType(adUnit) { + function err(msg) { + logError(`Error in adUnit "${adUnit.code}": ${msg}. Removing native request from ad unit`, adUnit); + delete validatedAdUnit.mediaTypes.native; + return validatedAdUnit; + } + function checkDeprecated(onDeprecated) { + for (const key of ['sendTargetingKeys', 'types']) { + if (native.hasOwnProperty(key)) { + const res = onDeprecated(key); + if (res) return res; + } + } + } const validatedAdUnit = deepClone(adUnit); const native = validatedAdUnit.mediaTypes.native; // if native assets are specified in OpenRTB format, remove legacy assets and print a warn. if (native.ortb) { + if (native.ortb.assets?.some(asset => !isNumber(asset.id) || asset.id < 0 || asset.id % 1 !== 0)) { + return err('native asset ID must be a nonnegative integer'); + } + if (checkDeprecated(key => err(`ORTB native requests cannot specify "${key}"`))) { + return validatedAdUnit; + } const legacyNativeKeys = Object.keys(NATIVE_KEYS).filter(key => NATIVE_KEYS[key].includes('hb_native_')); const nativeKeys = Object.keys(native); const intersection = nativeKeys.filter(nativeKey => legacyNativeKeys.includes(nativeKey)); @@ -149,6 +168,8 @@ function validateNativeMediaType(adUnit) { logError(`when using native OpenRTB format, you cannot use legacy native properties. Deleting ${intersection} keys from request.`); intersection.forEach(legacyKey => delete validatedAdUnit.mediaTypes.native[legacyKey]); } + } else { + checkDeprecated(key => `mediaTypes.native.${key} is deprecated, consider using native ORTB instead`, adUnit); } if (native.image && native.image.sizes && !Array.isArray(native.image.sizes)) { logError('Please use an array of sizes for native.image.sizes field. Removing invalid mediaTypes.native.image.sizes property from request.'); @@ -402,26 +423,7 @@ pbjsInstance.setTargetingForGPTAsync = function (adUnit, customSlotMatching) { logError('window.googletag is not defined on the page'); return; } - - // get our ad unit codes - let targetingSet = targeting.getAllTargeting(adUnit); - - // first reset any old targeting - targeting.resetPresetTargeting(adUnit, customSlotMatching); - - // now set new targeting keys - targeting.setTargetingForGPT(targetingSet, customSlotMatching); - - Object.keys(targetingSet).forEach((adUnitCode) => { - Object.keys(targetingSet[adUnitCode]).forEach((targetingKey) => { - if (targetingKey === 'hb_adid') { - auctionManager.setStatusForBids(targetingSet[adUnitCode][targetingKey], BID_STATUS.BID_TARGETING_SET); - } - }); - }); - - // emit event - events.emit(SET_TARGETING, targetingSet); + targeting.setTargetingForGPT(adUnit, customSlotMatching); }; /** @@ -641,7 +643,7 @@ export function executeCallbacks(fn, reqBidsConfigObj) { } } -// This hook will execute all storage callbacks which were registered before gdpr enforcement hook was added. Some bidders, user id modules use storage functions when module is parsed but gdpr enforcement hook is not added at that stage as setConfig callbacks are yet to be called. Hence for such calls we execute all the stored callbacks just before requestBids. At this hook point we will know for sure that gdprEnforcement module is added or not +// This hook will execute all storage callbacks which were registered before gdpr enforcement hook was added. Some bidders, user id modules use storage functions when module is parsed but gdpr enforcement hook is not added at that stage as setConfig callbacks are yet to be called. Hence for such calls we execute all the stored callbacks just before requestBids. At this hook point we will know for sure that tcfControl module is added or not pbjsInstance.requestBids.before(executeCallbacks, 49); /** @@ -867,6 +869,10 @@ pbjsInstance.getHighestCpmBids = function (adUnitCode) { return targeting.getWinningBids(adUnitCode); }; +pbjsInstance.clearAllAuctions = function () { + auctionManager.clearAllAuctions(); +}; + if (FEATURES.VIDEO) { /** * Mark the winning bid as used, should only be used in conjunction with video @@ -974,6 +980,7 @@ function processQueue(queue) { * @alias module:pbjs.processQueue */ pbjsInstance.processQueue = function () { + insertLocatorFrame(); hook.ready(); processQueue(pbjsInstance.que); processQueue(pbjsInstance.cmd); diff --git a/src/prebid.public.js b/src/prebid.public.js new file mode 100644 index 00000000000..f05e671ac24 --- /dev/null +++ b/src/prebid.public.js @@ -0,0 +1 @@ +export {default} from './prebid.js'; diff --git a/src/secureCreatives.js b/src/secureCreatives.js index a33f742b738..9fa01c990c2 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -144,7 +144,7 @@ export function resizeRemoteCreative({adId, adUnitCode, width, height}) { elementStyle.width = getDimension(width) elementStyle.height = getDimension(height); } else { - logWarn(`Unable to locate matching page element for adUnitCode ${adUnitCode}. Can't resize it to ad's dimensions. Please review setup.`); + logError(`Unable to locate matching page element for adUnitCode ${adUnitCode}. Can't resize it to ad's dimensions. Please review setup.`); } }); diff --git a/src/storageManager.js b/src/storageManager.js index 87d714f77b8..493c44f056e 100644 --- a/src/storageManager.js +++ b/src/storageManager.js @@ -18,6 +18,8 @@ export const STORAGE_TYPE_COOKIES = 'cookie'; export let storageCallbacks = []; +/* eslint-disable prebid/no-global */ + /* * Storage manager constructor. Consumers should prefer one of `getStorageManager` or `getCoreStorageManager`. */ @@ -64,6 +66,7 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is const expiresPortion = (expires && expires !== '') ? ` ;expires=${expires}` : ''; const isNone = (sameSite != null && sameSite.toLowerCase() == 'none') const secure = (isNone) ? '; Secure' : ''; + // eslint-disable-next-line prebid/no-member document.cookie = `${key}=${encodeURIComponent(value)}${expiresPortion}; path=/${domainPortion}${sameSite ? `; SameSite=${sameSite}` : ''}${secure}`; } } @@ -85,27 +88,6 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is return schedule(cb, STORAGE_TYPE_COOKIES, done); }; - /** - * @returns {boolean} - */ - const localStorageIsEnabled = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - localStorage.setItem('prebid.cookieTest', '1'); - return localStorage.getItem('prebid.cookieTest') === '1'; - } catch (error) { - } finally { - try { - localStorage.removeItem('prebid.cookieTest'); - } catch (error) {} - } - } - return false; - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - /** * @returns {boolean} */ @@ -119,60 +101,69 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is return schedule(cb, STORAGE_TYPE_COOKIES, done); } - /** - * @param {string} key - * @param {string} value - */ - const setDataInLocalStorage = function (key, value, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - window.localStorage.setItem(key, value); - } - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } + function storageMethods(name) { + const capName = name.charAt(0).toUpperCase() + name.substring(1); + const backend = () => window[name]; - /** - * @param {string} key - * @returns {(string|null)} - */ - const getDataFromLocalStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - return window.localStorage.getItem(key); - } - return null; - } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - - /** - * @param {string} key - */ - const removeDataFromLocalStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - window.localStorage.removeItem(key); + const hasStorage = function (done) { + let cb = function (result) { + if (result && result.valid) { + try { + return !!backend(); + } catch (e) { + logError(`${name} api disabled`); + } + } + return false; } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); - } - /** - * @returns {boolean} - */ - const hasLocalStorage = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - return !!window.localStorage; - } catch (e) { - logError('Local storage api disabled'); + return { + [`has${capName}`]: hasStorage, + [`${name}IsEnabled`](done) { + let cb = function (result) { + if (result && result.valid) { + try { + backend().setItem('prebid.cookieTest', '1'); + return backend().getItem('prebid.cookieTest') === '1'; + } catch (error) { + } finally { + try { + backend().removeItem('prebid.cookieTest'); + } catch (error) {} + } + } + return false; } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); + }, + [`setDataIn${capName}`](key, value, done) { + let cb = function (result) { + if (result && result.valid && hasStorage()) { + backend().setItem(key, value); + } + } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); + }, + [`getDataFrom${capName}`](key, done) { + let cb = function (result) { + if (result && result.valid && hasStorage()) { + return backend().getItem(key); + } + return null; + } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); + }, + [`removeDataFrom${capName}`](key, done) { + let cb = function (result) { + if (result && result.valid && hasStorage()) { + backend().removeItem(key); + } + } + return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); } - return false; } - return schedule(cb, STORAGE_TYPE_LOCALSTORAGE, done); } /** @@ -186,6 +177,7 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is if (result && result.valid) { const all = []; if (hasDeviceAccess()) { + // eslint-disable-next-line prebid/no-member const cookies = document.cookie.split(';'); while (cookies.length) { const cookie = cookies.pop(); @@ -207,12 +199,9 @@ export function newStorageManager({moduleName, moduleType} = {}, {isAllowed = is return { setCookie, getCookie, - localStorageIsEnabled, cookiesAreEnabled, - setDataInLocalStorage, - getDataFromLocalStorage, - removeDataFromLocalStorage, - hasLocalStorage, + ...storageMethods('localStorage'), + ...storageMethods('sessionStorage'), findSimilarCookies } } diff --git a/src/targeting.js b/src/targeting.js index d3fb3878248..9a2ea5d66fa 100644 --- a/src/targeting.js +++ b/src/targeting.js @@ -1,3 +1,21 @@ +import { auctionManager } from './auctionManager.js'; +import { getTTL } from './bidTTL.js'; +import { bidderSettings } from './bidderSettings.js'; +import { config } from './config.js'; +import { + BID_STATUS, + DEFAULT_TARGETING_KEYS, + EVENTS, + JSON_MAPPING, + NATIVE_KEYS, + STATUS, + TARGETING_KEYS +} from './constants.js'; +import * as events from './events.js'; +import { hook } from './hook.js'; +import { ADPOD } from './mediaTypes.js'; +import { NATIVE_TARGETING_KEYS } from './native.js'; +import { find, includes } from './polyfill.js'; import { deepAccess, deepClone, @@ -14,16 +32,7 @@ import { timestamp, uniques, } from './utils.js'; -import {config} from './config.js'; -import {NATIVE_TARGETING_KEYS} from './native.js'; -import {auctionManager} from './auctionManager.js'; -import {ADPOD} from './mediaTypes.js'; -import {hook} from './hook.js'; -import {bidderSettings} from './bidderSettings.js'; -import {find, includes} from './polyfill.js'; -import { BID_STATUS, JSON_MAPPING, DEFAULT_TARGETING_KEYS, TARGETING_KEYS, NATIVE_KEYS, STATUS } from './constants.js'; -import {getHighestCpm, getOldestHighestCpmBid} from './utils/reducers.js'; -import {getTTL} from './bidTTL.js'; +import { getHighestCpm, getOldestHighestCpmBid } from './utils/reducers.js'; var pbTargetingKeys = []; @@ -124,6 +133,22 @@ export function sortByDealAndPriceBucketOrCpm(useCpm = false) { } } +/** + * Return a map where each code in `adUnitCodes` maps to a list of GPT slots that match it. + * + * @param {Array} adUnitCodes + * @param customSlotMatching + * @param getSlots + * @return {Object.} + */ +export function getGPTSlotsForAdUnits(adUnitCodes, customSlotMatching, getSlots = () => window.googletag.pubads().getSlots()) { + return getSlots().reduce((auToSlots, slot) => { + const customMatch = isFn(customSlotMatching) && customSlotMatching(slot); + Object.keys(auToSlots).filter(isFn(customMatch) ? customMatch : isAdUnitCodeMatchingSlot(slot)).forEach(au => auToSlots[au].push(slot)); + return auToSlots; + }, Object.fromEntries(adUnitCodes.map(au => [au, []]))); +} + /** * @typedef {Object.} targeting * @property {string} targeting_key @@ -144,22 +169,13 @@ export function newTargeting(auctionManager) { targeting.resetPresetTargeting = function(adUnitCode, customSlotMatching) { if (isGptPubadsDefined()) { const adUnitCodes = getAdUnitCodes(adUnitCode); - const adUnits = auctionManager.getAdUnits().filter(adUnit => includes(adUnitCodes, adUnit.code)); let unsetKeys = pbTargetingKeys.reduce((reducer, key) => { reducer[key] = null; return reducer; }, {}); - window.googletag.pubads().getSlots().forEach(slot => { - let customSlotMatchingFunc = isFn(customSlotMatching) && customSlotMatching(slot); - // reset only registered adunits - adUnits.forEach(unit => { - if (unit.code === slot.getAdUnitPath() || - unit.code === slot.getSlotElementId() || - (isFn(customSlotMatchingFunc) && customSlotMatchingFunc(unit.code))) { - slot.updateTargetingFromMap(unsetKeys); - } - }); - }); + Object.values(getGPTSlotsForAdUnits(adUnitCodes, customSlotMatching)).forEach((slots) => { + slots.forEach(slot => slot.updateTargetingFromMap(unsetKeys)) + }) } }; @@ -415,27 +431,45 @@ export function newTargeting(auctionManager) { return targetingObj; } - /** - * Sets targeting for DFP - * @param {Object.>} targetingConfig - */ - targeting.setTargetingForGPT = function(targetingConfig, customSlotMatching) { - window.googletag.pubads().getSlots().forEach(slot => { - Object.keys(targetingConfig).filter(customSlotMatching ? customSlotMatching(slot) : isAdUnitCodeMatchingSlot(slot)) - .forEach(targetId => { - Object.keys(targetingConfig[targetId]).forEach(key => { - let value = targetingConfig[targetId][key]; - if (typeof value === 'string' && value.indexOf(',') !== -1) { - // due to the check the array will be formed only if string has ',' else plain string will be assigned as value - value = value.split(','); - } - targetingConfig[targetId][key] = value; - }); - logMessage(`Attempting to set targeting-map for slot: ${slot.getSlotElementId()} with targeting-map:`, targetingConfig[targetId]); - slot.updateTargetingFromMap(targetingConfig[targetId]) - }) + targeting.setTargetingForGPT = hook('sync', function (adUnit, customSlotMatching) { + // get our ad unit codes + let targetingSet = targeting.getAllTargeting(adUnit); + + let resetMap = Object.fromEntries(pbTargetingKeys.map(key => [key, null])); + + Object.entries(getGPTSlotsForAdUnits(Object.keys(targetingSet), customSlotMatching)).forEach(([targetId, slots]) => { + slots.forEach(slot => { + // now set new targeting keys + Object.keys(targetingSet[targetId]).forEach(key => { + let value = targetingSet[targetId][key]; + if (typeof value === 'string' && value.indexOf(',') !== -1) { + // due to the check the array will be formed only if string has ',' else plain string will be assigned as value + value = value.split(','); + } + targetingSet[targetId][key] = value; + }); + logMessage(`Attempting to set targeting-map for slot: ${slot.getSlotElementId()} with targeting-map:`, targetingSet[targetId]); + slot.updateTargetingFromMap(Object.assign({}, resetMap, targetingSet[targetId])) + }) }) - }; + + Object.keys(targetingSet).forEach((adUnitCode) => { + Object.keys(targetingSet[adUnitCode]).forEach((targetingKey) => { + if (targetingKey === 'hb_adid') { + auctionManager.setStatusForBids(targetingSet[adUnitCode][targetingKey], BID_STATUS.BID_TARGETING_SET); + } + }); + }); + + targeting.targetingDone(targetingSet); + + // emit event + events.emit(EVENTS.SET_TARGETING, targetingSet); + }, 'setTargetingForGPT'); + + targeting.targetingDone = hook('sync', function (targetingSet) { + return targetingSet; + }, 'targetingDone'); /** * normlizes input to a `adUnit.code` array diff --git a/src/userSync.js b/src/userSync.js index 1b684de6de0..d8f2238007d 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -25,7 +25,7 @@ export const USERSYNC_DEFAULT_CONFIG = { }, syncsPerBidder: 5, syncDelay: 3000, - auctionDelay: 0 + auctionDelay: 500 }; // Set userSync default values diff --git a/src/utils.js b/src/utils.js index 2affc52ab8c..ec227c6d74b 100644 --- a/src/utils.js +++ b/src/utils.js @@ -4,8 +4,9 @@ import {includes} from './polyfill.js'; import { EVENTS, S2S } from './constants.js'; import {GreedyPromise} from './utils/promise.js'; import {getGlobal} from './prebidGlobal.js'; +import { default as deepAccess } from 'dlv/index.js'; -export { default as deepAccess } from 'dlv/index.js'; +export { deepAccess }; export { dset as deepSetValue } from 'dset'; var tStr = 'String'; @@ -661,6 +662,21 @@ export function isSafeFrameWindow() { return !!(ws.$sf && ws.$sf.ext); } +/** + * Returns the result of calling the function $sf.ext.geom() if it exists + * @see https://iabtechlab.com/wp-content/uploads/2016/03/SafeFrames_v1.1_final.pdf — 5.4 Function $sf.ext.geom + * @returns {Object | undefined} geometric information about the container + */ +export function getSafeframeGeometry() { + try { + const ws = getWindowSelf(); + return (typeof ws.$sf.ext.geom === 'function') ? ws.$sf.ext.geom() : undefined; + } catch (e) { + logError('Error getting SafeFrame geometry', e); + return undefined; + } +} + export function isSafariBrowser() { return /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent); } @@ -693,6 +709,33 @@ export function getPerformanceNow() { return (window.performance && window.performance.now && window.performance.now()) || 0; } +/** + * Retuns the difference between `timing.domLoading` and `timing.navigationStart`. + * This function uses the deprecated `Performance.timing` API and should be removed in future. + * It has not been updated yet because it is still used in some modules. + * @deprecated + * @param {Window} w The window object used to perform the api call. default to window.self + * @returns {number} + */ +export function getDomLoadingDuration(w) { + let domLoadingDuration = -1; + + w = w || getWindowSelf(); + + const performance = w.performance; + + if (w.performance?.timing) { + if (w.performance.timing.navigationStart > 0) { + const val = performance.timing.domLoading - performance.timing.navigationStart; + if (val > 0) { + domLoadingDuration = val; + } + } + } + + return domLoadingDuration; +} + /** * When the deviceAccess flag config option is false, no cookies should be read or set * @returns {boolean} @@ -705,6 +748,7 @@ export function hasDeviceAccess() { * @returns {(boolean|undefined)} */ export function checkCookieSupport() { + // eslint-disable-next-line prebid/no-member if (window.navigator.cookieEnabled || !!document.cookie.length) { return true; } @@ -1066,6 +1110,14 @@ export function safeJSONParse(data) { } catch (e) {} } +export function safeJSONEncode(data) { + try { + return JSON.stringify(data); + } catch (e) { + return ''; + } +} + /** * Returns a memoized version of `fn`. * @@ -1087,6 +1139,33 @@ export function memoize(fn, key = function (arg) { return arg; }) { return memoized; } +/** + * Returns a Unix timestamp for given time value and unit. + * @param {number} timeValue numeric value, defaults to 0 (which means now) + * @param {string} timeUnit defaults to days (or 'd'), use 'm' for minutes. Any parameter that isn't 'd' or 'm' will return Date.now(). + * @returns {number} + */ +export function getUnixTimestampFromNow(timeValue = 0, timeUnit = 'd') { + const acceptableUnits = ['m', 'd']; + if (acceptableUnits.indexOf(timeUnit) < 0) { + return Date.now(); + } + const multiplication = timeValue / (timeUnit === 'm' ? 1440 : 1); + return Date.now() + (timeValue && timeValue > 0 ? (1000 * 60 * 60 * 24 * multiplication) : 0); +} + +/** + * Converts given object into an array, so {key: 1, anotherKey: 'fred', third: ['fred']} is turned + * into [{key: 1}, {anotherKey: 'fred'}, {third: ['fred']}] + * @param {Object} obj the object + * @returns {Array} + */ +export function convertObjectToArray(obj) { + return Object.keys(obj).map(key => { + return {[key]: obj[key]}; + }); +} + /** * Sets dataset attributes on a script * @param {HTMLScriptElement} script @@ -1123,3 +1202,59 @@ export function binarySearch(arr, el, key = (el) => el) { } return left; } + +/** + * Checks if an object has non-serializable properties. + * Non-serializable properties are functions and RegExp objects. + * + * @param {Object} obj - The object to check. + * @param {Set} checkedObjects - A set of properties that have already been checked. + * @returns {boolean} - Returns true if the object has non-serializable properties, false otherwise. + */ +export function hasNonSerializableProperty(obj, checkedObjects = new Set()) { + for (const key in obj) { + const value = obj[key]; + const type = typeof value; + + if ( + value === undefined || + type === 'function' || + type === 'symbol' || + value instanceof RegExp || + value instanceof Map || + value instanceof Set || + value instanceof Date || + (value !== null && type === 'object' && value.hasOwnProperty('toJSON')) + ) { + return true; + } + if (value !== null && type === 'object' && value.constructor === Object) { + if (checkedObjects.has(value)) { + // circular reference, means we have a non-serializable property + return true; + } + checkedObjects.add(value); + if (hasNonSerializableProperty(value, checkedObjects)) { + return true; + } + } + } + return false; +} + +/** + * Returns the value of a nested property in an array of objects. + * + * @param {Array} collection - Array of objects. + * @param {String} key - Key of nested property. + * @returns {any, undefined} - Value of nested property. + */ +export function setOnAny(collection, key) { + for (let i = 0, result; i < collection.length; i++) { + result = deepAccess(collection[i], key); + if (result) { + return result; + } + } + return undefined; +} diff --git a/src/utils/focusTimeout.js b/src/utils/focusTimeout.js new file mode 100644 index 00000000000..0ba66cc4efc --- /dev/null +++ b/src/utils/focusTimeout.js @@ -0,0 +1,41 @@ +let outOfFocusStart; +let timeOutOfFocus = 0; +let suspendedTimeouts = []; + +document.addEventListener('visibilitychange', () => { + if (document.hidden) { + outOfFocusStart = Date.now() + } else { + timeOutOfFocus += Date.now() - outOfFocusStart + suspendedTimeouts.forEach(({ callback, startTime, setTimerId }) => setTimerId(setFocusTimeout(callback, timeOutOfFocus - startTime)())) + outOfFocusStart = null; + } +}); + +/** + * Wraps native setTimeout function in order to count time only when page is focused + * + * @param {function(*): ()} [callback] - A function that will be invoked after passed time + * @param {number} [milliseconds] - Minimum duration (in milliseconds) that the callback will be executed after + * @returns {function(*): (number)} - Getter function for current timer id + */ +export default function setFocusTimeout(callback, milliseconds) { + const startTime = timeOutOfFocus; + let timerId = setTimeout(() => { + if (timeOutOfFocus === startTime && outOfFocusStart == null) { + callback(); + } else if (outOfFocusStart != null) { + // case when timeout ended during page is out of focus + suspendedTimeouts.push({ + callback, + startTime, + setTimerId(newId) { + timerId = newId; + } + }) + } else { + timerId = setFocusTimeout(callback, timeOutOfFocus - startTime)(); + } + }, milliseconds); + return () => timerId; +} diff --git a/src/utils/gpdr.js b/src/utils/gdpr.js similarity index 100% rename from src/utils/gpdr.js rename to src/utils/gdpr.js diff --git a/src/utils/ttlCollection.js b/src/utils/ttlCollection.js index 2294c072108..b6e0a5198df 100644 --- a/src/utils/ttlCollection.js +++ b/src/utils/ttlCollection.js @@ -1,5 +1,6 @@ import {GreedyPromise} from './promise.js'; import {binarySearch, logError, timestamp} from '../utils.js'; +import setFocusTimeout from './focusTimeout.js'; /** * Create a set-like collection that automatically forgets items after a certain time. @@ -46,7 +47,7 @@ export function ttlCollection( if (pendingPurge.length > 0) { const now = timestamp(); nextPurge = Math.max(now, pendingPurge[0].expiry + slack); - task = setTimeout(() => { + task = setFocusTimeout(() => { const now = timestamp(); let cnt = 0; for (const entry of pendingPurge) { diff --git a/src/videoCache.js b/src/videoCache.js index 6cba77de308..cf39c1c9452 100644 --- a/src/videoCache.js +++ b/src/videoCache.js @@ -12,6 +12,8 @@ import {ajaxBuilder} from './ajax.js'; import {config} from './config.js'; import {auctionManager} from './auctionManager.js'; +import {logError, logWarn} from './utils.js'; +import {addBidToAuction} from './auction.js'; /** * Might be useful to be configurable in the future @@ -159,3 +161,73 @@ export function store(bids, done, getAjax = ajaxBuilder) { export function getCacheUrl(id) { return `${config.getConfig('cache.url')}?uuid=${id}`; } + +export const _internal = { + store +} + +export function storeBatch(batch) { + const bids = batch.map(entry => entry.bidResponse) + function err(msg) { + logError(`Failed to save to the video cache: ${msg}. Video bids will be discarded:`, bids) + } + _internal.store(bids, function (error, cacheIds) { + if (error) { + err(error) + } else if (batch.length !== cacheIds.length) { + logError(`expected ${batch.length} cache IDs, got ${cacheIds.length} instead`) + } else { + cacheIds.forEach((cacheId, i) => { + const {auctionInstance, bidResponse, afterBidAdded} = batch[i]; + if (cacheId.uuid === '') { + logWarn(`Supplied video cache key was already in use by Prebid Cache; caching attempt was rejected. Video bid must be discarded.`); + } else { + bidResponse.videoCacheKey = cacheId.uuid; + if (!bidResponse.vastUrl) { + bidResponse.vastUrl = getCacheUrl(bidResponse.videoCacheKey); + } + addBidToAuction(auctionInstance, bidResponse); + afterBidAdded(); + } + }); + } + }); +}; + +let batchSize, batchTimeout; +if (FEATURES.VIDEO) { + config.getConfig('cache', (cacheConfig) => { + batchSize = typeof cacheConfig.cache.batchSize === 'number' && cacheConfig.cache.batchSize > 0 + ? cacheConfig.cache.batchSize + : 1; + batchTimeout = typeof cacheConfig.cache.batchTimeout === 'number' && cacheConfig.cache.batchTimeout > 0 + ? cacheConfig.cache.batchTimeout + : 0; + }); +} + +export const batchingCache = (timeout = setTimeout, cache = storeBatch) => { + let batches = [[]]; + let debouncing = false; + const noTimeout = cb => cb(); + + return function (auctionInstance, bidResponse, afterBidAdded) { + const batchFunc = batchTimeout > 0 ? timeout : noTimeout; + if (batches[batches.length - 1].length >= batchSize) { + batches.push([]); + } + + batches[batches.length - 1].push({auctionInstance, bidResponse, afterBidAdded}); + + if (!debouncing) { + debouncing = true; + batchFunc(() => { + batches.forEach(cache); + batches = [[]]; + debouncing = false; + }, batchTimeout); + } + }; +}; + +export const batchAndStore = batchingCache(); diff --git a/test/helpers/index_adapter_utils.js b/test/helpers/index_adapter_utils.js index f01145b573d..0eb7af88d14 100644 --- a/test/helpers/index_adapter_utils.js +++ b/test/helpers/index_adapter_utils.js @@ -1,3 +1,5 @@ +import { deepClone } from '../../src/utils'; + var AllowedAdUnits = [[728, 90], [120, 600], [300, 250], [160, 600], [336, 280], [234, 60], [300, 600], [300, 50], [320, 50], [970, 250], [300, 1050], [970, 90], [180, 150]]; var UnsupportedAdUnits = [[700, 100], [100, 600], [300, 200], [100, 600], [300, 200], [200, 60], [900, 200], [300, 1000], [900, 90], [100, 100]]; @@ -117,7 +119,7 @@ exports.getExpectedIndexSlots = function(bids) { } function clone(x) { - return JSON.parse(JSON.stringify(x)); + return deepClone(x); } // returns the difference(lhs, rhs), difference(rhs,lhs), and intersection(lhs, rhs) based on the object keys diff --git a/test/mocks/ortbConverter.js b/test/mocks/ortbConverter.js new file mode 100644 index 00000000000..446fac4629a --- /dev/null +++ b/test/mocks/ortbConverter.js @@ -0,0 +1,8 @@ +import {defaultProcessors} from '../../libraries/ortbConverter/converter.js'; +import {pbsExtensions} from '../../libraries/pbsExtensions/pbsExtensions.js'; + +beforeEach(() => { + // disable caching of default processors so that tests do not freeze a subset for other tests + defaultProcessors.clear(); + pbsExtensions.clear(); +}); diff --git a/test/mocks/videoCacheStub.js b/test/mocks/videoCacheStub.js index 7ce899cae35..acae5cd6a32 100644 --- a/test/mocks/videoCacheStub.js +++ b/test/mocks/videoCacheStub.js @@ -1,4 +1,4 @@ -import * as videoCache from 'src/videoCache.js'; +import {_internal as videoCache} from 'src/videoCache.js'; /** * Function which can be called from unit tests to stub out the video cache. diff --git a/test/pages/banner_sync.html b/test/pages/banner_sync.html new file mode 100644 index 00000000000..71403ba5570 --- /dev/null +++ b/test/pages/banner_sync.html @@ -0,0 +1,97 @@ + + + + + + + Prebid.js Banner Example + + + + + + + + + + + + + + + +

Prebid.js Banner Ad Unit Test

+
+ +
+
+ + + diff --git a/test/pages/consent_mgt_gdpr.html b/test/pages/consent_mgt_gdpr.html index c55a2b9236f..6ff24938bf3 100644 --- a/test/pages/consent_mgt_gdpr.html +++ b/test/pages/consent_mgt_gdpr.html @@ -1,6 +1,6 @@ - + ", width: 844, height: 617}; - let validBidRequests_temp = [ - {bidder: 'iqm', - params: { - publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', - placementId: 23451, - bidfloor: 0.5}, - crumbs: { - pubcid: 'a0f51f64-6d86-41d0-abaf-7ece71404d94'}, - ortb2Imp: {ext: {data: {'pbadslot': '/19968336/header-bid-tag-0'}}}, - mediaTypes: { - banner: { - sizes: [[300, 250]]}}, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: '56fe8d92-ff6e-4c34-90ad-2f743cd0eae8', - sizes: [[300, 250]], - bidId: '266d810da21904', - bidderRequestId: '13c05d264c7ffe', - auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0}]; - let bidderRequest = { - bidderCode: 'iqm', - auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', - bidderRequestId: '13c05d264c7ffe', - bids: [{ - bidder: 'iqm', - params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5}, - crumbs: {pubcid: 'a0f51f64-6d86-41d0-abaf-7ece71404d94'}, - ortb2Imp: {ext: {data: {'pbadslot': '/19968336/header-bid-tag-0'}}}, - mediaTypes: {banner: {sizes: [[300, 250]]}}, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: '56fe8d92-ff6e-4c34-90ad-2f743cd0eae8', - sizes: [[300, 250]], - bidId: '266d810da21904', - bidderRequestId: '13c05d264c7ffe', - auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }], - auctionStart: 1615205942159, - timeout: 7000, - refererInfo: { - page: 'http://test.localhost:9999/integrationExamples/gpt/hello_world.html', - domain: 'test.localhost.com:9999', - ref: null, - reachedTop: true, - isAmp: false, - numIframes: 0, - stack: ['http://test.localhost:9999/integrationExamples/gpt/hello_world.html'], - canonicalUrl: null - }, - start: 1615205942162 - }; - let response = { - - id: '5bdbab92aae961cfbdf7465d', - seatbid: [{bid: [{id: 'bid-5bdbab92aae961cfbdf7465d-5bdbab92aae961cfbdf74653', impid: '5bdbab92aae961cfbdf74653', price: 9.9, nurl: 'https://winn.stage.iqm.com/smaato?raw=w9XViV4dovBHrxujHhBj-l-uWB08CUOMW_oR-EUxZbaWLL0ENzcMlP3CJFEURN6FgRp_HdjAjxTYHR7uG4S6h6dl_vjU_YNABiPd607-iTqxOCl-2cKLo-hhQus4sMw01VIqyqrPmzOTHTwJm4vTjUIoWMPZbARgQvUnBzjRH9xeYS-Bv3kgAW9NSBfgBZeLyT3WJJ_3VKIE_Iurt8OjpA%3D%3D&req_id=5bdbab92aae961cfbdf7465d&ap=${AUCTION_PRICE}', adm: " ", adomain: ['click.iqm.com'], iurl: 'https://d3jme5si7t6llb.cloudfront.net/image/1/404/owVo6mc_1588902031079.png', cid: '169218', crid: 'cr-301435', attr: [], h: 250, w: 250}]}], - bidid: '5bdbab92aae961cfbdf7465d' - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - {requestId: '49ad5f21156efd', currency: 'USD', cpm: 9.9, netRevenue: true, creativeId: 'cr-301435', adUnitCode: '/19968336/header-bid-tag-0', auctionId: '853cddf1-8d13-4482-bd88-f5ef927d5ab3', mediaType: 'banner', ttl: 3000, ad: " ", width: 250, height: 250} - ]; - let temprequest = spec.buildRequests(validBidRequests_temp, bidderRequest); - - let result = spec.interpretResponse({ body: response }, temprequest[0]); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - let validBidRequests_temp_video = - [{bidder: 'iqm', params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5, video: {placement: 2, mimes: ['video/mp4'], protocols: [2, 5], skipppable: true, playback_method: ['auto_play_sound_off']}}, crumbs: {pubcid: 'cd86c3ff-d630-40e6-83ab-420e9e800594'}, fpd: {context: {pbAdSlot: 'video1'}}, mediaTypes: {video: {playerSize: [[640, 480]], context: 'instream'}}, adUnitCode: 'video1', transactionId: '8335b266-7a41-45f9-86a2-92fdc7cf0cd9', sizes: [[640, 480]], bidId: '26274beff25455', bidderRequestId: '17c5d8c3168761', auctionId: '2c592dcf-7dfc-4823-8203-dd1ebab77fe0', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}]; - let bidderRequest_video = { - bidderCode: 'iqm', - auctionId: '3140a2ec-d567-4db0-9bbb-eb6fa20ccb71', - bidderRequestId: '16e1ce8481bc6d', - bids: [{ - bidder: 'iqm', - params: { - publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', - placementId: 23451, - bidfloor: 0.5, - video: { - placement: 2, - mimes: ['video/mp4'], - protocols: [2, 5], - skipppable: true, - playback_method: ['auto_play_sound_off'] - } - }, - crumbs: {pubcid: '09b8f065-9d1b-4a36-bd0c-ea22e2dad807'}, - ortb2Imp: {ext: {data: {'pbadslot': 'video1'}}}, - mediaTypes: {video: {playerSize: [[640, 480]], context: 'instream'}}, - adUnitCode: 'video1', - transactionId: '86795c66-acf9-4dd5-998f-6d5362aaa541', - sizes: [[640, 480]], - bidId: '28bfb7e2d12897', - bidderRequestId: '16e1ce8481bc6d', - auctionId: '3140a2ec-d567-4db0-9bbb-eb6fa20ccb71', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }], - auctionStart: 1615271191985, - timeout: 3000, - refererInfo: { - page: 'http://test.localhost:9999/integrationExamples/gpt/pbjs_video_adUnit.html', - domain: 'test.localhost.com:9999', - ref: '', - reachedTop: true, - isAmp: false, - numIframes: 0, - stack: ['http://test.localhost:9999/integrationExamples/gpt/pbjs_video_adUnit.html'], - canonicalUrl: null - }, - start: 1615271191988 - }; - - it('handles non-banner media responses', function () { - let response = {id: '2341234', seatbid: [{bid: [{id: 'bid-2341234-1', impid: '1', price: 9, nurl: 'https://frontend.stage.iqm.com/static/vast-01.xml', adm: 'http://cdn.iqm.com/pbd?raw=312730_203cf73dc83fb_2824348636878_pbd', adomain: ['app1.stage.iqm.com'], cid: '168900', crid: 'cr-304503', attr: []}]}], bidid: '2341234'}; - - let temprequest_video = spec.buildRequests(validBidRequests_temp_video, bidderRequest_video); - - let result = spec.interpretResponse({ body: response }, temprequest_video[0]); - expect(result[0]).to.have.property('vastUrl'); - }); - }); -}); diff --git a/test/spec/modules/iqzoneBidAdapter_spec.js b/test/spec/modules/iqzoneBidAdapter_spec.js index 9d012e526e2..8f622cc39ed 100644 --- a/test/spec/modules/iqzoneBidAdapter_spec.js +++ b/test/spec/modules/iqzoneBidAdapter_spec.js @@ -3,7 +3,7 @@ import { spec } from '../../../modules/iqzoneBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; -const bidder = 'iqzone' +const bidder = 'iqzone'; describe('IQZoneBidAdapter', function () { const userIdAsEids = [{ @@ -26,7 +26,7 @@ describe('IQZoneBidAdapter', function () { } }, params: { - placementId: 'testBanner', + placementId: 'testBanner' }, userIdAsEids }, @@ -41,7 +41,7 @@ describe('IQZoneBidAdapter', function () { } }, params: { - placementId: 'testVideo', + placementId: 'testVideo' }, userIdAsEids }, @@ -65,7 +65,7 @@ describe('IQZoneBidAdapter', function () { } }, params: { - placementId: 'testNative', + placementId: 'testNative' }, userIdAsEids } @@ -87,10 +87,19 @@ describe('IQZoneBidAdapter', function () { const bidderRequest = { uspConsent: '1---', gdprConsent: { - consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw' + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } }, timeout: 500 }; @@ -181,12 +190,63 @@ describe('IQZoneBidAdapter', function () { } }); + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + it('Returns data with gdprConsent and without uspConsent', function () { delete bidderRequest.uspConsent; serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; @@ -202,12 +262,6 @@ describe('IQZoneBidAdapter', function () { expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([], bidderRequest); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); }); describe('gpp consent', function () { diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index e5b2fbc359a..42c0c2afdf5 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -821,8 +821,9 @@ describe('IndexexchangeAdapter', function () { tid: 'mock-tid' } }, - fledgeEnabled: true, - defaultForSlots: 1 + paapi: { + enabled: true + }, }; const DEFAULT_OPTION_FLEDGE_ENABLED = { @@ -843,7 +844,9 @@ describe('IndexexchangeAdapter', function () { tid: 'mock-tid' } }, - fledgeEnabled: true + paapi: { + enabled: true + } }; const DEFAULT_IDENTITY_RESPONSE = { @@ -1348,34 +1351,6 @@ describe('IndexexchangeAdapter', function () { }); }); - describe('Roundel alias adapter', function () { - const vaildBids = [DEFAULT_BANNER_VALID_BID, DEFAULT_VIDEO_VALID_BID, DEFAULT_MULTIFORMAT_BANNER_VALID_BID, DEFAULT_MULTIFORMAT_VIDEO_VALID_BID]; - const ALIAS_OPTIONS = Object.assign({ - bidderCode: 'roundel' - }, DEFAULT_OPTION); - - it('should not build requests for mediaTypes if liveramp data is unavaliable', function () { - vaildBids.forEach((validBid) => { - const request = spec.buildRequests(validBid, ALIAS_OPTIONS); - expect(request).to.be.an('array'); - expect(request).to.have.lengthOf(0); - }); - }); - - it('should build requests for mediaTypes if liveramp data is avaliable', function () { - vaildBids.forEach((validBid) => { - const cloneValidBid = utils.deepClone(validBid); - cloneValidBid[0].userIdAsEids = utils.deepClone(DEFAULT_USERIDASEIDS_DATA); - const request = spec.buildRequests(cloneValidBid, ALIAS_OPTIONS); - const payload = extractPayload(request[0]); - expect(request).to.be.an('array'); - expect(request).to.have.lengthOf.above(0); // should be 1 or more - expect(payload.user.eids).to.have.lengthOf(11); - expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[0]); - }); - }); - }); - describe('buildRequestsIdentity', function () { let request; let payload; @@ -3464,16 +3439,7 @@ describe('IndexexchangeAdapter', function () { expect(impression.ext.ae).to.equal(1); }); - it('impression should have ae=1 in ext when fledge module is enabled globally and default is set through setConfig', function () { - const bidderRequest = deepClone(DEFAULT_OPTION_FLEDGE_ENABLED_GLOBALLY); - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - const requestBidFloor = spec.buildRequests([bid], bidderRequest)[0]; - const impression = extractPayload(requestBidFloor).imp[0]; - - expect(impression.ext.ae).to.equal(1); - }); - - it('impression should have ae=1 in ext when fledge module is enabled globally but no default set through setConfig but set at ad unit level', function () { + it('impression should have ae=1 in ext when request has paapi.enabled = true and ext.ae = 1', function () { const bidderRequest = deepClone(DEFAULT_OPTION_FLEDGE_ENABLED); const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID_WITH_FLEDGE_ENABLED[0]); const requestBidFloor = spec.buildRequests([bid], bidderRequest)[0]; @@ -4180,7 +4146,7 @@ describe('IndexexchangeAdapter', function () { beforeEach(() => { bidderRequestWithFledgeEnabled = spec.buildRequests(DEFAULT_BANNER_VALID_BID_WITH_FLEDGE_ENABLED, {})[0]; - bidderRequestWithFledgeEnabled.fledgeEnabled = true; + bidderRequestWithFledgeEnabled.paapi = {enabled: true}; serverResponseWithoutFledgeConfigs = { body: { @@ -4244,17 +4210,17 @@ describe('IndexexchangeAdapter', function () { } } ]; - expect(result.fledgeAuctionConfigs).to.deep.equal(expectedOutput); + expect(result.paapi).to.deep.equal(expectedOutput); }); it('should correctly interpret response without auction configs', () => { const result = spec.interpretResponse(serverResponseWithoutFledgeConfigs, bidderRequestWithFledgeEnabled); - expect(result.fledgeAuctionConfigs).to.be.undefined; + expect(result.paapi).to.be.undefined; }); it('should handle malformed auction configs gracefully', () => { const result = spec.interpretResponse(serverResponseWithMalformedAuctionConfig, bidderRequestWithFledgeEnabled); - expect(result.fledgeAuctionConfigs).to.be.empty; + expect(result.paapi).to.be.empty; }); it('should log warning for malformed auction configs', () => { @@ -4266,7 +4232,7 @@ describe('IndexexchangeAdapter', function () { it('should return bids when protected audience auction conigs is malformed', () => { const result = spec.interpretResponse(serverResponseWithMalformedAuctionConfigs, bidderRequestWithFledgeEnabled); - expect(result.fledgeAuctionConfigs).to.be.undefined; + expect(result.paapi).to.be.undefined; expect(result.length).to.be.greaterThan(0); }); }); @@ -4285,7 +4251,7 @@ describe('IndexexchangeAdapter', function () { }; bidderRequestWithFledgeEnabled = spec.buildRequests(DEFAULT_BANNER_VALID_BID_WITH_FLEDGE_ENABLED, {})[0]; - bidderRequestWithFledgeEnabled.fledgeEnabled = true; + bidderRequestWithFledgeEnabled.paapi = {enabled: true}; bidderRequestWithoutFledgeEnabled = spec.buildRequests(DEFAULT_BANNER_VALID_BID, {})[0]; }); diff --git a/test/spec/modules/jwplayerRtdProvider_spec.js b/test/spec/modules/jwplayerRtdProvider_spec.js index c57c8a685e7..58cfc751a4f 100644 --- a/test/spec/modules/jwplayerRtdProvider_spec.js +++ b/test/spec/modules/jwplayerRtdProvider_spec.js @@ -12,6 +12,7 @@ import { getVatFromCache, getVatFromPlayer, setOverrides, + getPlayer, jwplayerSubmodule } from 'modules/jwplayerRtdProvider.js'; import {server} from 'test/mocks/xhr.js'; @@ -629,7 +630,7 @@ describe('jwplayerRtdProvider', function() { expect(ortb2Fragments.global).to.have.property('site'); expect(ortb2Fragments.global.site).to.have.property('content'); - expect(ortb2Fragments.global.site.content).to.have.property('id', 'jw_' + testIdForSuccess); + expect(ortb2Fragments.global.site.content).to.have.property('id', 'randomContentId'); expect(ortb2Fragments.global.site.content).to.have.property('data'); const data = ortb2Fragments.global.site.content.data; expect(data).to.have.length(3); @@ -801,7 +802,7 @@ describe('jwplayerRtdProvider', function() { describe(' Add Ortb Site Content', function () { beforeEach(() => { setOverrides({ - overrideContentId: 'always', + overrideContentId: 'whenEmpty', overrideContentUrl: 'whenEmpty', overrideContentTitle: 'whenEmpty', overrideContentDescription: 'whenEmpty' @@ -865,16 +866,16 @@ describe('jwplayerRtdProvider', function() { } }; - const expectedId = 'expectedId'; + const newId = 'newId'; const expectedUrl = 'expectedUrl'; const expectedTitle = 'expectedTitle'; const expectedDescription = 'expectedDescription'; const expectedData = { datum: 'datum' }; - addOrtbSiteContent(ortb2, expectedId, expectedData, expectedTitle, expectedDescription, expectedUrl); + addOrtbSiteContent(ortb2, newId, expectedData, expectedTitle, expectedDescription, expectedUrl); expect(ortb2).to.have.nested.property('site.random.random_sub', 'randomSub'); expect(ortb2).to.have.nested.property('app.content.id', 'appId'); expect(ortb2).to.have.nested.property('site.content.ext.random_field', 'randomField'); - expect(ortb2).to.have.nested.property('site.content.id', expectedId); + expect(ortb2).to.have.nested.property('site.content.id', 'oldId'); expect(ortb2).to.have.nested.property('site.content.url', expectedUrl); expect(ortb2).to.have.nested.property('site.content.title', expectedTitle); expect(ortb2).to.have.nested.property('site.content.ext.description', expectedDescription); @@ -889,7 +890,7 @@ describe('jwplayerRtdProvider', function() { expect(ortb2).to.have.nested.property('site.content.id', expectedId); }); - it('should override content id by default', function () { + it('should keep old content id by default', function () { const ortb2 = { site: { content: { @@ -898,9 +899,8 @@ describe('jwplayerRtdProvider', function() { } }; - const expectedId = 'expectedId'; - addOrtbSiteContent(ortb2, expectedId); - expect(ortb2).to.have.nested.property('site.content.id', expectedId); + addOrtbSiteContent(ortb2, 'newId'); + expect(ortb2).to.have.nested.property('site.content.id', 'oldId'); }); it('should keep previous content id when new value is not available', function () { @@ -1604,6 +1604,66 @@ describe('jwplayerRtdProvider', function() { }); }); + describe('Player detection', function () { + const playerInstanceMock = { + getPlaylist: () => [], + getPlaylistItem: () => ({}) + }; + + beforeEach(function () { + window.jwplayer = sinon.stub(); + }); + + afterEach(function () { + delete window.jwplayer; + }); + + it('should fail if jwplayer global does not exist', function () { + delete window.jwplayer; + expect(getPlayer('divId')).to.be.undefined; + }); + + it('should return the player instance for the specified div id', function () { + window.jwplayer.returns(playerInstanceMock); + const player = getPlayer('divId'); + expect(player).to.deep.equal(playerInstanceMock); + }); + + it('should request a player when the div id does not match a player on the page and only 1 player is in the DOM', function () { + const playerDomElement = document.createElement('div'); + playerDomElement.className = 'jwplayer'; + document.body.appendChild(playerDomElement); + + window.jwplayer.withArgs('invalidDivId').returns(undefined); + window.jwplayer.returns(playerInstanceMock); + + const playerInstance = getPlayer('invalidDivId'); + + expect(playerInstance).to.deep.equal(playerInstanceMock); + + document.body.removeChild(playerDomElement); + }); + + it('should fail when the div id does not match a player on the page, and multiple players are instantiated', function () { + const firstPlayerDomElement = document.createElement('div'); + const secondPlayerDomElement = document.createElement('div'); + firstPlayerDomElement.className = 'jwplayer'; + secondPlayerDomElement.className = 'jwplayer'; + document.body.appendChild(firstPlayerDomElement); + document.body.appendChild(secondPlayerDomElement); + + window.jwplayer.withArgs('invalidDivId').returns(undefined); + window.jwplayer.returns(playerInstanceMock); + + const playerInstance = getPlayer('invalidDivId'); + + expect(playerInstance).to.be.undefined; + + document.body.removeChild(firstPlayerDomElement); + document.body.removeChild(secondPlayerDomElement); + }); + }); + describe('jwplayerSubmodule', function () { it('successfully instantiates', function () { expect(jwplayerSubmodule.init()).to.equal(true); diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js index ee89d6468a5..e24c34dd1ab 100644 --- a/test/spec/modules/kargoBidAdapter_spec.js +++ b/test/spec/modules/kargoBidAdapter_spec.js @@ -300,7 +300,7 @@ describe('kargo adapter tests', function() { domain, isAmp: false, location: topUrl, - numIframs: 0, + numIframes: 0, page: topUrl, reachedTop: true, ref: referer, @@ -428,12 +428,12 @@ describe('kargo adapter tests', function() { } } }]); - expect(payload.ext).to.deep.equal({ ortb2: { + expect(payload.ext.ortb2).to.deep.equal({ user: { key: 'value' } - }}); + }); payload = getPayloadFromTestBids(testBids); - expect(payload.ext).to.be.undefined; + expect(payload.ext.ortb2).to.be.undefined; payload = getPayloadFromTestBids([{ ...minimumBidParams, @@ -450,9 +450,33 @@ describe('kargo adapter tests', function() { } } }]); - expect(payload.ext).to.deep.equal({ortb2: { + expect(payload.ext.ortb2).to.deep.equal({ user: { key: 'value' } - }}); + } + ); + }); + + it('copies the refererInfo object from bidderRequest if present', function() { + let payload; + payload = getPayloadFromTestBids(testBids); + expect(payload.ext.refererInfo).to.deep.equal({ + canonicalUrl: 'https://random.com/this/is/a/url', + domain: 'random.com', + isAmp: false, + location: 'https://random.com/this/is/a/url', + numIframes: 0, + page: 'https://random.com/this/is/a/url', + reachedTop: true, + ref: 'https://random.com/', + stack: [ + 'https://random.com/this/is/a/url' + ], + topmostLocation: 'https://random.com/this/is/a/url' + }); + + delete bidderRequest.refererInfo + payload = getPayloadFromTestBids(testBids); + expect(payload.ext).to.be.undefined; }); it('pulls the site category from the first bids ortb2 object', function() { @@ -1808,7 +1832,7 @@ describe('kargo adapter tests', function() { }); }); - it('should return fledgeAuctionConfigs if provided in bid response', function () { + it('should return paapi if provided in bid response', function () { const auctionConfig = { seller: 'https://kargo.com', decisionLogicUrl: 'https://kargo.com/decision_logic.js', @@ -1841,11 +1865,11 @@ describe('kargo adapter tests', function() { expect(bid).to.have.property('meta').that.is.an('object'); }); - // Test properties of fledgeAuctionConfigs - expect(result.fledgeAuctionConfigs).to.have.lengthOf(3); + // Test properties of paapi + expect(result.paapi).to.have.lengthOf(3); const expectedBidIds = ['1', '3', '5']; // Expected bidIDs - result.fledgeAuctionConfigs.forEach(config => { + result.paapi.forEach(config => { expect(config).to.have.property('bidId'); expect(expectedBidIds).to.include(config.bidId); @@ -1861,16 +1885,15 @@ describe('kargo adapter tests', function() { describe('getUserSyncs', function() { let crb = {}; const clientId = 'random-client-id-string'; - const baseUrl = 'https://crb.kargo.com/api/v1/initsyncrnd/random-client-id-string?seed=3205e885-8d37-4139-b47e-f82cff268000&idx=0&gdpr=0&gdpr_consent=&us_privacy=&gpp=&gpp_sid='; + const baseUrl = 'https://crb.kargo.com/api/v1/initsyncrnd/random-client-id-string?seed=3205e885-8d37-4139-b47e-f82cff268000&gdpr=0&gdpr_consent=&us_privacy=&gpp=&gpp_sid='; - function buildSyncUrls(baseUrl = 'https://crb.kargo.com/api/v1/initsyncrnd/random-client-id-string?seed=3205e885-8d37-4139-b47e-f82cff268000&idx=0&gdpr=0&gdpr_consent=&us_privacy=&gpp=&gpp_sid=') { + function buildSyncUrls(baseUrl = 'https://crb.kargo.com/api/v1/initsyncrnd/random-client-id-string?seed=3205e885-8d37-4139-b47e-f82cff268000&gdpr=0&gdpr_consent=&us_privacy=&gpp=&gpp_sid=') { let syncs = []; - for (let i = 0; i < 5; i++) { - syncs.push({ - type: 'iframe', - url: baseUrl.replace(/idx=\d+&/, `idx=${i}&`), - }); - } + + syncs.push({ + type: 'iframe', + url: baseUrl + }); return syncs; } diff --git a/test/spec/modules/kiviadsBidAdapter_spec.js b/test/spec/modules/kiviadsBidAdapter_spec.js index 03d58cbc265..618648a0c07 100644 --- a/test/spec/modules/kiviadsBidAdapter_spec.js +++ b/test/spec/modules/kiviadsBidAdapter_spec.js @@ -3,11 +3,21 @@ import { spec } from '../../../modules/kiviadsBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; -const bidder = 'kiviads' +const bidder = 'kiviads'; const adUrl = 'https://lb.kiviads.com/pbjs'; const syncUrl = 'https://sync.kiviads.com'; describe('KiviAdsBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -18,8 +28,9 @@ describe('KiviAdsBidAdapter', function () { } }, params: { - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -32,8 +43,9 @@ describe('KiviAdsBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -55,8 +67,9 @@ describe('KiviAdsBidAdapter', function () { } }, params: { - placementId: 'testNative', - } + placementId: 'testNative' + }, + userIdAsEids } ]; @@ -75,11 +88,22 @@ describe('KiviAdsBidAdapter', function () { const bidderRequest = { uspConsent: '1---', - gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' }, - bidderTimeout: 300 + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } + }, + timeout: 500 }; describe('isBidRequestValid', function () { @@ -122,7 +146,6 @@ describe('KiviAdsBidAdapter', function () { 'coppa', 'ccpa', 'gdpr', - 'gpp', 'tmax' ); expect(data.deviceWidth).to.be.a('number'); @@ -130,11 +153,9 @@ describe('KiviAdsBidAdapter', function () { expect(data.language).to.be.a('string'); expect(data.secure).to.be.within(0, 1); expect(data.host).to.be.a('string'); - expect(data.host).to.contain('localhost'); expect(data.page).to.be.a('string'); - expect(data.page).to.equal('/'); expect(data.coppa).to.be.a('number'); - expect(data.gdpr).to.be.a('string'); + expect(data.gdpr).to.be.a('object'); expect(data.ccpa).to.be.a('string'); expect(data.tmax).to.be.a('number'); expect(data.placements).to.have.lengthOf(3); @@ -150,6 +171,56 @@ describe('KiviAdsBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -175,8 +246,10 @@ describe('KiviAdsBidAdapter', function () { serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); @@ -191,12 +264,38 @@ describe('KiviAdsBidAdapter', function () { expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) }); describe('interpretResponse', function () { @@ -400,5 +499,17 @@ describe('KiviAdsBidAdapter', function () { expect(syncData[0].url).to.be.a('string') expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&ccpa_consent=1---&coppa=0`) }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0`) + }); }); }); diff --git a/test/spec/modules/krushmediaBidAdapter_spec.js b/test/spec/modules/krushmediaBidAdapter_spec.js index 86437180e94..452eb517eb8 100644 --- a/test/spec/modules/krushmediaBidAdapter_spec.js +++ b/test/spec/modules/krushmediaBidAdapter_spec.js @@ -1,146 +1,303 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/krushmediaBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/krushmediaBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; +import { getUniqueIdentifierStr } from '../../../src/utils.js'; + +const bidder = 'krushmedia'; describe('KrushmediabBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'krushmedia', + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + key: 783 + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + key: 783 + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + key: 783 + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, mediaTypes: { [BANNER]: { sizes: [[300, 250]] } }, params: { - key: 783 + } - }; + } const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, refererInfo: { - referer: 'test.com' - } + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } + }, + timeout: 500 }; describe('isBidRequestValid', function () { it('Should return true if there are bidId, params and key parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; + expect(spec.isBidRequestValid(bids[0])).to.be.true; }); it('Should return false if at least one of parameters is not present', function () { - delete bid.params.key; - expect(spec.isBidRequestValid(bid)).to.be.false; + expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); }); describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); + it('Creates a ServerRequest object with method, URL and data', function () { expect(serverRequest).to.exist; expect(serverRequest.method).to.exist; expect(serverRequest.url).to.exist; expect(serverRequest.data).to.exist; }); + it('Returns POST method', function () { expect(serverRequest.method).to.equal('POST'); }); + it('Returns valid URL', function () { expect(serverRequest.url).to.equal('https://ads4.krushmedia.com/?c=rtb&m=hb'); }); - it('Returns valid data if array of bids is valid', function () { + + it('Returns general data valid', function () { let data = serverRequest.data; expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data).to.have.all.keys('deviceWidth', + 'deviceHeight', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax' + ); expect(data.deviceWidth).to.be.a('number'); expect(data.deviceHeight).to.be.a('number'); expect(data.language).to.be.a('string'); expect(data.secure).to.be.within(0, 1); expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); - expect(data.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('key', 'bidId', 'traffic', 'sizes', 'schain', 'bidFloor'); - expect(placement.key).to.equal(783); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - expect(placement.sizes).to.be.an('array'); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); }); - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('key', 'bidId', 'traffic', 'wPlayer', 'hPlayer', 'schain', 'bidFloor', - 'minduration', 'maxduration', 'mimes', 'protocols', 'startdelay', 'placement', 'skip', - 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.key).to.be.equal(783); + expect(placement.traffic).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.traffic === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.traffic) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.wPlayer).to.be.an('number'); + expect(placement.hPlayer).to.be.an('number'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } }); - it('Returns valid data for mediatype native', function () { - const native = { - title: { - required: true - }, - body: { - required: true - }, - icon: { - required: true, - size: [64, 64] + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids } - }; + ]; - bid.mediaTypes = {}; - bid.params.traffic = NATIVE; - bid.mediaTypes[NATIVE] = native; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('key', 'bidId', 'traffic', 'native', 'schain', 'bidFloor'); - expect(placement.traffic).to.equal(NATIVE); - expect(placement.native).to.equal(native); + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.traffic).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.traffic === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.traffic) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.wPlayer).to.be.an('number'); + expect(placement.hPlayer).to.be.an('number'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } }); it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.ccpa).to.exist; expect(data.ccpa).to.be.a('string'); expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) }); + describe('interpretResponse', function () { it('Should interpret banner response', function () { const banner = { @@ -155,7 +312,11 @@ describe('KrushmediabBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', - dealId: '1' + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let bannerResponses = spec.interpretResponse(banner); @@ -163,15 +324,15 @@ describe('KrushmediabBidAdapter', function () { let dataItem = bannerResponses[0]; expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); + expect(dataItem.currency).to.equal(banner.body[0].currency); expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); }); it('Should interpret video response', function () { @@ -185,7 +346,11 @@ describe('KrushmediabBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', - dealId: '1' + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let videoResponses = spec.interpretResponse(video); @@ -219,6 +384,10 @@ describe('KrushmediabBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let nativeResponses = spec.interpretResponse(native); @@ -305,6 +474,7 @@ describe('KrushmediabBidAdapter', function () { expect(serverResponses).to.be.an('array').that.is.empty; }); }); + describe('getUserSyncs', function() { it('Should return array of objects with proper sync config , include GDPR', function() { const syncData = spec.getUserSyncs({}, {}, { @@ -314,20 +484,32 @@ describe('KrushmediabBidAdapter', function () { expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') - expect(syncData[0].type).to.equal('iframe') + expect(syncData[0].type).to.equal('image') expect(syncData[0].url).to.be.a('string') - expect(syncData[0].url).to.equal('https://cs.krushmedia.com/html?src=pbjs&gdpr=1&gdpr_consent=ALL') + expect(syncData[0].url).to.equal('https://cs.krushmedia.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1NNN' + consentString: '1---' + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://cs.krushmedia.com/image?pbjs=1&ccpa_consent=1---&coppa=0') + }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] }); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') - expect(syncData[0].type).to.equal('iframe') + expect(syncData[0].type).to.equal('image') expect(syncData[0].url).to.be.a('string') - expect(syncData[0].url).to.equal('https://cs.krushmedia.com/html?src=pbjs&ccpa_consent=1NNN') + expect(syncData[0].url).to.equal('https://cs.krushmedia.com/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0') }); }); }); diff --git a/test/spec/modules/kueezRtbBidAdapter_spec.js b/test/spec/modules/kueezRtbBidAdapter_spec.js index ebd11885af4..dd3ea4bfb2b 100644 --- a/test/spec/modules/kueezRtbBidAdapter_spec.js +++ b/test/spec/modules/kueezRtbBidAdapter_spec.js @@ -2,6 +2,14 @@ import {expect} from 'chai'; import { spec as adapter, createDomain, + storage +} from 'modules/kueezRtbBidAdapter.js'; +import * as utils from 'src/utils.js'; +import {version} from 'package.json'; +import {useFakeTimers} from 'sinon'; +import {BANNER, VIDEO} from '../../../src/mediaTypes'; +import {config} from '../../../src/config'; +import { hashCode, extractPID, extractCID, @@ -10,12 +18,7 @@ import { setStorageItem, tryParseJSON, getUniqueDealId, -} from 'modules/kueezRtbBidAdapter.js'; -import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes'; -import {config} from '../../../src/config'; +} from '../../../libraries/vidazooUtils/bidderUtils.js'; export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -322,7 +325,12 @@ describe('KueezRtbBidAdapter', function () { startdelay: 0 } }, - gpid: '' + gpid: '', + cat: [], + contentData: [], + isStorageAllowed: true, + pagecat: [], + userData: [] } }); }); @@ -384,6 +392,11 @@ describe('KueezRtbBidAdapter', function () { uqs: getTopWindowQueryParams(), 'ext.param1': 'loremipsum', 'ext.param2': 'dolorsitamet', + cat: [], + contentData: [], + isStorageAllowed: true, + pagecat: [], + userData: [] } }); }); @@ -526,8 +539,6 @@ describe('KueezRtbBidAdapter', function () { switch (idSystemProvider) { case 'lipb': return {lipbid: id}; - case 'parrableId': - return {eid: id}; case 'id5id': return {uid: id}; default: @@ -580,13 +591,13 @@ describe('KueezRtbBidAdapter', function () { const key = 'myKey'; let uniqueDealId; beforeEach(() => { - uniqueDealId = getUniqueDealId(key, 0); + uniqueDealId = getUniqueDealId(storage, key, 0); }) it('should get current unique deal id', function (done) { // waiting some time so `now` will become past setTimeout(() => { - const current = getUniqueDealId(key); + const current = getUniqueDealId(storage, key); expect(current).to.be.equal(uniqueDealId); done(); }, 200); @@ -594,7 +605,7 @@ describe('KueezRtbBidAdapter', function () { it('should get new unique deal id on expiration', function (done) { setTimeout(() => { - const current = getUniqueDealId(key, 100); + const current = getUniqueDealId(storage, key, 100); expect(current).to.not.be.equal(uniqueDealId); done(); }, 200) @@ -618,8 +629,8 @@ describe('KueezRtbBidAdapter', function () { shouldAdvanceTime: true, now }); - setStorageItem('myKey', 2020); - const {value, created} = getStorageItem('myKey'); + setStorageItem(storage, 'myKey', 2020); + const {value, created} = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -630,7 +641,7 @@ describe('KueezRtbBidAdapter', function () { it('should get external stored value', function () { const value = 'superman' window.localStorage.setItem('myExternalKey', value); - const item = getStorageItem('myExternalKey'); + const item = getStorageItem(storage, 'myExternalKey'); expect(item).to.be.equal(value); }); diff --git a/test/spec/modules/lassoBidAdapter_spec.js b/test/spec/modules/lassoBidAdapter_spec.js index ad4040c0452..15dee20e566 100644 --- a/test/spec/modules/lassoBidAdapter_spec.js +++ b/test/spec/modules/lassoBidAdapter_spec.js @@ -62,14 +62,14 @@ describe('lassoBidAdapter', function () { expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should return true when there are extra params', function () { - const bid = Object.assign({}, bid, { + const invalidBid = Object.assign({}, bid, { params: { adUnitId: 123456, zone: 1, publisher: 'test' } }) - expect(spec.isBidRequestValid(bid)).to.equal(true); + expect(spec.isBidRequestValid(invalidBid)).to.equal(true); }); it('should return false when there are no params', function () { const invalidBid = { ...bid }; diff --git a/test/spec/modules/lkqdBidAdapter_spec.js b/test/spec/modules/lkqdBidAdapter_spec.js index 4ff69ce5e2a..1e05b9deeb3 100644 --- a/test/spec/modules/lkqdBidAdapter_spec.js +++ b/test/spec/modules/lkqdBidAdapter_spec.js @@ -46,12 +46,12 @@ describe('lkqdBidAdapter', () => { }); it('should return false when required params are not passed', () => { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { wrong: 'missing zone id' }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/loganBidAdapter_spec.js b/test/spec/modules/loganBidAdapter_spec.js index a9859bbd4ae..f51f22580e2 100644 --- a/test/spec/modules/loganBidAdapter_spec.js +++ b/test/spec/modules/loganBidAdapter_spec.js @@ -79,7 +79,7 @@ describe('LoganBidAdapter', function () { expect(data).to.be.an('object'); let placement = data['placements'][0]; expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'adFormat', 'wPlayer', 'hPlayer', 'schain', 'minduration', 'maxduration', 'mimes', 'protocols', 'startdelay', 'placement', 'skip', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity', 'bidfloor'); + expect(placement).to.have.keys('placementId', 'bidId', 'adFormat', 'wPlayer', 'hPlayer', 'schain', 'minduration', 'maxduration', 'mimes', 'protocols', 'startdelay', 'placement', 'plcmt', 'skip', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity', 'bidfloor'); expect(placement.adFormat).to.equal(VIDEO); expect(placement.wPlayer).to.equal(playerSize[0]); expect(placement.hPlayer).to.equal(playerSize[1]); diff --git a/test/spec/modules/logicadBidAdapter_spec.js b/test/spec/modules/logicadBidAdapter_spec.js index 12e8ca31cbb..5c86ffc9325 100644 --- a/test/spec/modules/logicadBidAdapter_spec.js +++ b/test/spec/modules/logicadBidAdapter_spec.js @@ -182,7 +182,9 @@ describe('LogicadAdapter', function () { stack: [] }, auctionStart: 1563337198010, - fledgeEnabled: true + paapi: { + enabled: true + } }; const serverResponse = { body: { @@ -388,8 +390,8 @@ describe('LogicadAdapter', function () { const paapiRequest = spec.buildRequests(bidRequests, bidderRequest)[0]; const paapiInterpretedResponse = spec.interpretResponse(paapiServerResponse, paapiRequest); expect(paapiInterpretedResponse).to.have.property('bids'); - expect(paapiInterpretedResponse).to.have.property('fledgeAuctionConfigs'); - expect(paapiInterpretedResponse.fledgeAuctionConfigs[0]).to.deep.equal(paapiServerResponse.body.ext.fledgeAuctionConfigs[0]); + expect(paapiInterpretedResponse).to.have.property('paapi'); + expect(paapiInterpretedResponse.paapi[0]).to.deep.equal(paapiServerResponse.body.ext.fledgeAuctionConfigs[0]); // native const nativeRequest = spec.buildRequests(nativeBidRequests, bidderRequest)[0]; diff --git a/test/spec/modules/loyalBidAdapter_spec .js b/test/spec/modules/loyalBidAdapter_spec.js similarity index 77% rename from test/spec/modules/loyalBidAdapter_spec .js rename to test/spec/modules/loyalBidAdapter_spec.js index 28e87fc7047..f125eef4c5c 100644 --- a/test/spec/modules/loyalBidAdapter_spec .js +++ b/test/spec/modules/loyalBidAdapter_spec.js @@ -3,9 +3,19 @@ import { spec } from '../../../modules/loyalBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; -const bidder = 'loyal' +const bidder = 'loyal'; describe('LoyalBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -16,8 +26,9 @@ describe('LoyalBidAdapter', function () { } }, params: { - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -30,8 +41,9 @@ describe('LoyalBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -53,8 +65,9 @@ describe('LoyalBidAdapter', function () { } }, params: { - placementId: 'testNative', - } + placementId: 'testNative' + }, + userIdAsEids } ]; @@ -74,10 +87,19 @@ describe('LoyalBidAdapter', function () { const bidderRequest = { uspConsent: '1---', gdprConsent: { - consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw' + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } }, timeout: 500 }; @@ -147,7 +169,56 @@ describe('LoyalBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); - expect(placement.eids).to.exist.and.to.be.an('array'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -174,6 +245,9 @@ describe('LoyalBidAdapter', function () { let data = serverRequest.data; expect(data.gdpr).to.exist; expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); @@ -188,12 +262,38 @@ describe('LoyalBidAdapter', function () { expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); + }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([], bidderRequest); + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) }); describe('interpretResponse', function () { diff --git a/test/spec/modules/lunamediahbBidAdapter_spec.js b/test/spec/modules/lunamediahbBidAdapter_spec.js index 181b6e75fe7..f2653269c7b 100644 --- a/test/spec/modules/lunamediahbBidAdapter_spec.js +++ b/test/spec/modules/lunamediahbBidAdapter_spec.js @@ -1,145 +1,252 @@ import {expect} from 'chai'; import {spec} from '../../../modules/lunamediahbBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; +import { getUniqueIdentifierStr } from '../../../src/utils.js'; + +const bidder = 'lunamediahb'; describe('LunamediaHBBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'lunamediahb', + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + placementId: 'testBanner' + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + placementId: 'testVideo' + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + placementId: 'testNative' + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, mediaTypes: { [BANNER]: { sizes: [[300, 250]] } }, params: { - placementId: 783, - traffic: BANNER + } - }; + } const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, refererInfo: { - referer: 'test.com' - } + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } + }, + timeout: 500 }; describe('isBidRequestValid', function () { it('Should return true if there are bidId, params and key parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; + expect(spec.isBidRequestValid(bids[0])).to.be.true; }); it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; + expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); }); describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); + it('Creates a ServerRequest object with method, URL and data', function () { expect(serverRequest).to.exist; expect(serverRequest.method).to.exist; expect(serverRequest.url).to.exist; expect(serverRequest.data).to.exist; }); + it('Returns POST method', function () { expect(serverRequest.method).to.equal('POST'); }); + it('Returns valid URL', function () { expect(serverRequest.url).to.equal('https://balancer.lmgssp.com/?c=o&m=multi'); }); - it('Returns valid data if array of bids is valid', function () { + + it('Returns general data valid', function () { let data = serverRequest.data; expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data).to.have.all.keys('deviceWidth', + 'deviceHeight', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax' + ); expect(data.deviceWidth).to.be.a('number'); expect(data.deviceHeight).to.be.a('number'); expect(data.language).to.be.a('string'); expect(data.secure).to.be.within(0, 1); expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); - expect(data.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'schain'); - expect(placement.placementId).to.equal(783); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - expect(placement.sizes).to.be.an('array'); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); }); - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'wPlayer', 'hPlayer', 'schain', 'videoContext'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); - }); + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); - it('Returns valid data for mediatype native', function () { - const native = { - title: { - required: true - }, - body: { - required: true - }, - icon: { - required: true, - size: [64, 64] + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); } - }; - - bid.mediaTypes = {}; - bid.params.traffic = NATIVE; - bid.mediaTypes[NATIVE] = native; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'native', 'schain'); - expect(placement.traffic).to.equal(NATIVE); - expect(placement.native).to.equal(native); + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } }); it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.ccpa).to.exist; expect(data.ccpa).to.be.a('string'); expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) }); + describe('interpretResponse', function () { it('Should interpret banner response', function () { const banner = { @@ -154,23 +261,28 @@ describe('LunamediaHBBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', - dealId: '1' + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let bannerResponses = spec.interpretResponse(banner); expect(bannerResponses).to.be.an('array').that.is.not.empty; let dataItem = bannerResponses[0]; expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); + expect(dataItem.currency).to.equal(banner.body[0].currency); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); }); it('Should interpret video response', function () { const video = { @@ -183,7 +295,11 @@ describe('LunamediaHBBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', - dealId: '1' + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let videoResponses = spec.interpretResponse(video); @@ -191,7 +307,7 @@ describe('LunamediaHBBidAdapter', function () { let dataItem = videoResponses[0]; expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); expect(dataItem.requestId).to.equal('23fhj33i987f'); expect(dataItem.cpm).to.equal(0.5); expect(dataItem.vastUrl).to.equal('test.com'); @@ -199,6 +315,7 @@ describe('LunamediaHBBidAdapter', function () { expect(dataItem.creativeId).to.equal('2'); expect(dataItem.netRevenue).to.be.true; expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); }); it('Should interpret native response', function () { const native = { @@ -216,13 +333,17 @@ describe('LunamediaHBBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let nativeResponses = spec.interpretResponse(native); expect(nativeResponses).to.be.an('array').that.is.not.empty; let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta'); expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') expect(dataItem.requestId).to.equal('23fhj33i987f'); expect(dataItem.cpm).to.equal(0.4); @@ -235,6 +356,7 @@ describe('LunamediaHBBidAdapter', function () { expect(dataItem.creativeId).to.equal('2'); expect(dataItem.netRevenue).to.be.true; expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); }); it('Should return an empty array if invalid banner response is passed', function () { const invBanner = { @@ -326,5 +448,17 @@ describe('LunamediaHBBidAdapter', function () { expect(syncData[0].url).to.be.a('string') expect(syncData[0].url).to.equal('https://cookie.lmgssp.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://cookie.lmgssp.com/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0') + }); }); }); diff --git a/test/spec/modules/luponmediaBidAdapter_spec.js b/test/spec/modules/luponmediaBidAdapter_spec.js index 064bad74835..664c888b45e 100755 --- a/test/spec/modules/luponmediaBidAdapter_spec.js +++ b/test/spec/modules/luponmediaBidAdapter_spec.js @@ -21,12 +21,12 @@ describe('luponmediaBidAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'siteId': 12345 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/madvertiseBidAdapter_spec.js b/test/spec/modules/madvertiseBidAdapter_spec.js index 466d30acdd3..8128bcc2d42 100644 --- a/test/spec/modules/madvertiseBidAdapter_spec.js +++ b/test/spec/modules/madvertiseBidAdapter_spec.js @@ -118,7 +118,7 @@ describe('madvertise adapater', () => { expect(req[0].url).to.contain(`&zoneId=test`); expect(req[0].url).to.contain(`&sizes[0]=728x90`); expect(req[0].url).to.contain(`&gdpr=1`); - expect(req[0].url).to.contain(`&consent[0][format]=IAB`); + expect(req[0].url).to.contain(`&consent[0][format]=iab`); expect(req[0].url).to.contain(`&consent[0][value]=CO_5mtSPHOmEIAsAkBFRBOCsAP_AAH_AAAqIHQgB7SrERyNAYWB5gusAKYlfQAQCA2AABAYdASgJQQBAMJYEkGAIuAnAACAKAAAEIHQAAAAlCCmABAEAAIABBSGMAQgABZAAIiAEEAATAABACAABGYCSCAIQjIAAAAEAgEKEAAoAQGBAAAEgBABAAAogACADAgXmACIKkQBAkBAYAkAYQAogAhAAAAAIAAAAAAAKAABAAAghAAQQAAAAAAAAAgAAAAABAAAAAAAAQAAAAAAAAABAAgAAAAAAAAAIAAAAAAAAAAAAAAAABAAAAAAAAAAAQCAKCgBgEQALgAqkJADAIgAXABVIaACAAERABAACKgAgABA`) }); diff --git a/test/spec/modules/magniteAnalyticsAdapter_spec.js b/test/spec/modules/magniteAnalyticsAdapter_spec.js index 731b4ab1682..df06a4e38f7 100644 --- a/test/spec/modules/magniteAnalyticsAdapter_spec.js +++ b/test/spec/modules/magniteAnalyticsAdapter_spec.js @@ -1758,16 +1758,32 @@ describe('magnite analytics adapter', function () { }); }); describe('cookieless', () => { - beforeEach(() => { - magniteAdapter.enableAnalytics({ - options: { - cookieles: undefined - } - }); - }) afterEach(() => { magniteAdapter.disableAnalytics(); }) + it('should not add cookieless and preserve original rule name', () => { + // Set the confs + config.setConfig({ + rubicon: { + wrapperName: '1001_general', + wrapperFamily: 'general', + rule_name: 'desktop-magnite.com', + } + }); + performStandardAuction(); + + expect(server.requests.length).to.equal(1); + let request = server.requests[0]; + + expect(request.url).to.match(/\/\/localhost:9999\/event/); + + let message = JSON.parse(request.requestBody); + expect(message.wrapper).to.deep.equal({ + name: '1001_general', + family: 'general', + rule: 'desktop-magnite.com', + }); + }) it('should add sufix _cookieless to the wrapper.rule if ortb2.device.ext.cdep start with "treatment" or "control_2"', () => { // Set the confs config.setConfig({ diff --git a/test/spec/modules/mantisBidAdapter_spec.js b/test/spec/modules/mantisBidAdapter_spec.js index 579f41e620d..f0f453d32a0 100644 --- a/test/spec/modules/mantisBidAdapter_spec.js +++ b/test/spec/modules/mantisBidAdapter_spec.js @@ -35,10 +35,10 @@ describe('MantisAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/mathildeadsBidAdapter_spec.js b/test/spec/modules/mathildeadsBidAdapter_spec.js index 107906ec83d..e55e7175f4b 100644 --- a/test/spec/modules/mathildeadsBidAdapter_spec.js +++ b/test/spec/modules/mathildeadsBidAdapter_spec.js @@ -3,21 +3,32 @@ import { spec } from '../../../modules/mathildeadsBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; -const bidder = 'mathildeads' +const bidder = 'mathildeads'; describe('MathildeAdsBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), - bidder: bidder, + bidder, mediaTypes: { [BANNER]: { sizes: [[300, 250]] } }, params: { - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -30,8 +41,9 @@ describe('MathildeAdsBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -53,8 +65,9 @@ describe('MathildeAdsBidAdapter', function () { } }, params: { - placementId: 'testNative', - } + placementId: 'testNative' + }, + userIdAsEids } ]; @@ -66,14 +79,27 @@ describe('MathildeAdsBidAdapter', function () { sizes: [[300, 250]] } }, - params: {} + params: { + + } } const bidderRequest = { uspConsent: '1---', - gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } }, timeout: 500 }; @@ -127,7 +153,7 @@ describe('MathildeAdsBidAdapter', function () { expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); expect(data.coppa).to.be.a('number'); - expect(data.gdpr).to.be.a('string'); + expect(data.gdpr).to.be.a('object'); expect(data.ccpa).to.be.a('string'); expect(data.tmax).to.be.a('number'); expect(data.placements).to.have.lengthOf(3); @@ -142,6 +168,8 @@ describe('MathildeAdsBidAdapter', function () { expect(placement.bidId).to.be.a('string'); expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -167,8 +195,10 @@ describe('MathildeAdsBidAdapter', function () { serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); @@ -183,12 +213,38 @@ describe('MathildeAdsBidAdapter', function () { expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) }); describe('interpretResponse', function () { @@ -367,6 +423,7 @@ describe('MathildeAdsBidAdapter', function () { expect(serverResponses).to.be.an('array').that.is.empty; }); }); + describe('getUserSyncs', function() { it('Should return array of objects with proper sync config , include GDPR', function() { const syncData = spec.getUserSyncs({}, {}, { @@ -391,5 +448,17 @@ describe('MathildeAdsBidAdapter', function () { expect(syncData[0].url).to.be.a('string') expect(syncData[0].url).to.equal('https://cs2.mathilde-ads.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://cs2.mathilde-ads.com/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0') + }); }); }); diff --git a/test/spec/modules/mediafuseBidAdapter_spec.js b/test/spec/modules/mediafuseBidAdapter_spec.js index dd2b5df70bd..1fb09265d56 100644 --- a/test/spec/modules/mediafuseBidAdapter_spec.js +++ b/test/spec/modules/mediafuseBidAdapter_spec.js @@ -35,23 +35,23 @@ describe('MediaFuseAdapter', function () { }); it('should return true when required params found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'member': '1234', 'invCode': 'ABCD' }; - expect(spec.isBidRequestValid(bid)).to.equal(true); + expect(spec.isBidRequestValid(invalidBid)).to.equal(true); }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/mediagoBidAdapter_spec.js b/test/spec/modules/mediagoBidAdapter_spec.js index 6e58217b3d3..5a1545ae028 100644 --- a/test/spec/modules/mediagoBidAdapter_spec.js +++ b/test/spec/modules/mediagoBidAdapter_spec.js @@ -3,14 +3,11 @@ import { spec, getPmgUID, storage, - getPageTitle, - getPageDescription, - getPageKeywords, - getConnectionDownLink, THIRD_PARTY_COOKIE_ORIGIN, COOKIE_KEY_MGUID, getCurrentTimeToUTCString } from 'modules/mediagoBidAdapter.js'; +import { getPageTitle, getPageDescription, getPageKeywords, getConnectionDownLink } from '../../../libraries/fpdUtils/pageInfo.js'; import * as utils from 'src/utils.js'; describe('mediago:BidAdapterTests', function () { @@ -260,43 +257,43 @@ describe('mediago:BidAdapterTests', function () { expect(bid.height).to.equal(250); expect(bid.currency).to.equal('USD'); }); +}); - describe('mediago: getUserSyncs', function() { - const COOKY_SYNC_IFRAME_URL = 'https://cdn.mediago.io/js/cookieSync.html'; - const IFRAME_ENABLED = { - iframeEnabled: true, - pixelEnabled: false, - }; - const IFRAME_DISABLED = { - iframeEnabled: false, - pixelEnabled: false, - }; - const GDPR_CONSENT = { - consentString: 'gdprConsentString', - gdprApplies: true - }; - const USP_CONSENT = { - consentString: 'uspConsentString' +describe('mediago: getUserSyncs', function() { + const COOKY_SYNC_IFRAME_URL = 'https://cdn.mediago.io/js/cookieSync.html'; + const IFRAME_ENABLED = { + iframeEnabled: true, + pixelEnabled: false, + }; + const IFRAME_DISABLED = { + iframeEnabled: false, + pixelEnabled: false, + }; + const GDPR_CONSENT = { + consentString: 'gdprConsentString', + gdprApplies: true + }; + const USP_CONSENT = { + consentString: 'uspConsentString' + } + + let syncParamUrl = `dm=${encodeURIComponent(location.origin || `https://${location.host}`)}`; + syncParamUrl += '&gdpr=1&gdpr_consent=gdprConsentString&ccpa_consent=uspConsentString'; + const expectedIframeSyncs = [ + { + type: 'iframe', + url: `${COOKY_SYNC_IFRAME_URL}?${syncParamUrl}` } + ]; - let syncParamUrl = `dm=${encodeURIComponent(location.origin || `https://${location.host}`)}`; - syncParamUrl += '&gdpr=1&gdpr_consent=gdprConsentString&ccpa_consent=uspConsentString'; - const expectedIframeSyncs = [ - { - type: 'iframe', - url: `${COOKY_SYNC_IFRAME_URL}?${syncParamUrl}` - } - ]; - - it('should return nothing if iframe is disabled', () => { - const userSyncs = spec.getUserSyncs(IFRAME_DISABLED, undefined, GDPR_CONSENT, USP_CONSENT, undefined); - expect(userSyncs).to.be.undefined; - }); + it('should return nothing if iframe is disabled', () => { + const userSyncs = spec.getUserSyncs(IFRAME_DISABLED, undefined, GDPR_CONSENT, USP_CONSENT, undefined); + expect(userSyncs).to.be.undefined; + }); - it('should do userSyncs if iframe is enabled', () => { - const userSyncs = spec.getUserSyncs(IFRAME_ENABLED, undefined, GDPR_CONSENT, USP_CONSENT, undefined); - expect(userSyncs).to.deep.equal(expectedIframeSyncs); - }); + it('should do userSyncs if iframe is enabled', () => { + const userSyncs = spec.getUserSyncs(IFRAME_ENABLED, undefined, GDPR_CONSENT, USP_CONSENT, undefined); + expect(userSyncs).to.deep.equal(expectedIframeSyncs); }); }); diff --git a/test/spec/modules/medianetBidAdapter_spec.js b/test/spec/modules/medianetBidAdapter_spec.js index cc1a15fd733..d3eab769f4a 100644 --- a/test/spec/modules/medianetBidAdapter_spec.js +++ b/test/spec/modules/medianetBidAdapter_spec.js @@ -1,7 +1,8 @@ import {expect, assert} from 'chai'; -import {spec} from 'modules/medianetBidAdapter.js'; +import {spec, EVENT_PIXEL_URL, EVENTS} from 'modules/medianetBidAdapter.js'; import { makeSlot } from '../integration/faker/googletag.js'; import { config } from 'src/config.js'; +import {server} from '../../mocks/xhr.js'; $$PREBID_GLOBAL$$.version = $$PREBID_GLOBAL$$.version || 'version'; let VALID_BID_REQUEST = [{ @@ -264,6 +265,72 @@ let VALID_BID_REQUEST = [{ 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', 'bidRequestsCount': 1 }], + VALID_BID_REQUEST_WITH_USERIDASEIDS = [{ + 'bidder': 'medianet', + 'params': { + 'crid': 'crid', + 'cid': 'customer_id', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + }, + userIdAsEids: [{ + 'source': 'criteo.com', + 'uids': [ + { + 'id': 'VZME3l9ycFFORncwaGJRVUNtUzB1UVhpWVd5TElrR3A5SHVSWXAwSFVPJTJCWiUyRnV2UTBPWjZOZ1ZrWnN4SldxcWUlMkJhUnFmUVNzUVg4N1NsdW84SGpUU1BsUllQSnN5bERMdFdPM2pWVXAlMkZVSSUyQkZsJTJGcktlenpZaHp0YXlvU25INWRQQ2tXciUyRk9PQmdac3RHeG9adDNKVzlRWE51ZyUzRCUzRA', + 'atype': 1 + } + ] + } + ], + 'adUnitCode': 'div-gpt-ad-1460505748561-0', + ortb2Imp: { + ext: { + tid: '277b631f-92f5-4844-8b19-ea13c095d3f1', + } + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]], + } + }, + 'bidId': '28f8f8130a583e', + 'bidderRequestId': '1e9b1f07797c1c', + 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', + 'bidRequestsCount': 1 + }, { + 'bidder': 'medianet', + 'params': { + 'crid': 'crid', + 'cid': 'customer_id', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + }, + 'adUnitCode': 'div-gpt-ad-1460505748561-123', + ortb2Imp: { + ext: { + tid: 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', + } + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 251]], + } + }, + 'sizes': [[300, 251]], + 'bidId': '3f97ca71b1e5c2', + 'bidderRequestId': '1e9b1f07797c1c', + 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', + 'bidRequestsCount': 1 + }], VALID_BID_REQUEST_INVALID_BIDFLOOR = [{ 'bidder': 'medianet', @@ -457,7 +524,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_applies': false, 'usp_applies': false, 'coppa_applies': false, @@ -535,6 +602,7 @@ let VALID_BID_REQUEST = [{ } } }], + 'ortb2': {}, 'tmax': config.getConfig('bidderTimeout') }, VALID_PAYLOAD_NATIVE = { @@ -547,7 +615,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_applies': false, 'usp_applies': false, 'coppa_applies': false, @@ -626,6 +694,7 @@ let VALID_BID_REQUEST = [{ } } }], + 'ortb2': {}, 'tmax': config.getConfig('bidderTimeout') }, VALID_PAYLOAD = { @@ -638,7 +707,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_applies': false, 'usp_applies': false, 'coppa_applies': false, @@ -715,6 +784,7 @@ let VALID_BID_REQUEST = [{ } } }], + 'ortb2': {}, 'tmax': config.getConfig('bidderTimeout') }, VALID_PAYLOAD_WITH_USERID = { @@ -727,7 +797,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_applies': false, 'user_id': { britepoolid: '82efd5e1-816b-4f87-97f8-044f407e2911' @@ -811,6 +881,114 @@ let VALID_BID_REQUEST = [{ } } }], + 'ortb2': {}, + 'tmax': config.getConfig('bidderTimeout') + }, + VALID_PAYLOAD_WITH_USERIDASEIDS = { + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'topMostLocation': 'http://media.net/topmost', + 'isTop': true + }, + 'ext': { + 'customer_id': 'customer_id', + 'prebid_version': 'v' + '$prebid.version$', + 'gdpr_applies': false, + 'usp_applies': false, + 'coppa_applies': false, + 'screen': { + 'w': 1000, + 'h': 1000 + } + }, + 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', + 'imp': [{ + 'id': '28f8f8130a583e', + ortb2Imp: VALID_BID_REQUEST_WITH_USERID[0].ortb2Imp, + 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', + 'tagid': 'crid', + 'ext': { + 'dfp_id': 'div-gpt-ad-1460505748561-0', + 'visibility': 1, + 'viewability': 1, + 'coordinates': { + 'top_left': { + x: 50, + y: 50 + }, + 'bottom_right': { + x: 100, + y: 100 + } + }, + 'display_count': 1 + }, + 'banner': [{ + 'w': 300, + 'h': 250 + }], + 'all': { + 'cid': 'customer_id', + 'crid': 'crid', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + } + }, { + 'id': '3f97ca71b1e5c2', + ortb2Imp: VALID_BID_REQUEST_WITH_USERID[1].ortb2Imp, + 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', + 'tagid': 'crid', + 'ext': { + 'dfp_id': 'div-gpt-ad-1460505748561-123', + 'visibility': 1, + 'viewability': 1, + 'coordinates': { + 'top_left': { + x: 50, + y: 50 + }, + 'bottom_right': { + x: 100, + y: 100 + } + }, + 'display_count': 1 + }, + 'banner': [{ + 'w': 300, + 'h': 251 + }], + 'all': { + 'cid': 'customer_id', + 'crid': 'crid', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + } + }], + 'ortb2': { + 'user': { + 'ext': { + 'eids': [{ + 'source': 'criteo.com', + 'uids': [{ + 'id': 'VZME3l9ycFFORncwaGJRVUNtUzB1UVhpWVd5TElrR3A5SHVSWXAwSFVPJTJCWiUyRnV2UTBPWjZOZ1ZrWnN4SldxcWUlMkJhUnFmUVNzUVg4N1NsdW84SGpUU1BsUllQSnN5bERMdFdPM2pWVXAlMkZVSSUyQkZsJTJGcktlenpZaHp0YXlvU25INWRQQ2tXciUyRk9PQmdac3RHeG9adDNKVzlRWE51ZyUzRCUzRA', + 'atype': 1 + } + ] + }] + } + }, + }, 'tmax': config.getConfig('bidderTimeout') }, VALID_PAYLOAD_WITH_CRID = { @@ -823,7 +1001,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_applies': false, 'usp_applies': false, 'coppa_applies': true, @@ -904,6 +1082,7 @@ let VALID_BID_REQUEST = [{ } } }], + 'ortb2': {}, 'tmax': config.getConfig('bidderTimeout') }, // Protected Audience API Valid Payload @@ -917,7 +1096,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_applies': false, 'usp_applies': false, 'coppa_applies': false, @@ -973,6 +1152,7 @@ let VALID_BID_REQUEST = [{ 'tagid': 'crid' } ], + 'ortb2': {}, 'tmax': 3000 }, @@ -1451,7 +1631,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_consent_string': 'consentString', 'gdpr_applies': true, 'usp_applies': true, @@ -1530,6 +1710,7 @@ let VALID_BID_REQUEST = [{ } } }], + 'ortb2': {}, 'tmax': 3000, }, VALID_BIDDER_REQUEST_WITH_GPP_IN_ORTB2 = { @@ -1559,7 +1740,7 @@ let VALID_BID_REQUEST = [{ }, 'ext': { 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, + 'prebid_version': 'v' + '$prebid.version$', 'gdpr_applies': false, 'usp_applies': false, 'coppa_applies': false, @@ -1767,13 +1948,18 @@ describe('Media.net bid adapter', function () { expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_WITH_USERID); }); + it('should have userIdAsEids in bid request', function () { + let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_USERIDASEIDS, VALID_AUCTIONDATA); + expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_WITH_USERIDASEIDS); + }); + it('should have valid payload when PAAPI is enabled', function () { - let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, fledgeEnabled: true}); + let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_PAAPI); }); it('should send whatever is set in ortb2imp.ext.ae in all bid requests when PAAPI is enabled', function () { - let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, fledgeEnabled: true}); + let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); let data = JSON.parse(bidReq.data); expect(data).to.deep.equal(VALID_PAYLOAD_PAAPI); expect(data.imp[0].ext).to.have.property('ae'); @@ -1782,7 +1968,7 @@ describe('Media.net bid adapter', function () { describe('build requests: when page meta-data is available', () => { beforeEach(() => { - spec.clearMnData(); + spec.clearPageMeta(); }); it('should pass canonical, twitter and fb paramters if available', () => { let documentStub = sandbox.stub(window.top.document, 'querySelector'); @@ -1955,44 +2141,139 @@ describe('Media.net bid adapter', function () { expect(bids).to.deep.equal(validBids); }); - it('should return fledgeAuctionConfigs if PAAPI response is received', function() { + it('should return paapi if PAAPI response is received', function() { let response = spec.interpretResponse(SERVER_RESPONSE_PAAPI, []); expect(response).to.have.property('bids'); - expect(response).to.have.property('fledgeAuctionConfigs'); - expect(response.fledgeAuctionConfigs[0]).to.deep.equal(SERVER_RESPONSE_PAAPI.body.ext.paApiAuctionConfigs[0]); + expect(response).to.have.property('paapi'); + expect(response.paapi[0]).to.deep.equal(SERVER_RESPONSE_PAAPI.body.ext.paApiAuctionConfigs[0]); }); - it('should return fledgeAuctionConfigs if openRTB PAAPI response received', function () { + it('should return paapi if openRTB PAAPI response received', function () { let response = spec.interpretResponse(SERVER_RESPONSE_PAAPI_ORTB, []); expect(response).to.have.property('bids'); - expect(response).to.have.property('fledgeAuctionConfigs'); - expect(response.fledgeAuctionConfigs[0]).to.deep.equal(SERVER_RESPONSE_PAAPI_ORTB.body.ext.igi[0].igs[0]) + expect(response).to.have.property('paapi'); + expect(response.paapi[0]).to.deep.equal(SERVER_RESPONSE_PAAPI_ORTB.body.ext.igi[0].igs[0]) }); - it('should have the correlation between fledgeAuctionConfigs[0].bidId and bidreq.imp[0].id', function() { - let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, fledgeEnabled: true}); + it('should have the correlation between paapi[0].bidId and bidreq.imp[0].id', function() { + let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); let bidRes = spec.interpretResponse(SERVER_RESPONSE_PAAPI, []); - expect(bidRes.fledgeAuctionConfigs[0].bidId).to.equal(JSON.parse(bidReq.data).imp[0].id) + expect(bidRes.paapi[0].bidId).to.equal(JSON.parse(bidReq.data).imp[0].id) }); - it('should have the correlation between fledgeAuctionConfigs[0].bidId and bidreq.imp[0].id for openRTB response', function() { - let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, fledgeEnabled: true}); + it('should have the correlation between paapi[0].bidId and bidreq.imp[0].id for openRTB response', function() { + let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); let bidRes = spec.interpretResponse(SERVER_RESPONSE_PAAPI_ORTB, []); - expect(bidRes.fledgeAuctionConfigs[0].bidId).to.equal(JSON.parse(bidReq.data).imp[0].id) + expect(bidRes.paapi[0].bidId).to.equal(JSON.parse(bidReq.data).imp[0].id) }); }); describe('onTimeout', function () { - it('should have valid timeout data', function() { - let response = spec.onTimeout({}); - expect(response).to.deep.equal(undefined); + it('onTimeout exist as a function', () => { + assert.typeOf(spec.onTimeout, 'function'); + }); + it('should send timeout data correctly', function () { + const timeoutData = [{ + bidder: 'medianet', + bidId: 'mnet-4644-442a-b5e0-93f268cf8d19', + adUnitCode: 'adUnit-code', + timeout: 3000, + auctionId: '12a34b56c' + }]; + sandbox.stub(window.navigator, 'sendBeacon').returns(false); + + spec.onTimeout(timeoutData); + const reqBody = new URLSearchParams(server.requests[0].requestBody); + + assert.equal(server.requests[0].method, 'POST'); + assert.equal(server.requests[0].url, EVENT_PIXEL_URL); + assert.equal(reqBody.get('event'), EVENTS.TIMEOUT_EVENT_NAME); + assert.equal(reqBody.get('rd'), timeoutData[0].timeout.toString()); + assert.equal(reqBody.get('acid[]'), timeoutData[0].auctionId); }); }); describe('onBidWon', function () { - it('should have valid bid data', function() { - let response = spec.onBidWon(undefined); - expect(response).to.deep.equal(undefined); + it('onBidWon exist as a function', () => { + assert.typeOf(spec.onBidWon, 'function'); + }); + it('should send winning bid data correctly', function () { + const bid = { + bidder: 'medianet', + bidId: 'mnet-4644-442a-b5e0-93f268cf8d19', + adUnitCode: 'adUnit-code', + timeout: 3000, + auctionId: '12a34b56c', + cpm: 12.24 + }; + sandbox.stub(window.navigator, 'sendBeacon').returns(false); + + spec.onBidWon(bid); + const reqBody = new URLSearchParams(server.requests[0].requestBody); + + assert.equal(server.requests[0].method, 'POST'); + assert.equal(server.requests[0].url, EVENT_PIXEL_URL); + assert.equal(reqBody.get('event'), EVENTS.BID_WON_EVENT_NAME); + assert.equal(reqBody.get('value'), bid.cpm.toString()); + assert.equal(reqBody.get('acid[]'), bid.auctionId); + }); + }); + + describe('onSetTargeting', function () { + it('onSetTargeting exist as a function', () => { + assert.typeOf(spec.onSetTargeting, 'function'); + }); + it('should send targeting data correctly', function () { + const bid = { + bidder: 'medianet', + bidId: 'mnet-4644-442a-b5e0-93f268cf8d19', + adUnitCode: 'adUnit-code', + timeout: 3000, + auctionId: '12a34b56c', + cpm: 12.24 + }; + sandbox.stub(window.navigator, 'sendBeacon').returns(false); + sandbox.stub(config, 'getConfig').withArgs('enableSendAllBids').returns(false); + + spec.onSetTargeting(bid); + const reqBody = new URLSearchParams(server.requests[0].requestBody); + + assert.equal(server.requests[0].method, 'POST'); + assert.equal(server.requests[0].url, EVENT_PIXEL_URL); + assert.equal(reqBody.get('event'), EVENTS.SET_TARGETING); + assert.equal(reqBody.get('value'), bid.cpm.toString()); + assert.equal(reqBody.get('acid[]'), bid.auctionId); + }); + }); + + describe('onBidderError', function () { + it('onBidderError exist as a function', () => { + assert.typeOf(spec.onBidderError, 'function'); + }); + it('should send bidderError data correctly', function () { + const error = { + reason: {message: 'Failed to fetch', status: 500}, + timedOut: true, + status: 0 + } + const bids = [{ + bidder: 'medianet', + bidId: 'mnet-4644-442a-b5e0-93f268cf8d19', + adUnitCode: 'adUnit-code', + timeout: 3000, + auctionId: '12a34b56c', + cpm: 12.24 + }]; + sandbox.stub(window.navigator, 'sendBeacon').returns(false); + + spec.onBidderError({error, bidderRequest: {bids}}); + const reqBody = new URLSearchParams(server.requests[0].requestBody); + + assert.equal(server.requests[0].method, 'POST'); + assert.equal(server.requests[0].url, EVENT_PIXEL_URL); + assert.equal(reqBody.get('event'), EVENTS.BIDDER_ERROR); + assert.equal(reqBody.get('rd'), `timedOut:${error.timedOut}|status:${error.status}|message:${error.reason.message}`); + assert.equal(reqBody.get('acid[]'), bids[0].auctionId); }); }); diff --git a/test/spec/modules/mgidBidAdapter_spec.js b/test/spec/modules/mgidBidAdapter_spec.js index f9bb1fb91e1..180b0dc723e 100644 --- a/test/spec/modules/mgidBidAdapter_spec.js +++ b/test/spec/modules/mgidBidAdapter_spec.js @@ -320,6 +320,14 @@ describe('Mgid bid adapter', function () { let abid = { adUnitCode: 'div', bidder: 'mgid', + ortb2Imp: { + ext: { + gpid: '/1111/gpid', + data: { + pbadslot: '/1111/gpid', + } + } + }, params: { accountId: '1', placementId: '2', @@ -447,12 +455,13 @@ describe('Mgid bid adapter', function () { expect(data.device.w).equal(screenWidth); expect(data.device.language).to.deep.equal(lang); expect(data.imp[0].tagid).to.deep.equal('2/div'); + expect(data.imp[0].ext.gpid).to.deep.equal('/1111/gpid'); expect(data.imp[0].banner).to.deep.equal({w: 300, h: 250}); expect(data.imp[0].secure).to.deep.equal(secure); expect(request).to.deep.equal({ 'method': 'POST', 'url': 'https://prebid.mgid.com/prebid/1', - 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"banner":{"w":300,"h":250}}],"tmax":3000}`, + 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"banner":{"w":300,"h":250}}],"tmax":3000}`, }); }); it('should not return native imp if minimum asset list not requested', function () { @@ -496,12 +505,13 @@ describe('Mgid bid adapter', function () { expect(data.device.w).equal(screenWidth); expect(data.device.language).to.deep.equal(lang); expect(data.imp[0].tagid).to.deep.equal('2/div'); + expect(data.imp[0].ext.gpid).to.deep.equal('/1111/gpid'); expect(data.imp[0].native).is.a('object').and.to.deep.equal({'request': {'assets': [{'id': 1, 'required': 1, 'title': {'len': 80}}, {'id': 2, 'img': {'h': 80, 'type': 3, 'w': 80}, 'required': 0}, {'data': {'type': 1}, 'id': 11, 'required': 0}], 'plcmtcnt': 1}}); expect(data.imp[0].secure).to.deep.equal(secure); expect(request).to.deep.equal({ 'method': 'POST', 'url': 'https://prebid.mgid.com/prebid/1', - 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`, + 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`, }); }); it('should return proper native imp with image altered', function () { @@ -538,7 +548,7 @@ describe('Mgid bid adapter', function () { expect(request).to.deep.equal({ 'method': 'POST', 'url': 'https://prebid.mgid.com/prebid/1', - 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":1,"img":{"type":3,"w":492,"h":328,"wmin":50,"hmin":50}},{"id":3,"required":0,"img":{"type":1,"w":50,"h":50}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`, + 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":1,"img":{"type":3,"w":492,"h":328,"wmin":50,"hmin":50}},{"id":3,"required":0,"img":{"type":1,"w":50,"h":50}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`, }); }); it('should return proper native imp with sponsoredBy', function () { @@ -574,7 +584,7 @@ describe('Mgid bid adapter', function () { expect(request).to.deep.equal({ 'method': 'POST', 'url': 'https://prebid.mgid.com/prebid/1', - 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":4,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`, + 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":4,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`, }); }); it('should return proper banner request', function () { @@ -608,7 +618,7 @@ describe('Mgid bid adapter', function () { expect(request).to.deep.equal({ 'method': 'POST', 'url': 'https://prebid.mgid.com/prebid/1', - 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"banner":{"w":300,"h":600,"format":[{"w":300,"h":600},{"w":300,"h":250}],"pos":1}}],"tmax":3000}`, + 'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"banner":{"w":300,"h":600,"format":[{"w":300,"h":600},{"w":300,"h":250}],"pos":1}}],"tmax":3000}`, }); }); it('should proper handle ortb2 data', function () { diff --git a/test/spec/modules/mgidXBidAdapter_spec.js b/test/spec/modules/mgidXBidAdapter_spec.js index 9efaf94c954..ae1ca17c70a 100644 --- a/test/spec/modules/mgidXBidAdapter_spec.js +++ b/test/spec/modules/mgidXBidAdapter_spec.js @@ -5,9 +5,19 @@ import { getUniqueIdentifierStr } from '../../../src/utils.js'; import { config } from '../../../src/config'; import { USERSYNC_DEFAULT_CONFIG } from '../../../src/userSync'; -const bidder = 'mgidX' +const bidder = 'mgidX'; describe('MGIDXBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -19,8 +29,9 @@ describe('MGIDXBidAdapter', function () { }, params: { region: 'eu', - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -33,8 +44,9 @@ describe('MGIDXBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -57,8 +69,9 @@ describe('MGIDXBidAdapter', function () { }, params: { region: 'eu', - placementId: 'testNative', - } + placementId: 'testNative' + }, + userIdAsEids } ]; @@ -82,9 +95,17 @@ describe('MGIDXBidAdapter', function () { vendorData: {} }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' }, - timeout: 1000 + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } + }, + timeout: 500 }; describe('isBidRequestValid', function () { @@ -160,6 +181,56 @@ describe('MGIDXBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -205,6 +276,38 @@ describe('MGIDXBidAdapter', function () { }); }); + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) + }); + describe('interpretResponse', function () { it('Should interpret banner response', function () { const banner = { diff --git a/test/spec/modules/microadBidAdapter_spec.js b/test/spec/modules/microadBidAdapter_spec.js index 9eb36d2fa6c..ac1738685db 100644 --- a/test/spec/modules/microadBidAdapter_spec.js +++ b/test/spec/modules/microadBidAdapter_spec.js @@ -301,10 +301,6 @@ describe('microadBidAdapter', () => { userId: {novatiq: {snowflake: 'novatiq-sample'}}, expected: {aids: JSON.stringify([{type: 10, id: 'novatiq-sample'}])} }, - 'Parrable ID': { - userId: {parrableId: {eid: 'parrable-sample'}}, - expected: {aids: JSON.stringify([{type: 11, id: 'parrable-sample'}])} - }, 'AudienceOne User ID': { userId: {dacId: {id: 'audience-one-sample'}}, expected: {aids: JSON.stringify([{type: 12, id: 'audience-one-sample'}])} diff --git a/test/spec/modules/minutemediaplusBidAdapter_spec.js b/test/spec/modules/minutemediaplusBidAdapter_spec.js deleted file mode 100644 index 5101f015b0e..00000000000 --- a/test/spec/modules/minutemediaplusBidAdapter_spec.js +++ /dev/null @@ -1,654 +0,0 @@ -import {expect} from 'chai'; -import { - spec as adapter, - createDomain, - hashCode, - extractPID, - extractCID, - extractSubDomain, - getStorageItem, - setStorageItem, - tryParseJSON, - getUniqueDealId, -} from 'modules/minutemediaplusBidAdapter.js'; -import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes'; -import {config} from '../../../src/config'; - -export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; - -const SUB_DOMAIN = 'exchange'; - -const BID = { - 'bidId': '2d52001cabd527', - 'adUnitCode': 'div-gpt-ad-12345-0', - 'params': { - 'subDomain': SUB_DOMAIN, - 'cId': '59db6b3b4ffaa70004f45cdc', - 'pId': '59ac17c192832d0011283fe3', - 'bidFloor': 0.1, - 'ext': { - 'param1': 'loremipsum', - 'param2': 'dolorsitamet' - } - }, - 'placementCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidderRequestId': '1fdb5ff1b6eaa7', - 'auctionId': 'auction_id', - 'bidRequestsCount': 4, - 'bidderRequestsCount': 3, - 'bidderWinsCount': 1, - 'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a', - 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc', - 'mediaTypes': [BANNER], - 'ortb2Imp': { - 'ext': { - 'gpid': '1234567890', - tid: 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf', - } - } -}; - -const VIDEO_BID = { - 'bidId': '2d52001cabd527', - 'adUnitCode': '63550ad1ff6642d368cba59dh5884270560', - 'bidderRequestId': '12a8ae9ada9c13', - 'auctionId': 'auction_id', - 'bidRequestsCount': 4, - 'bidderRequestsCount': 3, - 'bidderWinsCount': 1, - ortb2Imp: { - ext: { - tid: '56e184c6-bde9-497b-b9b9-cf47a61381ee', - } - }, - 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc', - 'params': { - 'subDomain': SUB_DOMAIN, - 'cId': '635509f7ff6642d368cb9837', - 'pId': '59ac17c192832d0011283fe3', - 'bidFloor': 0.1 - }, - 'sizes': [[545, 307]], - 'mediaTypes': { - 'video': { - 'playerSize': [[545, 307]], - 'context': 'instream', - 'mimes': [ - 'video/mp4', - 'application/javascript' - ], - 'protocols': [2, 3, 5, 6], - 'maxduration': 60, - 'minduration': 0, - 'startdelay': 0, - 'linearity': 1, - 'api': [2], - 'placement': 1 - } - } -} - -const BIDDER_REQUEST = { - 'gdprConsent': { - 'consentString': 'consent_string', - 'gdprApplies': true - }, - 'gppString': 'gpp_string', - 'gppSid': [7], - 'uspConsent': 'consent_string', - 'refererInfo': { - 'page': 'https://www.greatsite.com', - 'ref': 'https://www.somereferrer.com' - }, - 'ortb2': { - 'regs': { - 'gpp': 'gpp_string', - 'gpp_sid': [7] - }, - 'device': { - 'sua': { - 'source': 2, - 'platform': { - 'brand': 'Android', - 'version': ['8', '0', '0'] - }, - 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} - ], - 'mobile': 1, - 'model': 'SM-G955U', - 'bitness': '64', - 'architecture': '' - } - } - }, -}; - -const SERVER_RESPONSE = { - body: { - cid: 'testcid123', - results: [{ - 'ad': '', - 'price': 0.8, - 'creativeId': '12610997325162499419', - 'exp': 30, - 'width': 300, - 'height': 250, - 'advertiserDomains': ['securepubads.g.doubleclick.net'], - 'cookies': [{ - 'src': 'https://sync.com', - 'type': 'iframe' - }, { - 'src': 'https://sync.com', - 'type': 'img' - }] - }] - } -}; - -const VIDEO_SERVER_RESPONSE = { - body: { - 'cid': '635509f7ff6642d368cb9837', - 'results': [{ - 'ad': '', - 'advertiserDomains': ['minutemedia-prebid.com'], - 'exp': 60, - 'width': 545, - 'height': 307, - 'mediaType': 'video', - 'creativeId': '12610997325162499419', - 'price': 2, - 'cookies': [] - }] - } -}; - -const REQUEST = { - data: { - width: 300, - height: 250, - bidId: '2d52001cabd527' - } -}; - -function getTopWindowQueryParams() { - try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} - -describe('MinuteMediaPlus Bid Adapter', function () { - describe('validtae spec', function () { - it('exists and is a function', function () { - expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function'); - }); - - it('exists and is a function', function () { - expect(adapter.buildRequests).to.exist.and.to.be.a('function'); - }); - - it('exists and is a function', function () { - expect(adapter.interpretResponse).to.exist.and.to.be.a('function'); - }); - - it('exists and is a function', function () { - expect(adapter.getUserSyncs).to.exist.and.to.be.a('function'); - }); - - it('exists and is a string', function () { - expect(adapter.code).to.exist.and.to.be.a('string'); - }); - - it('exists and contains media types', function () { - expect(adapter.supportedMediaTypes).to.exist.and.to.be.an('array').with.length(2); - expect(adapter.supportedMediaTypes).to.contain.members([BANNER, VIDEO]); - }); - }); - - describe('validate bid requests', function () { - it('should require cId', function () { - const isValid = adapter.isBidRequestValid({ - params: { - pId: 'pid' - } - }); - expect(isValid).to.be.false; - }); - - it('should require pId', function () { - const isValid = adapter.isBidRequestValid({ - params: { - cId: 'cid' - } - }); - expect(isValid).to.be.false; - }); - - it('should validate correctly', function () { - const isValid = adapter.isBidRequestValid({ - params: { - cId: 'cid', - pId: 'pid' - } - }); - expect(isValid).to.be.true; - }); - }); - - describe('build requests', function () { - let sandbox; - before(function () { - $$PREBID_GLOBAL$$.bidderSettings = { - mmplus: { - storageAllowed: true - } - }; - sandbox = sinon.sandbox.create(); - sandbox.stub(Date, 'now').returns(1000); - }); - - it('should build video request', function () { - const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page); - config.setConfig({ - bidderTimeout: 3000 - }); - const requests = adapter.buildRequests([VIDEO_BID], BIDDER_REQUEST); - expect(requests).to.have.length(1); - expect(requests[0]).to.deep.equal({ - method: 'POST', - url: `${createDomain(SUB_DOMAIN)}/prebid/multi/635509f7ff6642d368cb9837`, - data: { - adUnitCode: '63550ad1ff6642d368cba59dh5884270560', - bidFloor: 0.1, - bidId: '2d52001cabd527', - bidderVersion: adapter.version, - bidderRequestId: '12a8ae9ada9c13', - cb: 1000, - gdpr: 1, - gdprConsent: 'consent_string', - usPrivacy: 'consent_string', - gppString: 'gpp_string', - gppSid: [7], - prebidVersion: version, - transactionId: '56e184c6-bde9-497b-b9b9-cf47a61381ee', - auctionId: 'auction_id', - bidRequestsCount: 4, - bidderRequestsCount: 3, - bidderWinsCount: 1, - bidderTimeout: 3000, - publisherId: '59ac17c192832d0011283fe3', - url: 'https%3A%2F%2Fwww.greatsite.com', - referrer: 'https://www.somereferrer.com', - res: `${window.top.screen.width}x${window.top.screen.height}`, - schain: VIDEO_BID.schain, - sizes: ['545x307'], - sua: { - 'source': 2, - 'platform': { - 'brand': 'Android', - 'version': ['8', '0', '0'] - }, - 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} - ], - 'mobile': 1, - 'model': 'SM-G955U', - 'bitness': '64', - 'architecture': '' - }, - uniqueDealId: `${hashUrl}_${Date.now().toString()}`, - uqs: getTopWindowQueryParams(), - mediaTypes: { - video: { - api: [2], - context: 'instream', - linearity: 1, - maxduration: 60, - mimes: [ - 'video/mp4', - 'application/javascript' - ], - minduration: 0, - placement: 1, - playerSize: [[545, 307]], - protocols: [2, 3, 5, 6], - startdelay: 0 - } - }, - gpid: '' - } - }); - }); - - it('should build banner request for each size', function () { - const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page); - config.setConfig({ - bidderTimeout: 3000 - }); - const requests = adapter.buildRequests([BID], BIDDER_REQUEST); - expect(requests).to.have.length(1); - expect(requests[0]).to.deep.equal({ - method: 'POST', - url: `${createDomain(SUB_DOMAIN)}/prebid/multi/59db6b3b4ffaa70004f45cdc`, - data: { - gdprConsent: 'consent_string', - gdpr: 1, - gppString: 'gpp_string', - gppSid: [7], - usPrivacy: 'consent_string', - transactionId: 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf', - auctionId: 'auction_id', - bidRequestsCount: 4, - bidderRequestsCount: 3, - bidderWinsCount: 1, - bidderTimeout: 3000, - bidderRequestId: '1fdb5ff1b6eaa7', - sizes: ['300x250', '300x600'], - sua: { - 'source': 2, - 'platform': { - 'brand': 'Android', - 'version': ['8', '0', '0'] - }, - 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} - ], - 'mobile': 1, - 'model': 'SM-G955U', - 'bitness': '64', - 'architecture': '' - }, - url: 'https%3A%2F%2Fwww.greatsite.com', - referrer: 'https://www.somereferrer.com', - cb: 1000, - bidFloor: 0.1, - bidId: '2d52001cabd527', - adUnitCode: 'div-gpt-ad-12345-0', - publisherId: '59ac17c192832d0011283fe3', - uniqueDealId: `${hashUrl}_${Date.now().toString()}`, - bidderVersion: adapter.version, - prebidVersion: version, - schain: BID.schain, - res: `${window.top.screen.width}x${window.top.screen.height}`, - mediaTypes: [BANNER], - gpid: '1234567890', - uqs: getTopWindowQueryParams(), - 'ext.param1': 'loremipsum', - 'ext.param2': 'dolorsitamet', - } - }); - }); - - after(function () { - $$PREBID_GLOBAL$$.bidderSettings = {}; - sandbox.restore(); - }); - }); - describe('getUserSyncs', function () { - it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); - - expect(result).to.deep.equal([{ - type: 'iframe', - url: 'https://sync.minutemedia-prebid.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=' - }]); - }); - - it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); - expect(result).to.deep.equal([{ - type: 'iframe', - url: 'https://sync.minutemedia-prebid.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=' - }]); - }); - - it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); - - expect(result).to.deep.equal([{ - 'url': 'https://sync.minutemedia-prebid.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=', - 'type': 'image' - }]); - }) - - it('should generate url with consent data', function () { - const gdprConsent = { - gdprApplies: true, - consentString: 'consent_string' - }; - const uspConsent = 'usp_string'; - const gppConsent = { - gppString: 'gpp_string', - applicableSections: [7] - } - - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); - - expect(result).to.deep.equal([{ - 'url': 'https://sync.minutemedia-prebid.com/api/sync/image/?cid=testcid123&gdpr=1&gdpr_consent=consent_string&us_privacy=usp_string&gpp=gpp_string&gpp_sid=7', - 'type': 'image' - }]); - }); - }); - - describe('interpret response', function () { - it('should return empty array when there is no response', function () { - const responses = adapter.interpretResponse(null); - expect(responses).to.be.empty; - }); - - it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); - expect(responses).to.be.empty; - }); - - it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); - expect(responses).to.be.empty; - }); - - it('should return an array of interpreted banner responses', function () { - const responses = adapter.interpretResponse(SERVER_RESPONSE, REQUEST); - expect(responses).to.have.length(1); - expect(responses[0]).to.deep.equal({ - requestId: '2d52001cabd527', - cpm: 0.8, - width: 300, - height: 250, - creativeId: '12610997325162499419', - currency: 'USD', - netRevenue: true, - ttl: 30, - ad: '', - meta: { - advertiserDomains: ['securepubads.g.doubleclick.net'] - } - }); - }); - - it('should get meta from response metaData', function () { - const serverResponse = utils.deepClone(SERVER_RESPONSE); - serverResponse.body.results[0].metaData = { - advertiserDomains: ['minutemedia-prebid.com'], - agencyName: 'Agency Name', - }; - const responses = adapter.interpretResponse(serverResponse, REQUEST); - expect(responses[0].meta).to.deep.equal({ - advertiserDomains: ['minutemedia-prebid.com'], - agencyName: 'Agency Name' - }); - }); - - it('should return an array of interpreted video responses', function () { - const responses = adapter.interpretResponse(VIDEO_SERVER_RESPONSE, REQUEST); - expect(responses).to.have.length(1); - expect(responses[0]).to.deep.equal({ - requestId: '2d52001cabd527', - cpm: 2, - width: 545, - height: 307, - mediaType: 'video', - creativeId: '12610997325162499419', - currency: 'USD', - netRevenue: true, - ttl: 60, - vastXml: '', - meta: { - advertiserDomains: ['minutemedia-prebid.com'] - } - }); - }); - - it('should take default TTL', function () { - const serverResponse = utils.deepClone(SERVER_RESPONSE); - delete serverResponse.body.results[0].exp; - const responses = adapter.interpretResponse(serverResponse, REQUEST); - expect(responses).to.have.length(1); - expect(responses[0].ttl).to.equal(300); - }); - }); - - describe('user id system', function () { - TEST_ID_SYSTEMS.forEach((idSystemProvider) => { - const id = Date.now().toString(); - const bid = utils.deepClone(BID); - - const userId = (function () { - switch (idSystemProvider) { - case 'lipb': - return {lipbid: id}; - case 'parrableId': - return {eid: id}; - case 'id5id': - return {uid: id}; - default: - return id; - } - })(); - - bid.userId = { - [idSystemProvider]: userId - }; - - it(`should include 'uid.${idSystemProvider}' in request params`, function () { - const requests = adapter.buildRequests([bid], BIDDER_REQUEST); - expect(requests[0].data[`uid.${idSystemProvider}`]).to.equal(id); - }); - }); - }); - - describe('alternate param names extractors', function () { - it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); - expect(cid).to.be.undefined; - expect(pid).to.be.undefined; - expect(subDomain).to.be.undefined; - }); - - it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); - expect(cid).to.be.equal('1'); - expect(pid).to.be.equal('2'); - expect(subDomain).to.be.equal('prebid'); - }); - }); - - describe('unique deal id', function () { - before(function () { - $$PREBID_GLOBAL$$.bidderSettings = { - mmplus: { - storageAllowed: true - } - }; - }); - after(function () { - $$PREBID_GLOBAL$$.bidderSettings = {}; - }); - const key = 'myKey'; - let uniqueDealId; - beforeEach(() => { - uniqueDealId = getUniqueDealId(key, 0); - }) - - it('should get current unique deal id', function (done) { - // waiting some time so `now` will become past - setTimeout(() => { - const current = getUniqueDealId(key); - expect(current).to.be.equal(uniqueDealId); - done(); - }, 200); - }); - - it('should get new unique deal id on expiration', function (done) { - setTimeout(() => { - const current = getUniqueDealId(key, 100); - expect(current).to.not.be.equal(uniqueDealId); - done(); - }, 200) - }); - }); - - describe('storage utils', function () { - before(function () { - $$PREBID_GLOBAL$$.bidderSettings = { - mmplus: { - storageAllowed: true - } - }; - }); - after(function () { - $$PREBID_GLOBAL$$.bidderSettings = {}; - }); - it('should get value from storage with create param', function () { - const now = Date.now(); - const clock = useFakeTimers({ - shouldAdvanceTime: true, - now - }); - setStorageItem('myKey', 2020); - const {value, created} = getStorageItem('myKey'); - expect(created).to.be.equal(now); - expect(value).to.be.equal(2020); - expect(typeof value).to.be.equal('number'); - expect(typeof created).to.be.equal('number'); - clock.restore(); - }); - - it('should get external stored value', function () { - const value = 'superman' - window.localStorage.setItem('myExternalKey', value); - const item = getStorageItem('myExternalKey'); - expect(item).to.be.equal(value); - }); - - it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); - expect(event).to.be.equal('send'); - }); - - it('should get original value on parse fail', function () { - const value = 21; - const parsed = tryParseJSON(value); - expect(typeof parsed).to.be.equal('number'); - expect(parsed).to.be.equal(value); - }); - }); -}); diff --git a/test/spec/modules/mobfoxpbBidAdapter_spec.js b/test/spec/modules/mobfoxpbBidAdapter_spec.js index a4e58afbd1b..de289f8a5e5 100644 --- a/test/spec/modules/mobfoxpbBidAdapter_spec.js +++ b/test/spec/modules/mobfoxpbBidAdapter_spec.js @@ -1,148 +1,268 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/mobfoxpbBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/mobfoxpbBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; +import { getUniqueIdentifierStr } from '../../../src/utils.js'; + +const bidder = 'mobfoxpb'; describe('MobfoxHBBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'mobfoxpb', + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + placementId: 'testBanner' + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + placementId: 'testVideo' + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + placementId: 'testNative' + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, mediaTypes: { [BANNER]: { sizes: [[300, 250]] } }, params: { - placementId: 783, - traffic: BANNER + } - }; + } const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, refererInfo: { - referer: 'test.com' + referer: 'https://test.com', + page: 'https://test.com' }, - ortb2: {} + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } + }, + timeout: 500 }; describe('isBidRequestValid', function () { it('Should return true if there are bidId, params and key parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; + expect(spec.isBidRequestValid(bids[0])).to.be.true; }); it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; + expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); }); describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); + it('Creates a ServerRequest object with method, URL and data', function () { expect(serverRequest).to.exist; expect(serverRequest.method).to.exist; expect(serverRequest.url).to.exist; expect(serverRequest.data).to.exist; }); + it('Returns POST method', function () { expect(serverRequest.method).to.equal('POST'); }); + it('Returns valid URL', function () { expect(serverRequest.url).to.equal('https://bes.mobfox.com/pbjs'); }); - it('Returns valid data if array of bids is valid', function () { + + it('Returns general data valid', function () { let data = serverRequest.data; expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data).to.have.all.keys('deviceWidth', + 'deviceHeight', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax' + ); expect(data.deviceWidth).to.be.a('number'); expect(data.deviceHeight).to.be.a('number'); expect(data.language).to.be.a('string'); expect(data.secure).to.be.within(0, 1); expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); - expect(data.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'schain', 'bidfloor'); - expect(placement.placementId).to.equal(783); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - expect(placement.sizes).to.be.an('array'); - expect(placement.bidfloor).to.equal(0); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); }); - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'playerSize', 'wPlayer', 'hPlayer', 'schain', 'bidfloor', - 'minduration', 'maxduration', 'mimes', 'protocols', 'startdelay', 'placement', - 'skip', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } }); - it('Returns valid data for mediatype native', function () { - const native = { - title: { - required: true - }, - body: { - required: true - }, - icon: { - required: true, - size: [64, 64] + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids } - }; + ]; - bid.mediaTypes = {}; - bid.params.traffic = NATIVE; - bid.mediaTypes[NATIVE] = native; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'native', 'schain', 'bidfloor'); - expect(placement.traffic).to.equal(NATIVE); - expect(placement.native).to.equal(native); + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.traffic) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } }); it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.ccpa).to.exist; expect(data.ccpa).to.be.a('string'); expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); }); describe('gpp consent', function () { @@ -152,7 +272,7 @@ describe('MobfoxHBBidAdapter', function () { applicableSections: [8] }; - let serverRequest = spec.buildRequests([bid], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data).to.be.an('object'); expect(data).to.have.property('gpp'); @@ -162,15 +282,18 @@ describe('MobfoxHBBidAdapter', function () { }) it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; bidderRequest.ortb2.regs.gpp = 'abc123'; bidderRequest.ortb2.regs.gpp_sid = [8]; - let serverRequest = spec.buildRequests([bid], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data).to.be.an('object'); expect(data).to.have.property('gpp'); expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; }) }); @@ -188,7 +311,11 @@ describe('MobfoxHBBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', - dealId: '1' + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let bannerResponses = spec.interpretResponse(banner); @@ -196,15 +323,16 @@ describe('MobfoxHBBidAdapter', function () { let dataItem = bannerResponses[0]; expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); + expect(dataItem.currency).to.equal(banner.body[0].currency); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); }); it('Should interpret video response', function () { const video = { @@ -217,7 +345,11 @@ describe('MobfoxHBBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', - dealId: '1' + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let videoResponses = spec.interpretResponse(video); @@ -233,6 +365,7 @@ describe('MobfoxHBBidAdapter', function () { expect(dataItem.creativeId).to.equal('2'); expect(dataItem.netRevenue).to.be.true; expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); }); it('Should interpret native response', function () { const native = { @@ -250,6 +383,10 @@ describe('MobfoxHBBidAdapter', function () { creativeId: '2', netRevenue: true, currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } }] }; let nativeResponses = spec.interpretResponse(native); @@ -269,6 +406,7 @@ describe('MobfoxHBBidAdapter', function () { expect(dataItem.creativeId).to.equal('2'); expect(dataItem.netRevenue).to.be.true; expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); }); it('Should return an empty array if invalid banner response is passed', function () { const invBanner = { diff --git a/test/spec/modules/mobianRtdProvider_spec.js b/test/spec/modules/mobianRtdProvider_spec.js new file mode 100644 index 00000000000..f16cb99dcd9 --- /dev/null +++ b/test/spec/modules/mobianRtdProvider_spec.js @@ -0,0 +1,105 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import { mobianBrandSafetySubmodule, MOBIAN_URL } from 'modules/mobianRtdProvider.js'; +import * as ajax from 'src/ajax.js'; + +describe('Mobian RTD Submodule', function () { + let ajaxStub; + let bidReqConfig; + + beforeEach(function () { + bidReqConfig = { + ortb2Fragments: { + global: { + site: { + ext: {} + } + } + } + }; + }); + + afterEach(function () { + ajaxStub.restore(); + }); + + it('should return no_risk when server responds with garm_no_risk', function () { + ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) { + callbacks.success({ + garm_no_risk: true, + garm_low_risk: false, + garm_medium_risk: false, + garm_high_risk: false + }); + }); + + return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => { + expect(risk).to.have.property('mobianGarmRisk'); + expect(risk['mobianGarmRisk']).to.equal('no_risk'); + expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk); + }); + }); + + it('should return low_risk when server responds with garm_no_risk', function () { + ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) { + callbacks.success({ + garm_no_risk: false, + garm_low_risk: true, + garm_medium_risk: false, + garm_high_risk: false + }); + }); + + return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => { + expect(risk).to.have.property('mobianGarmRisk'); + expect(risk['mobianGarmRisk']).to.equal('low_risk'); + expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk); + }); + }); + + it('should return medium_risk when server responds with garm_medium_risk', function () { + ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) { + callbacks.success({ + garm_no_risk: false, + garm_low_risk: false, + garm_medium_risk: true, + garm_high_risk: false + }); + }); + + return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => { + expect(risk).to.have.property('mobianGarmRisk'); + expect(risk['mobianGarmRisk']).to.equal('medium_risk'); + expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk); + }); + }); + + it('should return high_risk when server responds with garm_high_risk', function () { + ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) { + callbacks.success({ + garm_no_risk: false, + garm_low_risk: false, + garm_medium_risk: false, + garm_high_risk: true + }); + }); + + return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => { + expect(risk).to.have.property('mobianGarmRisk'); + expect(risk['mobianGarmRisk']).to.equal('high_risk'); + expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk); + }); + }); + + it('should return unknown when server response is not of the expected shape', function () { + ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) { + callbacks.success('unexpected output not even of the right type'); + }); + + return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => { + expect(risk).to.have.property('mobianGarmRisk'); + expect(risk['mobianGarmRisk']).to.equal('unknown'); + expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk); + }); + }); +}); diff --git a/test/spec/modules/mytargetBidAdapter_spec.js b/test/spec/modules/mytargetBidAdapter_spec.js deleted file mode 100644 index 8880efd3d7c..00000000000 --- a/test/spec/modules/mytargetBidAdapter_spec.js +++ /dev/null @@ -1,199 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/mytargetBidAdapter'; - -describe('MyTarget Adapter', function() { - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - let validBid = { - bidder: 'mytarget', - params: { - placementId: '1' - } - }; - - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - - it('should return false for when required params are not passed', function () { - let invalidBid = { - bidder: 'mytarget', - params: {} - }; - - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - bidId: 'bid1', - bidder: 'mytarget', - params: { - placementId: '1' - } - }, - { - bidId: 'bid2', - bidder: 'mytarget', - params: { - placementId: '2', - position: 1, - response: 1, - bidfloor: 10000 - } - } - ]; - let bidderRequest = { - refererInfo: { - page: 'https://example.com?param=value' - } - }; - - let bidRequest = spec.buildRequests(bidRequests, bidderRequest); - - it('should build single POST request for multiple bids', function() { - expect(bidRequest.method).to.equal('POST'); - expect(bidRequest.url).to.equal('//ad.mail.ru/hbid_prebid/'); - expect(bidRequest.data).to.be.an('object'); - expect(bidRequest.data.places).to.be.an('array'); - expect(bidRequest.data.places).to.have.lengthOf(2); - }); - - it('should pass bid parameters', function() { - let place1 = bidRequest.data.places[0]; - let place2 = bidRequest.data.places[1]; - - expect(place1.placementId).to.equal('1'); - expect(place2.placementId).to.equal('2'); - expect(place1.id).to.equal('bid1'); - expect(place2.id).to.equal('bid2'); - }); - - it('should pass default position and response type', function() { - let place = bidRequest.data.places[0]; - - expect(place.position).to.equal(0); - expect(place.response).to.equal(0); - }); - - it('should pass provided position and response type', function() { - let place = bidRequest.data.places[1]; - - expect(place.position).to.equal(1); - expect(place.response).to.equal(1); - }); - - it('should not pass default bidfloor', function() { - let place = bidRequest.data.places[0]; - - expect(place.bidfloor).not.to.exist; - }); - - it('should not pass provided bidfloor', function() { - let place = bidRequest.data.places[1]; - - expect(place.bidfloor).to.exist; - expect(place.bidfloor).to.equal(10000); - }); - - it('should pass site parameters', function() { - let site = bidRequest.data.site; - - expect(site).to.be.an('object'); - expect(site.sitename).to.equal('example.com'); - expect(site.page).to.equal('https://example.com?param=value'); - }); - - it('should pass settings', function() { - let settings = bidRequest.data.settings; - - expect(settings).to.be.an('object'); - expect(settings.currency).to.equal('RUB'); - expect(settings.windowSize).to.be.an('object'); - expect(settings.windowSize.width).to.equal(window.screen.width); - expect(settings.windowSize.height).to.equal(window.screen.height); - }); - }); - - describe('interpretResponse', function () { - let serverResponse = { - body: { - 'bidder_status': - [ - { - 'bidder': 'mail.ru', - 'response_time_ms': 100, - 'num_bids': 2 - } - ], - 'bids': - [ - { - 'displayUrl': 'https://ad.mail.ru/hbid_imp/12345', - 'size': - { - 'height': '400', - 'width': '240' - }, - 'id': '1', - 'currency': 'RUB', - 'price': 100, - 'ttl': 360, - 'creativeId': '123456' - }, - { - 'adm': '

Ad

', - 'size': - { - 'height': '250', - 'width': '300' - }, - 'id': '2', - 'price': 200 - } - ] - } - }; - - let bids = spec.interpretResponse(serverResponse); - - it('should return empty array for response with no bids', function() { - let emptyBids = spec.interpretResponse({ body: {} }); - - expect(emptyBids).to.have.lengthOf(0); - }); - - it('should parse all bids from response', function() { - expect(bids).to.have.lengthOf(2); - }); - - it('should parse bid with ad url', function() { - expect(bids[0].requestId).to.equal('1'); - expect(bids[0].cpm).to.equal(100); - expect(bids[0].width).to.equal('240'); - expect(bids[0].height).to.equal('400'); - expect(bids[0].ttl).to.equal(360); - expect(bids[0].currency).to.equal('RUB'); - expect(bids[0]).to.have.property('creativeId'); - expect(bids[0].creativeId).to.equal('123456'); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[0].adUrl).to.equal('https://ad.mail.ru/hbid_imp/12345'); - expect(bids[0]).to.not.have.property('ad'); - }); - - it('should parse bid with ad markup', function() { - expect(bids[1].requestId).to.equal('2'); - expect(bids[1].cpm).to.equal(200); - expect(bids[1].width).to.equal('300'); - expect(bids[1].height).to.equal('250'); - expect(bids[1].ttl).to.equal(180); - expect(bids[1].currency).to.equal('RUB'); - expect(bids[1]).to.have.property('creativeId'); - expect(bids[1].creativeId).not.to.equal('123456'); - expect(bids[1].netRevenue).to.equal(true); - expect(bids[1].ad).to.equal('

Ad

'); - expect(bids[1]).to.not.have.property('adUrl'); - }); - }); -}); diff --git a/test/spec/modules/omsBidAdapter_spec.js b/test/spec/modules/omsBidAdapter_spec.js index 10a9c4c946c..18b878acac3 100644 --- a/test/spec/modules/omsBidAdapter_spec.js +++ b/test/spec/modules/omsBidAdapter_spec.js @@ -107,9 +107,9 @@ describe('omsBidAdapter', function () { }); it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js index 3ceaec13cd5..a6edaaabe79 100644 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ b/test/spec/modules/onetagBidAdapter_spec.js @@ -436,13 +436,15 @@ describe('onetag', function () { 'auctionId': '1d1a030790a475', 'bidderRequestId': '22edbae2733bf6', 'timeout': 3000, - 'fledgeEnabled': true + 'paapi': { + 'enabled': true + } }; let serverRequest = spec.buildRequests([bannerBid], bidderRequest); const payload = JSON.parse(serverRequest.data); expect(payload.fledgeEnabled).to.exist; - expect(payload.fledgeEnabled).to.exist.and.to.equal(bidderRequest.fledgeEnabled); + expect(payload.fledgeEnabled).to.exist.and.to.equal(bidderRequest.paapi.enabled); }); it('Should send FLEDGE eligibility flag when FLEDGE is not enabled', function () { let bidderRequest = { @@ -450,13 +452,15 @@ describe('onetag', function () { 'auctionId': '1d1a030790a475', 'bidderRequestId': '22edbae2733bf6', 'timeout': 3000, - 'fledgeEnabled': false + paapi: { + enabled: false + } }; let serverRequest = spec.buildRequests([bannerBid], bidderRequest); const payload = JSON.parse(serverRequest.data); expect(payload.fledgeEnabled).to.exist; - expect(payload.fledgeEnabled).to.exist.and.to.equal(bidderRequest.fledgeEnabled); + expect(payload.fledgeEnabled).to.exist.and.to.equal(bidderRequest.paapi.enabled); }); it('Should send FLEDGE eligibility flag set to false when fledgeEnabled is not defined', function () { let bidderRequest = { @@ -485,7 +489,7 @@ describe('onetag', function () { expect(fledgeInterpretedResponse.bids).to.satisfy(function (value) { return value === null || Array.isArray(value); }); - expect(fledgeInterpretedResponse.fledgeAuctionConfigs).to.be.an('array').that.is.not.empty; + expect(fledgeInterpretedResponse.paapi).to.be.an('array').that.is.not.empty; for (let i = 0; i < interpretedResponse.length; i++) { let dataItem = interpretedResponse[i]; expect(dataItem).to.include.all.keys('requestId', 'cpm', 'width', 'height', 'ttl', 'creativeId', 'netRevenue', 'currency', 'meta', 'dealId'); diff --git a/test/spec/modules/onomagicBidAdapter_spec.js b/test/spec/modules/onomagicBidAdapter_spec.js index 6ddc0edd477..c636542c9c9 100644 --- a/test/spec/modules/onomagicBidAdapter_spec.js +++ b/test/spec/modules/onomagicBidAdapter_spec.js @@ -92,9 +92,9 @@ describe('onomagicBidAdapter', function() { }); it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/openwebBidAdapter_spec.js b/test/spec/modules/openwebBidAdapter_spec.js index 34f92a76c42..f6f6ad22476 100644 --- a/test/spec/modules/openwebBidAdapter_spec.js +++ b/test/spec/modules/openwebBidAdapter_spec.js @@ -25,7 +25,8 @@ describe('openwebAdapter', function () { 'adUnitCode': 'adunit-code', 'sizes': [['640', '480']], 'params': { - 'org': 'jdye8weeyirk00000001' + 'org': 'jdye8weeyirk00000001', + 'placementId': '123' } }; @@ -33,7 +34,7 @@ describe('openwebAdapter', function () { expect(spec.isBidRequestValid(bid)).to.equal(true); }); - it('should return false when required params are not found', function () { + it('should return false when org param is not found', function () { const newBid = Object.assign({}, bid); delete newBid.params; newBid.params = { @@ -41,6 +42,15 @@ describe('openwebAdapter', function () { }; expect(spec.isBidRequestValid(newBid)).to.equal(false); }); + + it('should return false when placementId param is not found', function () { + const newBid = Object.assign({}, bid); + delete newBid.params; + newBid.params = { + 'placementId': null + }; + expect(spec.isBidRequestValid(newBid)).to.equal(false); + }); }); describe('buildRequests', function () { @@ -50,7 +60,8 @@ describe('openwebAdapter', function () { 'adUnitCode': 'adunit-code', 'sizes': [[640, 480]], 'params': { - 'org': 'jdye8weeyirk00000001' + 'org': 'jdye8weeyirk00000001', + 'placementId': '123' }, 'bidId': '299ffc8cca0b87', 'loop': 1, @@ -103,15 +114,13 @@ describe('openwebAdapter', function () { const bidderRequest = { bidderCode: 'openweb', } - const placementId = '12345678'; const api = [1, 2]; const mimes = ['application/javascript', 'video/mp4', 'video/quicktime']; const protocols = [2, 3, 5, 6]; it('sends the placementId to ENDPOINT via POST', function () { - bidRequests[0].params.placementId = placementId; const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.bids[0].placementId).to.equal(placementId); + expect(request.data.bids[0].placementId).to.equal('123'); }); it('sends the plcmt to ENDPOINT via POST', function () { diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js index 25862eac83f..ad4ee1e74ce 100644 --- a/test/spec/modules/openxBidAdapter_spec.js +++ b/test/spec/modules/openxBidAdapter_spec.js @@ -10,14 +10,15 @@ import 'modules/currency.js'; import 'modules/userId/index.js'; import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/schain.js'; +import 'modules/paapi.js'; + import {deepClone} from 'src/utils.js'; import {version} from 'package.json'; import {syncAddFPDToBidderRequest} from '../../helpers/fpd.js'; import {hook} from '../../../src/hook.js'; - const DEFAULT_SYNC = SYNC_URL + '?ph=' + DEFAULT_PH; const BidRequestBuilder = function BidRequestBuilder(options) { @@ -187,9 +188,9 @@ describe('OpenxRtbAdapter', function () { }); it('should return false when required params are not passed', function () { - let videoBidWithMediaTypes = Object.assign({}, videoBidWithMediaTypes); - videoBidWithMediaTypes.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false); + let invalidVideoBidWithMediaTypes = Object.assign({}, videoBidWithMediaTypes); + invalidVideoBidWithMediaTypes.params = {}; + expect(spec.isBidRequestValid(invalidVideoBidWithMediaTypes)).to.equal(false); }); }); describe('and request config uses both delDomain and platform', () => { @@ -216,9 +217,9 @@ describe('OpenxRtbAdapter', function () { }); it('should return false when required params are not passed', function () { - let videoBidWithMediaTypes = Object.assign({}, videoBidWithDelDomainAndPlatform); - videoBidWithMediaTypes.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false); + let invalidVideoBidWithMediaTypes = Object.assign({}, videoBidWithDelDomainAndPlatform); + invalidVideoBidWithMediaTypes.params = {}; + expect(spec.isBidRequestValid(invalidVideoBidWithMediaTypes)).to.equal(false); }); }); describe('and request config uses mediaType', () => { @@ -241,10 +242,10 @@ describe('OpenxRtbAdapter', function () { }); it('should return false when required params are not passed', function () { - let videoBidWithMediaType = Object.assign({}, videoBidWithMediaType); - delete videoBidWithMediaType.params; - videoBidWithMediaType.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(false); + let invalidVideoBidWithMediaType = Object.assign({}, videoBidWithMediaType); + delete invalidVideoBidWithMediaType.params; + invalidVideoBidWithMediaType.params = {}; + expect(spec.isBidRequestValid(invalidVideoBidWithMediaType)).to.equal(false); }); }); }); @@ -1037,7 +1038,9 @@ describe('OpenxRtbAdapter', function () { it('when FLEDGE is enabled, should send whatever is set in ortb2imp.ext.ae in all bid requests', function () { const request = spec.buildRequests(bidRequestsWithMediaTypes, { ...mockBidderRequest, - fledgeEnabled: true + paapi: { + enabled: true + } }); expect(request[0].data.imp[0].ext.ae).to.equal(2); }); @@ -1503,13 +1506,13 @@ describe('OpenxRtbAdapter', function () { it('should return FLEDGE auction_configs alongside bids', function () { expect(response).to.have.property('bids'); - expect(response).to.have.property('fledgeAuctionConfigs'); - expect(response.fledgeAuctionConfigs.length).to.equal(1); - expect(response.fledgeAuctionConfigs[0].bidId).to.equal('test-bid-id'); + expect(response).to.have.property('paapi'); + expect(response.paapi.length).to.equal(1); + expect(response.paapi[0].bidId).to.equal('test-bid-id'); }); it('should inject ortb2Imp in auctionSignals', function () { - const auctionConfig = response.fledgeAuctionConfigs[0].config; + const auctionConfig = response.paapi[0].config; expect(auctionConfig).to.deep.include({ auctionSignals: { ortb2Imp: { diff --git a/test/spec/modules/optableBidAdapter_spec.js b/test/spec/modules/optableBidAdapter_spec.js index d7f2230328e..ef04474c270 100644 --- a/test/spec/modules/optableBidAdapter_spec.js +++ b/test/spec/modules/optableBidAdapter_spec.js @@ -78,10 +78,10 @@ describe('optableBidAdapter', function() { } }; - it('maps fledgeAuctionConfigs from ext.optable.fledge.auctionconfigs', function() { + it('maps paapi from ext.optable.fledge.auctionconfigs', function() { const request = spec.buildRequests([validBid], bidderRequest); const result = spec.interpretResponse(response, request); - expect(result.fledgeAuctionConfigs).to.deep.equal([ + expect(result.paapi).to.deep.equal([ { bidId: 'bid123', config: { seller: 'https://ads.optable.co' } } ]); }); diff --git a/test/spec/modules/orakiBidAdapter_spec.js b/test/spec/modules/orakiBidAdapter_spec.js new file mode 100644 index 00000000000..47a7bf8779d --- /dev/null +++ b/test/spec/modules/orakiBidAdapter_spec.js @@ -0,0 +1,510 @@ +import { expect } from 'chai'; +import { spec } from '../../../modules/orakiBidAdapter'; +import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes'; +import { getUniqueIdentifierStr } from '../../../src/utils'; + +const bidder = 'oraki'; + +describe('OrakiBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + placementId: 'testBanner', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + placementId: 'testVideo', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + placementId: 'testNative' + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + + } + } + + const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, + refererInfo: { + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK', + } + }, + timeout: 500 + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and key parameters present', function () { + expect(spec.isBidRequestValid(bids[0])).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests(bids, bidderRequest); + + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + + it('Returns general data valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys( + 'deviceWidth', + 'deviceHeight', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax' + ); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); + }); + + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns data with gdprConsent and without uspConsent', function () { + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data.gdpr).to.exist; + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); + expect(data.ccpa).to.not.exist; + delete bidderRequest.gdprConsent; + }); + + it('Returns data with uspConsent and without gdprConsent', function () { + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data.ccpa).to.exist; + expect(data.ccpa).to.be.a('string'); + expect(data.ccpa).to.equal(bidderRequest.uspConsent); + expect(data.gdpr).to.not.exist; + }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) + }); + + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + let bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + let dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal(banner.body[0].currency); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + let videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + let dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + let nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + let dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + let serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + + describe('getUserSyncs', function() { + it('Should return array of objects with proper sync config , include GDPR', function() { + const syncData = spec.getUserSyncs({}, {}, { + consentString: 'ALL', + gdprApplies: true, + }, {}); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://sync.oraki.io/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') + }); + it('Should return array of objects with proper sync config , include CCPA', function() { + const syncData = spec.getUserSyncs({}, {}, {}, { + consentString: '1---' + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://sync.oraki.io/image?pbjs=1&ccpa_consent=1---&coppa=0') + }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://sync.oraki.io/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0') + }); + }); +}); diff --git a/test/spec/modules/outbrainBidAdapter_spec.js b/test/spec/modules/outbrainBidAdapter_spec.js index 9825eb3ee79..5e9d76b59b9 100644 --- a/test/spec/modules/outbrainBidAdapter_spec.js +++ b/test/spec/modules/outbrainBidAdapter_spec.js @@ -65,6 +65,23 @@ describe('Outbrain Adapter', function () { } } + const ortb2WithDeviceData = { + ortb2: { + device: { + w: 980, + h: 1720, + dnt: 0, + ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/125.0.6422.80 Mobile/15E148 Safari/604.1', + language: 'en', + devicetype: 1, + make: 'Apple', + model: 'iPhone 12 Pro Max', + os: 'iOS', + osv: '17.4' + } + } + }; + describe('isBidRequestValid', function () { before(() => { config.setConfig({ @@ -390,7 +407,8 @@ describe('Outbrain Adapter', function () { minduration: 3, maxduration: 10, startdelay: 2, - placement: 4, + placement: 5, + plcmt: 4, linearity: 1 } } @@ -620,6 +638,19 @@ describe('Outbrain Adapter', function () { const resData = JSON.parse(res.data) expect(resData.imp[0].native.request).to.equal(JSON.stringify(expectedNativeAssets)); }); + + it('should pass ortb2 device data', function () { + const bidRequest = { + ...commonBidRequest, + ...nativeBidRequestParams, + }; + + const res = spec.buildRequests( + [bidRequest], + {...commonBidderRequest, ...ortb2WithDeviceData}, + ); + expect(JSON.parse(res.data).device).to.deep.equal(ortb2WithDeviceData.ortb2.device); + }); }) describe('interpretResponse', function () { diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js index 73df2fba8fd..b48943da266 100644 --- a/test/spec/modules/ozoneBidAdapter_spec.js +++ b/test/spec/modules/ozoneBidAdapter_spec.js @@ -4,6 +4,7 @@ import { config } from 'src/config.js'; import {Renderer} from '../../../src/Renderer.js'; import {getGranularityKeyName, getGranularityObject} from '../../../modules/ozoneBidAdapter.js'; import * as utils from '../../../src/utils.js'; +import {deepSetValue} from '../../../src/utils.js'; const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction'; const BIDDER_CODE = 'ozone'; var validBidRequests = [ @@ -401,6 +402,66 @@ var validBidderRequest = { start: 1536838908987, timeout: 3000 }; +var validBidderRequestWithCookieDeprecation = { + auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', + auctionStart: 1536838908986, + bidderCode: 'ozone', + bidderRequestId: '1c1586b27a1b5c8', + bids: [{ + adUnitCode: 'div-gpt-ad-1460505748561-0', + auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', + bidId: '2899ec066a91ff8', + bidRequestsCount: 1, + bidder: 'ozone', + bidderRequestId: '1c1586b27a1b5c8', + crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, + params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] }, + sizes: [[300, 250], [300, 600]], + transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' + }], + doneCbCallCount: 1, + start: 1536838908987, + timeout: 3000, + ortb2: { + 'device': { + 'w': 1617, + 'h': 317, + 'dnt': 0, + 'ua': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', + 'language': 'en', + 'sua': { + 'source': 1, + 'platform': { + 'brand': 'macOS' + }, + 'browsers': [ + { + 'brand': 'Google Chrome', + 'version': [ + '125' + ] + }, + { + 'brand': 'Chromium', + 'version': [ + '125' + ] + }, + { + 'brand': 'Not.A/Brand', + 'version': [ + '24' + ] + } + ], + 'mobile': 0 + }, + 'ext': { + 'cdep': 'fake_control_2' + } + } + } +}; var bidderRequestWithFullGdpr = { auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', auctionStart: 1536838908986, @@ -1814,7 +1875,7 @@ describe('ozone Adapter', function () { }); it('should add gdpr consent information to the request when ozone is true', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: true, @@ -1832,7 +1893,7 @@ describe('ozone Adapter', function () { }); it('should add gdpr consent information to the request when vendorData is missing vendorConsents (Mirror)', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: true, @@ -1848,7 +1909,7 @@ describe('ozone Adapter', function () { }); it('should set regs.ext.gdpr flag to 0 when gdprApplies is false', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: false, @@ -1863,9 +1924,24 @@ describe('ozone Adapter', function () { const payload = JSON.parse(request.data); expect(payload.regs.ext.gdpr).to.equal(0); }); + it('should set gpp and gpp_sid when available', function() { + let gppString = 'gppConsentString'; + let gppSections = [7, 8, 9]; + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); + bidderRequest.ortb2 = {regs: {gpp: gppString, gpp_sid: gppSections}}; + const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.regs.gpp).to.equal(gppString); + expect(payload.regs.gpp_sid).to.have.same.members(gppSections); + }); + it('should not set gpp and gpp_sid keys when not available', function() { + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); + const payload = JSON.parse(request.data); + expect(payload).to.not.contain.keys(['gpp', 'gpp_sid', 'ext', 'regs']); + }); it('should not have imp[N].ext.ozone.userId', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: false, @@ -1876,7 +1952,7 @@ describe('ozone Adapter', function () { purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true} } }; - let bidRequests = validBidRequests; + let bidRequests = JSON.parse(JSON.stringify(validBidRequests)); bidRequests[0]['userId'] = { 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, @@ -1891,23 +1967,12 @@ describe('ozone Adapter', function () { const payload = JSON.parse(request.data); let firstBid = payload.imp[0].ext.ozone; expect(firstBid).to.not.have.property('userId'); - delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests }); it('should pick up the value of pubcid when built using the pubCommonId module (not userId)', function () { let bidRequests = validBidRequests; - bidRequests[0]['userId'] = { - 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, - 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, - 'idl_env': '3333', - 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue', - 'tdid': '6666', - 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'} - }; - bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids']; const request = spec.buildRequests(bidRequests, validBidderRequest); const payload = JSON.parse(request.data); expect(payload.ext.ozone.pubcid).to.equal(bidRequests[0]['crumbs']['pubcid']); - delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests }); it('should add a user.ext.eids object to contain user ID data in the new location (Nov 2019) Updated Aug 2020', function() { const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest); @@ -2056,7 +2121,7 @@ describe('ozone Adapter', function () { const data = JSON.parse(request.data); expect(data.imp[0].ext.gpid).to.equal('/22037345/projectozone'); }); - it('should batch into 10s if config is set', function () { + it('should batch into 10s if config is set to true', function () { config.setConfig({ozone: {'batchRequests': true}}); var specMock = utils.deepClone(spec); let arrReq = []; @@ -2069,7 +2134,20 @@ describe('ozone Adapter', function () { expect(request.length).to.equal(3); config.resetConfig(); }); - it('should not batch into 10s if config is set to false and singleRequest is true', function () { + it('should batch into 7 if config is set to 7', function () { + config.setConfig({ozone: {'batchRequests': 7}}); + var specMock = utils.deepClone(spec); + let arrReq = []; + for (let i = 0; i < 25; i++) { + let b = validBidRequests[0]; + b.adUnitCode += i; + arrReq.push(b); + } + const request = specMock.buildRequests(arrReq, validBidderRequest); + expect(request.length).to.equal(4); + config.resetConfig(); + }); + it('should not batch if config is set to false and singleRequest is true', function () { config.setConfig({ozone: {'batchRequests': false, 'singleRequest': true}}); var specMock = utils.deepClone(spec); let arrReq = []; @@ -2082,6 +2160,57 @@ describe('ozone Adapter', function () { expect(request.method).to.equal('POST'); config.resetConfig(); }); + it('should not batch if config is set to invalid value -10 and singleRequest is true', function () { + config.setConfig({ozone: {'batchRequests': -10, 'singleRequest': true}}); + var specMock = utils.deepClone(spec); + let arrReq = []; + for (let i = 0; i < 15; i++) { + let b = validBidRequests[0]; + b.adUnitCode += i; + arrReq.push(b); + } + const request = specMock.buildRequests(arrReq, validBidderRequest); + expect(request.method).to.equal('POST'); + config.resetConfig(); + }); + it('should use GET values for batchRequests if found', function() { + var specMock = utils.deepClone(spec); + specMock.getGetParametersAsObject = function() { + return {'batchRequests': '5'}; + }; + let arrReq = []; + for (let i = 0; i < 25; i++) { + let b = validBidRequests[0]; + b.adUnitCode += i; + arrReq.push(b); + } + let request = specMock.buildRequests(arrReq, validBidderRequest); + expect(request.length).to.equal(5); // 5 x 5 = 25 + specMock = utils.deepClone(spec); + specMock.getGetParametersAsObject = function() { + return {'batchRequests': '10'}; // the built in function will return '10' (string) + }; + request = specMock.buildRequests(arrReq, validBidderRequest); + expect(request.length).to.equal(3); // 10, 10, 5 + specMock = utils.deepClone(spec); + specMock.getGetParametersAsObject = function() { + return {'batchRequests': true}; + }; + request = specMock.buildRequests(arrReq, validBidderRequest); + expect(request.method).to.equal('POST'); // no batching - GET param must be numeric + specMock = utils.deepClone(spec); + specMock.getGetParametersAsObject = function() { + return {'batchRequests': 'true'}; + }; + request = specMock.buildRequests(arrReq, validBidderRequest); + expect(request.method).to.equal('POST'); // no batching - GET param must be numeric + specMock = utils.deepClone(spec); + specMock.getGetParametersAsObject = function() { + return {'batchRequests': -5}; + }; + request = specMock.buildRequests(arrReq, validBidderRequest); + expect(request.method).to.equal('POST'); // no batching + }); it('should use GET values auction=dev & cookiesync=dev if set', function() { var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { @@ -2295,6 +2424,27 @@ describe('ozone Adapter', function () { expect(data.source.ext).to.haveOwnProperty('schain'); expect(data.source.ext.schain).to.deep.equal(schainConfigObject); // .deep.equal() : Target object deeply (but not strictly) equals `{a: 1}` }); + it('should find ortb2 cookieDeprecation values', function () { + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequestWithCookieDeprecation)); + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.ext.ozone.cookieDeprecationLabel).to.equal('fake_control_2'); + }); + it('should set ortb2 cookieDeprecation to "none" if there is none', function () { + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.ext.ozone.cookieDeprecationLabel).to.equal('none'); + }); + it('should handle fledge requests', function () { + let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); + let bidRequests = JSON.parse(JSON.stringify(validBidRequests)); + deepSetValue(bidRequests[0], 'ortb2Imp.ext.ae', 1); + bidderRequest.fledgeEnabled = true; + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.imp[0].ext.ae).to.equal(1); + }); }); describe('interpretResponse', function () { beforeEach(function () { @@ -2509,6 +2659,20 @@ describe('ozone Adapter', function () { const bid = result[0]; expect(bid.mediaType).to.equal('video'); }); + it('should handle fledge response', function () { + const req = spec.buildRequests(validBidRequests, validBidderRequest); + let objResp = JSON.parse(JSON.stringify(validResponse)); + objResp.body.ext = {igi: [{ + 'impid': '1', + 'igb': [{ + 'origin': 'https://paapi.dsp.com', + 'pbs': '{"key": "value"}' + }] + }]}; + const result = spec.interpretResponse(objResp, req); + expect(result).to.be.an('object'); + expect(result.fledgeAuctionConfigs[0]['impid']).to.equal('1'); + }); }); describe('userSyncs', function () { it('should fail gracefully if no server response', function () { @@ -2540,6 +2704,10 @@ describe('ozone Adapter', function () { expect(result).to.be.an('array'); expect(result[0].url).to.include('usp_consent=&'); }); + it('should add gpp if its present', function () { + const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1, '1---', { gppString: 'gppStringHere', applicableSections: [7, 8, 9] }); + expect(result[0].url).to.include('gpp=gppStringHere&gpp_sid=7,8,9'); + }); }); describe('video object utils', function () { it('should find width & height from video object', function () { @@ -2698,7 +2866,7 @@ describe('ozone Adapter', function () { }); }); describe('addVideoDefaults', function() { - it('should correctly add video defaults', function () { + it('should not add video defaults if there is no videoParams config', function () { let mediaTypes = { playerSize: [640, 480], mimes: ['video/mp4'], @@ -2715,12 +2883,14 @@ describe('ozone Adapter', function () { testKey: 'child value' }; let result = spec.addVideoDefaults({}, mediaTypes, mediaTypes); - expect(result.placement).to.equal(3); + expect(result.placement).to.be.undefined; expect(result.skip).to.equal(0); result = spec.addVideoDefaults({}, mediaTypes, bid_params_video); expect(result.skip).to.equal(1); }); - it('should correctly add video defaults including skippable in parent', function () { + it('should correctly add video defaults if page config videoParams is defined, also check skip in the parent', function () { + var specMock = utils.deepClone(spec); + specMock.propertyBag.whitelabel.videoParams = {outstream: 3, instream: 1}; let mediaTypes = { playerSize: [640, 480], mimes: ['video/mp4'], @@ -2736,7 +2906,7 @@ describe('ozone Adapter', function () { skipafter: 5, testKey: 'child value' }; - let result = spec.addVideoDefaults({}, mediaTypes, bid_params_video); + let result = specMock.addVideoDefaults({}, mediaTypes, bid_params_video); expect(result.placement).to.equal(3); expect(result.skip).to.equal(1); }); diff --git a/test/spec/modules/paapiForGpt_spec.js b/test/spec/modules/paapiForGpt_spec.js new file mode 100644 index 00000000000..9a6637f82aa --- /dev/null +++ b/test/spec/modules/paapiForGpt_spec.js @@ -0,0 +1,216 @@ +import { + getPAAPISizeHook, + onAuctionConfigFactory, + setPAAPIConfigFactory, setTargetingHookFactory, + slotConfigurator +} from 'modules/paapiForGpt.js'; +import * as gptUtils from '../../../libraries/gptUtils/gptUtils.js'; +import 'modules/appnexusBidAdapter.js'; +import 'modules/rubiconBidAdapter.js'; +import {deepSetValue} from '../../../src/utils.js'; +import {config} from 'src/config.js'; + +describe('paapiForGpt module', () => { + let sandbox, fledgeAuctionConfig; + + beforeEach(() => { + sandbox = sinon.sandbox.create(); + fledgeAuctionConfig = { + seller: 'bidder', + mock: 'config' + }; + }); + afterEach(() => { + sandbox.restore(); + }); + + describe('slotConfigurator', () => { + let setGptConfig; + function mockGptSlot(auPath) { + return { + setConfig: sinon.stub(), + getAdUnitPath: () => auPath + } + } + beforeEach(() => { + setGptConfig = slotConfigurator(); + }); + + Object.entries({ + 'single slot': [mockGptSlot('mock/gpt/au')], + 'multiple slots': [mockGptSlot('mock/gpt/au'), mockGptSlot('mock/gpt/au2')] + }).forEach(([t, gptSlots]) => { + describe(`when ad unit code matches ${t}`, () => { + it('should set GPT slot config', () => { + setGptConfig('au', gptSlots, [fledgeAuctionConfig]); + gptSlots.forEach(slot => { + sinon.assert.calledWith(slot.setConfig, { + componentAuction: [{ + configKey: 'bidder', + auctionConfig: fledgeAuctionConfig, + }] + }); + }) + }); + describe('when reset = true', () => { + it('should reset GPT slot config', () => { + setGptConfig('au', gptSlots, [fledgeAuctionConfig]); + gptSlots.forEach(slot => slot.setConfig.resetHistory()); + setGptConfig('au', gptSlots, [], true); + gptSlots.forEach(slot => { + sinon.assert.calledWith(slot.setConfig, { + componentAuction: [{ + configKey: 'bidder', + auctionConfig: null + }] + }); + }) + }); + + it('should reset only sellers with no fresh config', () => { + setGptConfig('au', gptSlots, [{seller: 's1'}, {seller: 's2'}]); + gptSlots.forEach(slot => slot.setConfig.resetHistory()); + setGptConfig('au', gptSlots, [{seller: 's1'}], true); + gptSlots.forEach(slot => { + sinon.assert.calledWith(slot.setConfig, { + componentAuction: [{ + configKey: 's1', + auctionConfig: {seller: 's1'} + }, { + configKey: 's2', + auctionConfig: null + }] + }) + }) + }); + + it('should not reset sellers that were already reset', () => { + setGptConfig('au', gptSlots, [{seller: 's1'}]); + setGptConfig('au', gptSlots, [], true); + gptSlots.forEach(slot => slot.setConfig.resetHistory()); + setGptConfig('au', gptSlots, [], true); + gptSlots.forEach(slot => sinon.assert.notCalled(slot.setConfig)); + }) + + it('should keep track of configuration history by ad unit', () => { + setGptConfig('au1', gptSlots, [{seller: 's1'}]); + setGptConfig('au1', gptSlots, [{seller: 's2'}], false); + setGptConfig('au2', gptSlots, [{seller: 's3'}]); + gptSlots.forEach(slot => slot.setConfig.resetHistory()); + setGptConfig('au1', gptSlots, [], true); + gptSlots.forEach(slot => { + sinon.assert.calledWith(slot.setConfig, { + componentAuction: [{ + configKey: 's1', + auctionConfig: null + }, { + configKey: 's2', + auctionConfig: null + }] + }); + }) + }) + }); + }) + }) + }); + describe('setTargeting hook', () => { + let setPaapiConfig, setTargetingHook, next; + beforeEach(() => { + setPaapiConfig = sinon.stub() + setTargetingHook = setTargetingHookFactory(setPaapiConfig); + next = sinon.stub(); + }); + function expectFilters(...filters) { + expect(setPaapiConfig.args.length).to.eql(filters.length) + filters.forEach(filter => { + sinon.assert.calledWith(setPaapiConfig, filter, 'mock-matcher') + }) + } + function runHook(adUnit) { + setTargetingHook(next, adUnit, 'mock-matcher'); + sinon.assert.calledWith(next, adUnit, 'mock-matcher'); + } + it('should invoke with no filters when adUnit is undef', () => { + runHook(); + expectFilters(undefined); + }); + it('should invoke once when adUnit is a string', () => { + runHook('mock-au'); + expectFilters({adUnitCode: 'mock-au'}) + }); + it('should invoke once per ad unit when an array', () => { + runHook(['au1', 'au2']); + expectFilters({adUnitCode: 'au1'}, {adUnitCode: 'au2'}); + }) + }) + describe('setPAAPIConfigForGpt', () => { + let getPAAPIConfig, setGptConfig, getSlots, setPAAPIConfigForGPT; + beforeEach(() => { + getPAAPIConfig = sinon.stub(); + setGptConfig = sinon.stub(); + getSlots = sinon.stub().callsFake((codes) => Object.fromEntries(codes.map(code => [code, ['mock-slot']]))) + setPAAPIConfigForGPT = setPAAPIConfigFactory(getPAAPIConfig, setGptConfig, getSlots); + }); + + Object.entries({ + missing: null, + empty: {} + }).forEach(([t, configs]) => { + it(`does not set GPT slot config when config is ${t}`, () => { + getPAAPIConfig.returns(configs); + setPAAPIConfigForGPT('mock-filters'); + sinon.assert.calledWith(getPAAPIConfig, 'mock-filters'); + sinon.assert.notCalled(setGptConfig); + }) + }); + + it('passes customSlotMatching to getSlots', () => { + getPAAPIConfig.returns({au1: {}}); + setPAAPIConfigForGPT('mock-filters', 'mock-custom-matching'); + sinon.assert.calledWith(getSlots, ['au1'], 'mock-custom-matching'); + }) + + it('sets GPT slot config for each ad unit that has PAAPI config, and resets the rest', () => { + const cfg = { + au1: { + componentAuctions: [{seller: 's1'}, {seller: 's2'}] + }, + au2: { + componentAuctions: [{seller: 's3'}] + }, + au3: null + } + getPAAPIConfig.returns(cfg); + setPAAPIConfigForGPT('mock-filters'); + sinon.assert.calledWith(getPAAPIConfig, 'mock-filters'); + Object.entries(cfg).forEach(([au, config]) => { + sinon.assert.calledWith(setGptConfig, au, ['mock-slot'], config?.componentAuctions ?? [], true); + }) + }); + }); + + describe('getPAAPISizeHook', () => { + let next; + beforeEach(() => { + next = sinon.stub(); + next.bail = sinon.stub(); + }); + + it('should pick largest supported size over larger unsupported size', () => { + getPAAPISizeHook(next, [[999, 999], [300, 250], [300, 600], [1234, 4321]]); + sinon.assert.calledWith(next.bail, [300, 600]); + }); + + Object.entries({ + 'present': [], + 'supported': [[123, 4], [321, 5]], + 'defined': undefined, + }).forEach(([t, sizes]) => { + it(`should defer to next when no size is ${t}`, () => { + getPAAPISizeHook(next, sizes); + sinon.assert.calledWith(next, sizes); + }) + }) + }) +}); diff --git a/test/spec/modules/paapi_spec.js b/test/spec/modules/paapi_spec.js index 768e2ba8853..cc839307c8e 100644 --- a/test/spec/modules/paapi_spec.js +++ b/test/spec/modules/paapi_spec.js @@ -7,7 +7,7 @@ import {hook} from '../../../src/hook.js'; import 'modules/appnexusBidAdapter.js'; import 'modules/rubiconBidAdapter.js'; import { - addPaapiConfigHook, + addPaapiConfigHook, addPaapiData, buyersToAuctionConfigs, getPAAPIConfig, getPAAPISize, @@ -40,622 +40,619 @@ describe('paapi module', () => { reset(); }); - [ - 'fledgeForGpt', - 'paapi' - ].forEach(configNS => { - describe(`using ${configNS} for configuration`, () => { - let getPAAPISizeStub; + describe(`using paapi configuration`, () => { + let getPAAPISizeStub; - function getPAAPISizeHook(next, sizes) { - next.bail(getPAAPISizeStub(sizes)); - } + function getPAAPISizeHook(next, sizes) { + next.bail(getPAAPISizeStub(sizes)); + } - before(() => { - getPAAPISize.before(getPAAPISizeHook, 100); - }); + before(() => { + getPAAPISize.before(getPAAPISizeHook, 100); + }); - after(() => { - getPAAPISize.getHooks({hook: getPAAPISizeHook}).remove(); - }); + after(() => { + getPAAPISize.getHooks({hook: getPAAPISizeHook}).remove(); + }); + beforeEach(() => { + getPAAPISizeStub = sinon.stub(); + }); + + describe('getPAAPIConfig', function () { + let nextFnSpy, auctionConfig, paapiConfig; + before(() => { + config.setConfig({paapi: {enabled: true}}); + }); beforeEach(() => { - getPAAPISizeStub = sinon.stub(); + auctionConfig = { + seller: 'bidder', + mock: 'config' + }; + paapiConfig = { + config: auctionConfig + }; + nextFnSpy = sinon.spy(); }); - describe('getPAAPIConfig', function () { - let nextFnSpy, auctionConfig, paapiConfig; - before(() => { - config.setConfig({[configNS]: {enabled: true}}); + describe('on a single auction', function () { + const auctionId = 'aid'; + beforeEach(function () { + sandbox.stub(auctionManager, 'index').value(stubAuctionIndex({auctionId})); }); - beforeEach(() => { - auctionConfig = { - seller: 'bidder', - mock: 'config' - }; - paapiConfig = { - config: auctionConfig - }; - nextFnSpy = sinon.spy(); + + it('should call next()', function () { + const request = {auctionId, adUnitCode: 'auc'}; + addPaapiConfigHook(nextFnSpy, request, paapiConfig); + sinon.assert.calledWith(nextFnSpy, request, paapiConfig); }); - describe('on a single auction', function () { - const auctionId = 'aid'; - beforeEach(function () { - sandbox.stub(auctionManager, 'index').value(stubAuctionIndex({auctionId})); + describe('igb', () => { + let igb1, igb2, buyerAuctionConfig; + beforeEach(() => { + igb1 = { + origin: 'buyer.1' + }; + igb2 = { + origin: 'buyer.2' + }; + buyerAuctionConfig = { + seller: 'seller', + decisionLogicURL: 'seller-decision-logic' + }; + config.mergeConfig({ + paapi: { + componentSeller: { + auctionConfig: buyerAuctionConfig + } + } + }); }); - it('should call next()', function () { - const request = {auctionId, adUnitCode: 'auc'}; - addPaapiConfigHook(nextFnSpy, request, paapiConfig); - sinon.assert.calledWith(nextFnSpy, request, paapiConfig); + function addIgb(request, igb) { + addPaapiConfigHook(nextFnSpy, Object.assign({auctionId}, request), {igb}); + } + + it('should be collected into an auction config', () => { + addIgb({adUnitCode: 'au1'}, igb1); + addIgb({adUnitCode: 'au1'}, igb2); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); + const buyerConfig = getPAAPIConfig({auctionId}).au1.componentAuctions[0]; + sinon.assert.match(buyerConfig, { + interestGroupBuyers: [igb1.origin, igb2.origin], + ...buyerAuctionConfig + }); }); - describe('igb', () => { - let igb1, igb2, buyerAuctionConfig; + describe('FPD', () => { + let ortb2, ortb2Imp; beforeEach(() => { - igb1 = { - origin: 'buyer1' - }; - igb2 = { - origin: 'buyer2' - }; - buyerAuctionConfig = { - seller: 'seller', - decisionLogicURL: 'seller-decision-logic' - }; - config.mergeConfig({ - [configNS]: { - componentSeller: { - auctionConfig: buyerAuctionConfig - } - } - }); + ortb2 = {'fpd': 1}; + ortb2Imp = {'fpd': 2}; }); - function addIgb(request, igb) { - addPaapiConfigHook(nextFnSpy, Object.assign({auctionId}, request), {igb}); + function getBuyerAuctionConfig() { + addIgb({adUnitCode: 'au1', ortb2, ortb2Imp}, igb1); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); + return getPAAPIConfig({auctionId}).au1.componentAuctions[0]; } - it('should be collected into an auction config', () => { - addIgb({adUnitCode: 'au1'}, igb1); - addIgb({adUnitCode: 'au1'}, igb2); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); - const buyerConfig = getPAAPIConfig({auctionId}).au1.componentAuctions[0]; - sinon.assert.match(buyerConfig, { - interestGroupBuyers: [igb1.origin, igb2.origin], - ...buyerAuctionConfig + it('should be added to auction config', () => { + sinon.assert.match(getBuyerAuctionConfig().perBuyerSignals[igb1.origin], { + prebid: { + ortb2, + ortb2Imp + } }); }); - describe('FPD', () => { - let ortb2, ortb2Imp; - beforeEach(() => { - ortb2 = {'fpd': 1}; - ortb2Imp = {'fpd': 2}; + it('should not override existing perBuyerSignals', () => { + const original = { + ortb2: { + fpd: 'original' + } + }; + igb1.pbs = { + prebid: deepClone(original) + }; + sinon.assert.match(getBuyerAuctionConfig().perBuyerSignals[igb1.origin], { + prebid: original }); + }); + }); + }); - function getBuyerAuctionConfig() { - addIgb({adUnitCode: 'au1', ortb2, ortb2Imp}, igb1); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); - return getPAAPIConfig({auctionId}).au1.componentAuctions[0]; - } - - it('should be added to auction config', () => { - sinon.assert.match(getBuyerAuctionConfig().perBuyerSignals[igb1.origin], { - prebid: { - ortb2, - ortb2Imp - } - }); - }); + describe('should collect auction configs', () => { + let cf1, cf2; + beforeEach(() => { + cf1 = {...auctionConfig, id: 1, seller: 'b1'}; + cf2 = {...auctionConfig, id: 2, seller: 'b2'}; + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, {config: cf1}); + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au2'}, {config: cf2}); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1', 'au2', 'au3']}); + }); - it('should not override existing perBuyerSignals', () => { - const original = { - ortb2: { - fpd: 'original' - } - }; - igb1.pbs = { - prebid: deepClone(original) - }; - sinon.assert.match(getBuyerAuctionConfig().perBuyerSignals[igb1.origin], { - prebid: original - }); - }); + it('and make them available at end of auction', () => { + sinon.assert.match(getPAAPIConfig({auctionId}), { + au1: { + componentAuctions: [cf1] + }, + au2: { + componentAuctions: [cf2] + } }); }); - describe('should collect auction configs', () => { - let cf1, cf2; - beforeEach(() => { - cf1 = {...auctionConfig, id: 1, seller: 'b1'}; - cf2 = {...auctionConfig, id: 2, seller: 'b2'}; - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, {config: cf1}); - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au2'}, {config: cf2}); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1', 'au2', 'au3']}); + it('and filter them by ad unit', () => { + const cfg = getPAAPIConfig({auctionId, adUnitCode: 'au1'}); + expect(Object.keys(cfg)).to.have.members(['au1']); + sinon.assert.match(cfg.au1, { + componentAuctions: [cf1] }); + }); - it('and make them available at end of auction', () => { - sinon.assert.match(getPAAPIConfig({auctionId}), { - au1: { - componentAuctions: [cf1] - }, - au2: { - componentAuctions: [cf2] - } - }); - }); + it('and not return them again', () => { + getPAAPIConfig(); + const cfg = getPAAPIConfig(); + expect(cfg).to.eql({}); + }); - it('and filter them by ad unit', () => { - const cfg = getPAAPIConfig({auctionId, adUnitCode: 'au1'}); - expect(Object.keys(cfg)).to.have.members(['au1']); - sinon.assert.match(cfg.au1, { - componentAuctions: [cf1] + describe('includeBlanks = true', () => { + it('includes all ad units', () => { + const cfg = getPAAPIConfig({}, true); + expect(Object.keys(cfg)).to.have.members(['au1', 'au2', 'au3']); + expect(cfg.au3).to.eql(null); + }); + it('includes the targeted adUnit', () => { + expect(getPAAPIConfig({adUnitCode: 'au3'}, true)).to.eql({ + au3: null }); }); - - it('and not return them again', () => { - getPAAPIConfig(); - const cfg = getPAAPIConfig(); - expect(cfg).to.eql({}); + it('includes the targeted auction', () => { + const cfg = getPAAPIConfig({auctionId}, true); + expect(Object.keys(cfg)).to.have.members(['au1', 'au2', 'au3']); + expect(cfg.au3).to.eql(null); }); - - describe('includeBlanks = true', () => { - it('includes all ad units', () => { - const cfg = getPAAPIConfig({}, true); - expect(Object.keys(cfg)).to.have.members(['au1', 'au2', 'au3']); - expect(cfg.au3).to.eql(null); - }); - it('includes the targeted adUnit', () => { - expect(getPAAPIConfig({adUnitCode: 'au3'}, true)).to.eql({ - au3: null - }); - }); - it('includes the targeted auction', () => { - const cfg = getPAAPIConfig({auctionId}, true); - expect(Object.keys(cfg)).to.have.members(['au1', 'au2', 'au3']); - expect(cfg.au3).to.eql(null); - }); - it('does not include non-existing ad units', () => { - expect(getPAAPIConfig({adUnitCode: 'other'})).to.eql({}); - }); - it('does not include non-existing auctions', () => { - expect(getPAAPIConfig({auctionId: 'other'})).to.eql({}); - }); + it('does not include non-existing ad units', () => { + expect(getPAAPIConfig({adUnitCode: 'other'})).to.eql({}); + }); + it('does not include non-existing auctions', () => { + expect(getPAAPIConfig({auctionId: 'other'})).to.eql({}); }); }); + }); - it('should drop auction configs after end of auction', () => { - events.emit(EVENTS.AUCTION_END, {auctionId}); - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au'}, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId}); - expect(getPAAPIConfig({auctionId})).to.eql({}); - }); + it('should drop auction configs after end of auction', () => { + events.emit(EVENTS.AUCTION_END, {auctionId}); + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au'}, paapiConfig); + events.emit(EVENTS.AUCTION_END, {auctionId}); + expect(getPAAPIConfig({auctionId})).to.eql({}); + }); - describe('FPD', () => { - let ortb2, ortb2Imp; - beforeEach(() => { - ortb2 = {fpd: 1}; - ortb2Imp = {fpd: 2}; - }); + describe('FPD', () => { + let ortb2, ortb2Imp; + beforeEach(() => { + ortb2 = {fpd: 1}; + ortb2Imp = {fpd: 2}; + }); - function getComponentAuctionConfig() { - addPaapiConfigHook(nextFnSpy, { - auctionId, - adUnitCode: 'au1', - ortb2: {fpd: 1}, - ortb2Imp: {fpd: 2} - }, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId}); - return getPAAPIConfig({auctionId}).au1.componentAuctions[0]; - } + function getComponentAuctionConfig() { + addPaapiConfigHook(nextFnSpy, { + auctionId, + adUnitCode: 'au1', + ortb2: {fpd: 1}, + ortb2Imp: {fpd: 2} + }, paapiConfig); + events.emit(EVENTS.AUCTION_END, {auctionId}); + return getPAAPIConfig({auctionId}).au1.componentAuctions[0]; + } - it('should be added to auctionSignals', () => { - sinon.assert.match(getComponentAuctionConfig().auctionSignals, { - prebid: {ortb2, ortb2Imp} - }); + it('should be added to auctionSignals', () => { + sinon.assert.match(getComponentAuctionConfig().auctionSignals, { + prebid: {ortb2, ortb2Imp} }); - it('should not override existing auctionSignals', () => { - auctionConfig.auctionSignals = {prebid: {ortb2: {fpd: 'original'}}}; - sinon.assert.match(getComponentAuctionConfig().auctionSignals, { - prebid: { - ortb2: {fpd: 'original'}, - ortb2Imp - } - }); + }); + it('should not override existing auctionSignals', () => { + auctionConfig.auctionSignals = {prebid: {ortb2: {fpd: 'original'}}}; + sinon.assert.match(getComponentAuctionConfig().auctionSignals, { + prebid: { + ortb2: {fpd: 'original'}, + ortb2Imp + } }); + }); - it('should be added to perBuyerSignals', () => { - auctionConfig.interestGroupBuyers = ['buyer1', 'buyer2']; - const pbs = getComponentAuctionConfig().perBuyerSignals; - sinon.assert.match(pbs, { - buyer1: {prebid: {ortb2, ortb2Imp}}, - buyer2: {prebid: {ortb2, ortb2Imp}} - }); + it('should be added to perBuyerSignals', () => { + auctionConfig.interestGroupBuyers = ['buyer.1', 'buyer.2']; + const pbs = getComponentAuctionConfig().perBuyerSignals; + sinon.assert.match(pbs, { + 'buyer.1': {prebid: {ortb2, ortb2Imp}}, + 'buyer.2': {prebid: {ortb2, ortb2Imp}} }); + }); - it('should not override existing perBuyerSignals', () => { - auctionConfig.interestGroupBuyers = ['buyer']; - const original = { - prebid: { - ortb2: { - fpd: 'original' - } + it('should not override existing perBuyerSignals', () => { + auctionConfig.interestGroupBuyers = ['buyer']; + const original = { + prebid: { + ortb2: { + fpd: 'original' } - }; - auctionConfig.perBuyerSignals = { - buyer: deepClone(original) - }; - sinon.assert.match(getComponentAuctionConfig().perBuyerSignals.buyer, original); - }); + } + }; + auctionConfig.perBuyerSignals = { + buyer: deepClone(original) + }; + sinon.assert.match(getComponentAuctionConfig().perBuyerSignals.buyer, original); }); + }); - describe('submodules', () => { - let submods; - beforeEach(() => { - submods = [1, 2].map(i => ({ - name: `test${i}`, - onAuctionConfig: sinon.stub() - })); - submods.forEach(registerSubmodule); - }); + describe('submodules', () => { + let submods; + beforeEach(() => { + submods = [1, 2].map(i => ({ + name: `test${i}`, + onAuctionConfig: sinon.stub() + })); + submods.forEach(registerSubmodule); + }); - describe('onAuctionConfig', () => { - const auctionId = 'aid'; - it('is invoked with null configs when there\'s no config', () => { - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au']}); - submods.forEach(submod => sinon.assert.calledWith(submod.onAuctionConfig, auctionId, {au: null})); - }); - it('is invoked with relevant configs', () => { - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, paapiConfig); - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au2'}, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1', 'au2', 'au3']}); - submods.forEach(submod => { - sinon.assert.calledWith(submod.onAuctionConfig, auctionId, { - au1: {componentAuctions: [auctionConfig]}, - au2: {componentAuctions: [auctionConfig]}, - au3: null - }); - }); - }); - it('removes configs from getPAAPIConfig if the module calls markAsUsed', () => { - submods[0].onAuctionConfig.callsFake((auctionId, configs, markAsUsed) => { - markAsUsed('au1'); + describe('onAuctionConfig', () => { + const auctionId = 'aid'; + it('is invoked with null configs when there\'s no config', () => { + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au']}); + submods.forEach(submod => sinon.assert.calledWith(submod.onAuctionConfig, auctionId, {au: null})); + }); + it('is invoked with relevant configs', () => { + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, paapiConfig); + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au2'}, paapiConfig); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1', 'au2', 'au3']}); + submods.forEach(submod => { + sinon.assert.calledWith(submod.onAuctionConfig, auctionId, { + au1: {componentAuctions: [auctionConfig]}, + au2: {componentAuctions: [auctionConfig]}, + au3: null }); - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); - expect(getPAAPIConfig()).to.eql({}); }); - it('keeps them available if they do not', () => { - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); - expect(getPAAPIConfig()).to.not.be.empty; + }); + it('removes configs from getPAAPIConfig if the module calls markAsUsed', () => { + submods[0].onAuctionConfig.callsFake((auctionId, configs, markAsUsed) => { + markAsUsed('au1'); }); + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, paapiConfig); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); + expect(getPAAPIConfig()).to.eql({}); + }); + it('keeps them available if they do not', () => { + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, paapiConfig); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); + expect(getPAAPIConfig()).to.not.be.empty; }); }); + }); - describe('floor signal', () => { - before(() => { - if (!getGlobal().convertCurrency) { - getGlobal().convertCurrency = () => null; - getGlobal().convertCurrency.mock = true; - } - }); - after(() => { - if (getGlobal().convertCurrency.mock) { - delete getGlobal().convertCurrency; - } - }); + describe('floor signal', () => { + before(() => { + if (!getGlobal().convertCurrency) { + getGlobal().convertCurrency = () => null; + getGlobal().convertCurrency.mock = true; + } + }); + after(() => { + if (getGlobal().convertCurrency.mock) { + delete getGlobal().convertCurrency; + } + }); - beforeEach(() => { - sandbox.stub(getGlobal(), 'convertCurrency').callsFake((amount, from, to) => { - if (from === to) return amount; - if (from === 'USD' && to === 'JPY') return amount * 100; - if (from === 'JPY' && to === 'USD') return amount / 100; - throw new Error('unexpected currency conversion'); - }); + beforeEach(() => { + sandbox.stub(getGlobal(), 'convertCurrency').callsFake((amount, from, to) => { + if (from === to) return amount; + if (from === 'USD' && to === 'JPY') return amount * 100; + if (from === 'JPY' && to === 'USD') return amount / 100; + throw new Error('unexpected currency conversion'); }); + }); - Object.entries({ - 'bids': (payload, values) => { - payload.bidsReceived = values - .map((val) => ({adUnitCode: 'au', cpm: val.amount, currency: val.cur})) - .concat([{adUnitCode: 'other', cpm: 10000, currency: 'EUR'}]); - }, - 'no bids': (payload, values) => { - payload.bidderRequests = values - .map((val) => ({ - bids: [{ - adUnitCode: 'au', - getFloor: () => ({floor: val.amount, currency: val.cur}) - }] - })) - .concat([{bids: {adUnitCode: 'other', getFloor: () => ({floor: -10000, currency: 'EUR'})}}]); - } - }).forEach(([tcase, setup]) => { - describe(`when auction has ${tcase}`, () => { - Object.entries({ - 'no currencies': { - values: [{amount: 1}, {amount: 100}, {amount: 10}, {amount: 100}], - 'bids': { - bidfloor: 100, - bidfloorcur: undefined - }, - 'no bids': { - bidfloor: 1, - bidfloorcur: undefined, - } + Object.entries({ + 'bids': (payload, values) => { + payload.bidsReceived = values + .map((val) => ({adUnitCode: 'au', cpm: val.amount, currency: val.cur})) + .concat([{adUnitCode: 'other', cpm: 10000, currency: 'EUR'}]); + }, + 'no bids': (payload, values) => { + payload.bidderRequests = values + .map((val) => ({ + bids: [{ + adUnitCode: 'au', + getFloor: () => ({floor: val.amount, currency: val.cur}) + }] + })) + .concat([{bids: {adUnitCode: 'other', getFloor: () => ({floor: -10000, currency: 'EUR'})}}]); + } + }).forEach(([tcase, setup]) => { + describe(`when auction has ${tcase}`, () => { + Object.entries({ + 'no currencies': { + values: [{amount: 1}, {amount: 100}, {amount: 10}, {amount: 100}], + 'bids': { + bidfloor: 100, + bidfloorcur: undefined }, - 'only zero values': { - values: [{amount: 0, cur: 'USD'}, {amount: 0, cur: 'JPY'}], - 'bids': { - bidfloor: undefined, - bidfloorcur: undefined, - }, - 'no bids': { - bidfloor: undefined, - bidfloorcur: undefined, - } + 'no bids': { + bidfloor: 1, + bidfloorcur: undefined, + } + }, + 'only zero values': { + values: [{amount: 0, cur: 'USD'}, {amount: 0, cur: 'JPY'}], + 'bids': { + bidfloor: undefined, + bidfloorcur: undefined, }, - 'matching currencies': { - values: [{amount: 10, cur: 'JPY'}, {amount: 100, cur: 'JPY'}], - 'bids': { - bidfloor: 100, - bidfloorcur: 'JPY', - }, - 'no bids': { - bidfloor: 10, - bidfloorcur: 'JPY', - } + 'no bids': { + bidfloor: undefined, + bidfloorcur: undefined, + } + }, + 'matching currencies': { + values: [{amount: 10, cur: 'JPY'}, {amount: 100, cur: 'JPY'}], + 'bids': { + bidfloor: 100, + bidfloorcur: 'JPY', }, - 'mixed currencies': { - values: [{amount: 10, cur: 'USD'}, {amount: 10, cur: 'JPY'}], - 'bids': { - bidfloor: 10, - bidfloorcur: 'USD' - }, - 'no bids': { - bidfloor: 10, - bidfloorcur: 'JPY', - } + 'no bids': { + bidfloor: 10, + bidfloorcur: 'JPY', + } + }, + 'mixed currencies': { + values: [{amount: 10, cur: 'USD'}, {amount: 10, cur: 'JPY'}], + 'bids': { + bidfloor: 10, + bidfloorcur: 'USD' + }, + 'no bids': { + bidfloor: 10, + bidfloorcur: 'JPY', } - }).forEach(([t, testConfig]) => { - const values = testConfig.values; - const {bidfloor, bidfloorcur} = testConfig[tcase]; - - describe(`with ${t}`, () => { - let payload; - beforeEach(() => { - payload = {auctionId}; - setup(payload, values); - }); - - it('should populate bidfloor/bidfloorcur', () => { - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au'}, paapiConfig); - events.emit(EVENTS.AUCTION_END, payload); - const cfg = getPAAPIConfig({auctionId}).au; - const signals = cfg.auctionSignals; - sinon.assert.match(cfg.componentAuctions[0].auctionSignals, signals || {}); - expect(signals?.prebid?.bidfloor).to.eql(bidfloor); - expect(signals?.prebid?.bidfloorcur).to.eql(bidfloorcur); - }); + } + }).forEach(([t, testConfig]) => { + const values = testConfig.values; + const {bidfloor, bidfloorcur} = testConfig[tcase]; + + describe(`with ${t}`, () => { + let payload; + beforeEach(() => { + payload = {auctionId}; + setup(payload, values); + }); + + it('should populate bidfloor/bidfloorcur', () => { + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au'}, paapiConfig); + events.emit(EVENTS.AUCTION_END, payload); + const cfg = getPAAPIConfig({auctionId}).au; + const signals = cfg.auctionSignals; + sinon.assert.match(cfg.componentAuctions[0].auctionSignals, signals || {}); + expect(signals?.prebid?.bidfloor).to.eql(bidfloor); + expect(signals?.prebid?.bidfloorcur).to.eql(bidfloorcur); }); }); }); }); }); + }); - describe('requestedSize', () => { - let adUnit; - beforeEach(() => { - adUnit = { - code: 'au', - }; - }); + describe('requestedSize', () => { + let adUnit; + beforeEach(() => { + adUnit = { + code: 'au', + }; + }); - function getConfig() { - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: adUnit.code}, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: [adUnit.code], adUnits: [adUnit]}); - return getPAAPIConfig()[adUnit.code]; - } + function getConfig() { + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: adUnit.code}, paapiConfig); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: [adUnit.code], adUnits: [adUnit]}); + return getPAAPIConfig()[adUnit.code]; + } - Object.entries({ - 'adUnit.ortb2Imp.ext.paapi.requestedSize'() { - adUnit.ortb2Imp = { - ext: { - paapi: { - requestedSize: { - width: 123, - height: 321 - } + Object.entries({ + 'adUnit.ortb2Imp.ext.paapi.requestedSize'() { + adUnit.ortb2Imp = { + ext: { + paapi: { + requestedSize: { + width: 123, + height: 321 } } - }; - }, - 'largest size'() { - getPAAPISizeStub.returns([123, 321]); - } - }).forEach(([t, setup]) => { - describe(`should be set from ${t}`, () => { - beforeEach(setup); - - it('without overriding component auctions, if set', () => { - auctionConfig.requestedSize = {width: '1px', height: '2px'}; - expect(getConfig().componentAuctions[0].requestedSize).to.eql({ - width: '1px', - height: '2px' - }); + } + }; + }, + 'largest size'() { + getPAAPISizeStub.returns([123, 321]); + } + }).forEach(([t, setup]) => { + describe(`should be set from ${t}`, () => { + beforeEach(setup); + + it('without overriding component auctions, if set', () => { + auctionConfig.requestedSize = {width: '1px', height: '2px'}; + expect(getConfig().componentAuctions[0].requestedSize).to.eql({ + width: '1px', + height: '2px' }); + }); - it('on component auction, if missing', () => { - expect(getConfig().componentAuctions[0].requestedSize).to.eql({ - width: 123, - height: 321 - }); + it('on component auction, if missing', () => { + expect(getConfig().componentAuctions[0].requestedSize).to.eql({ + width: 123, + height: 321 }); + }); - it('on top level auction', () => { - expect(getConfig().requestedSize).to.eql({ - width: 123, - height: 321, - }); + it('on top level auction', () => { + expect(getConfig().requestedSize).to.eql({ + width: 123, + height: 321, }); }); }); }); }); + }); - describe('with multiple auctions', () => { - const AUCTION1 = 'auction1'; - const AUCTION2 = 'auction2'; + describe('with multiple auctions', () => { + const AUCTION1 = 'auction1'; + const AUCTION2 = 'auction2'; - function mockAuction(auctionId) { - return { - getAuctionId() { - return auctionId; - } - }; - } + function mockAuction(auctionId) { + return { + getAuctionId() { + return auctionId; + } + }; + } - function expectAdUnitsFromAuctions(actualConfig, auToAuctionMap) { - expect(Object.keys(actualConfig)).to.have.members(Object.keys(auToAuctionMap)); - Object.entries(actualConfig).forEach(([au, cfg]) => { - cfg.componentAuctions.forEach(cmp => expect(cmp.auctionId).to.eql(auToAuctionMap[au])); - }); - } + function expectAdUnitsFromAuctions(actualConfig, auToAuctionMap) { + expect(Object.keys(actualConfig)).to.have.members(Object.keys(auToAuctionMap)); + Object.entries(actualConfig).forEach(([au, cfg]) => { + cfg.componentAuctions.forEach(cmp => expect(cmp.auctionId).to.eql(auToAuctionMap[au])); + }); + } - let configs; - beforeEach(() => { - const mockAuctions = [mockAuction(AUCTION1), mockAuction(AUCTION2)]; - sandbox.stub(auctionManager, 'index').value(new AuctionIndex(() => mockAuctions)); - configs = {[AUCTION1]: {}, [AUCTION2]: {}}; - Object.entries({ - [AUCTION1]: [['au1', 'au2'], ['missing-1']], - [AUCTION2]: [['au2', 'au3'], []], - }).forEach(([auctionId, [adUnitCodes, noConfigAdUnitCodes]]) => { - adUnitCodes.forEach(adUnitCode => { - const cfg = {...auctionConfig, auctionId, adUnitCode}; - configs[auctionId][adUnitCode] = cfg; - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode}, {config: cfg}); - }); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: adUnitCodes.concat(noConfigAdUnitCodes)}); + let configs; + beforeEach(() => { + const mockAuctions = [mockAuction(AUCTION1), mockAuction(AUCTION2)]; + sandbox.stub(auctionManager, 'index').value(new AuctionIndex(() => mockAuctions)); + configs = {[AUCTION1]: {}, [AUCTION2]: {}}; + Object.entries({ + [AUCTION1]: [['au1', 'au2'], ['missing-1']], + [AUCTION2]: [['au2', 'au3'], []], + }).forEach(([auctionId, [adUnitCodes, noConfigAdUnitCodes]]) => { + adUnitCodes.forEach(adUnitCode => { + const cfg = {...auctionConfig, auctionId, adUnitCode}; + configs[auctionId][adUnitCode] = cfg; + addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode}, {config: cfg}); }); + events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: adUnitCodes.concat(noConfigAdUnitCodes)}); }); + }); - it('should filter by auction', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1}), {au1: AUCTION1, au2: AUCTION1}); - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION2}), {au2: AUCTION2, au3: AUCTION2}); - }); + it('should filter by auction', () => { + expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1}), {au1: AUCTION1, au2: AUCTION1}); + expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION2}), {au2: AUCTION2, au3: AUCTION2}); + }); - it('should filter by auction and ad unit', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1, adUnitCode: 'au2'}), {au2: AUCTION1}); - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION2, adUnitCode: 'au2'}), {au2: AUCTION2}); - }); + it('should filter by auction and ad unit', () => { + expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1, adUnitCode: 'au2'}), {au2: AUCTION1}); + expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION2, adUnitCode: 'au2'}), {au2: AUCTION2}); + }); - it('should use last auction for each ad unit', () => { - expectAdUnitsFromAuctions(getPAAPIConfig(), {au1: AUCTION1, au2: AUCTION2, au3: AUCTION2}); - }); + it('should use last auction for each ad unit', () => { + expectAdUnitsFromAuctions(getPAAPIConfig(), {au1: AUCTION1, au2: AUCTION2, au3: AUCTION2}); + }); - it('should filter by ad unit and use latest auction', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({adUnitCode: 'au2'}), {au2: AUCTION2}); - }); + it('should filter by ad unit and use latest auction', () => { + expectAdUnitsFromAuctions(getPAAPIConfig({adUnitCode: 'au2'}), {au2: AUCTION2}); + }); - it('should keep track of which configs were returned', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1}), {au1: AUCTION1, au2: AUCTION1}); - expect(getPAAPIConfig({auctionId: AUCTION1})).to.eql({}); - expectAdUnitsFromAuctions(getPAAPIConfig(), {au2: AUCTION2, au3: AUCTION2}); - }); + it('should keep track of which configs were returned', () => { + expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1}), {au1: AUCTION1, au2: AUCTION1}); + expect(getPAAPIConfig({auctionId: AUCTION1})).to.eql({}); + expectAdUnitsFromAuctions(getPAAPIConfig(), {au2: AUCTION2, au3: AUCTION2}); + }); - describe('includeBlanks = true', () => { - Object.entries({ - 'auction with blanks': { - filters: {auctionId: AUCTION1}, - expected: {au1: true, au2: true, 'missing-1': false} - }, - 'blank adUnit in an auction': { - filters: {auctionId: AUCTION1, adUnitCode: 'missing-1'}, - expected: {'missing-1': false} - }, - 'non-existing auction': { - filters: {auctionId: 'other'}, - expected: {} - }, - 'non-existing adUnit in an auction': { - filters: {auctionId: AUCTION2, adUnitCode: 'other'}, - expected: {} - }, - 'non-existing ad unit': { - filters: {adUnitCode: 'other'}, - expected: {}, - }, - 'non existing ad unit in a non-existing auction': { - filters: {adUnitCode: 'other', auctionId: 'other'}, - expected: {} - }, - 'all ad units': { - filters: {}, - expected: {'au1': true, 'au2': true, 'missing-1': false, 'au3': true} - } - }).forEach(([t, {filters, expected}]) => { - it(t, () => { - const cfg = getPAAPIConfig(filters, true); - expect(Object.keys(cfg)).to.have.members(Object.keys(expected)); - Object.entries(expected).forEach(([au, shouldBeFilled]) => { - if (shouldBeFilled) { - expect(cfg[au]).to.not.be.null; - } else { - expect(cfg[au]).to.be.null; - } - }); + describe('includeBlanks = true', () => { + Object.entries({ + 'auction with blanks': { + filters: {auctionId: AUCTION1}, + expected: {au1: true, au2: true, 'missing-1': false} + }, + 'blank adUnit in an auction': { + filters: {auctionId: AUCTION1, adUnitCode: 'missing-1'}, + expected: {'missing-1': false} + }, + 'non-existing auction': { + filters: {auctionId: 'other'}, + expected: {} + }, + 'non-existing adUnit in an auction': { + filters: {auctionId: AUCTION2, adUnitCode: 'other'}, + expected: {} + }, + 'non-existing ad unit': { + filters: {adUnitCode: 'other'}, + expected: {}, + }, + 'non existing ad unit in a non-existing auction': { + filters: {adUnitCode: 'other', auctionId: 'other'}, + expected: {} + }, + 'all ad units': { + filters: {}, + expected: {'au1': true, 'au2': true, 'missing-1': false, 'au3': true} + } + }).forEach(([t, {filters, expected}]) => { + it(t, () => { + const cfg = getPAAPIConfig(filters, true); + expect(Object.keys(cfg)).to.have.members(Object.keys(expected)); + Object.entries(expected).forEach(([au, shouldBeFilled]) => { + if (shouldBeFilled) { + expect(cfg[au]).to.not.be.null; + } else { + expect(cfg[au]).to.be.null; + } }); }); }); }); }); + }); - describe('markForFledge', function () { - const navProps = Object.fromEntries(['runAdAuction', 'joinAdInterestGroup'].map(p => [p, navigator[p]])); - let adUnits; + describe('markForFledge', function () { + const navProps = Object.fromEntries(['runAdAuction', 'joinAdInterestGroup'].map(p => [p, navigator[p]])); + let adUnits; - before(function () { - // navigator.runAdAuction & co may not exist, so we can't stub it normally with - // sinon.stub(navigator, 'runAdAuction') or something - Object.keys(navProps).forEach(p => { - navigator[p] = sinon.stub(); - }); - hook.ready(); - config.resetConfig(); + before(function () { + // navigator.runAdAuction & co may not exist, so we can't stub it normally with + // sinon.stub(navigator, 'runAdAuction') or something + Object.keys(navProps).forEach(p => { + navigator[p] = sinon.stub(); }); + hook.ready(); + config.resetConfig(); + }); - after(function () { - Object.entries(navProps).forEach(([p, orig]) => navigator[p] = orig); - }); + after(function () { + Object.entries(navProps).forEach(([p, orig]) => navigator[p] = orig); + }); - beforeEach(() => { - getPAAPISizeStub = sinon.stub(); - adUnits = [{ - 'code': '/19968336/header-bid-tag1', - 'mediaTypes': { - 'banner': { - 'sizes': [[728, 90]] - }, + beforeEach(() => { + getPAAPISizeStub = sinon.stub(); + adUnits = [{ + 'code': '/19968336/header-bid-tag1', + 'mediaTypes': { + 'banner': { + 'sizes': [[728, 90]] }, - 'bids': [ - { - 'bidder': 'appnexus', - }, - { - 'bidder': 'rubicon', - }, - ] - }]; - }); + }, + 'bids': [ + { + 'bidder': 'appnexus', + }, + { + 'bidder': 'rubicon', + }, + ] + }]; + }); - afterEach(function () { - config.resetConfig(); - }); + afterEach(function () { + config.resetConfig(); + }); + describe('makeBidRequests', () => { function mark() { return Object.fromEntries( adapterManager.makeBidRequests( @@ -671,11 +668,9 @@ describe('paapi module', () => { function expectFledgeFlags(...enableFlags) { const bidRequests = mark(); - expect(bidRequests.appnexus.fledgeEnabled).to.eql(enableFlags[0].enabled); expect(bidRequests.appnexus.paapi?.enabled).to.eql(enableFlags[0].enabled); bidRequests.appnexus.bids.forEach(bid => expect(bid.ortb2Imp.ext.ae).to.eql(enableFlags[0].ae)); - expect(bidRequests.rubicon.fledgeEnabled).to.eql(enableFlags[1].enabled); expect(bidRequests.rubicon.paapi?.enabled).to.eql(enableFlags[1].enabled); bidRequests.rubicon.bids.forEach(bid => expect(bid.ortb2Imp?.ext?.ae).to.eql(enableFlags[1].ae)); @@ -689,36 +684,23 @@ describe('paapi module', () => { }); } - describe('with setBidderConfig()', () => { - it('should set fledgeEnabled correctly per bidder', function () { - config.setBidderConfig({ - bidders: ['appnexus'], - config: { - defaultForSlots: 1, - fledgeEnabled: true - } - }); - expectFledgeFlags({enabled: true, ae: 1}, {enabled: void 0, ae: void 0}); - }); - }); - describe('with setConfig()', () => { - it('should set fledgeEnabled correctly per bidder', function () { + it('should set paapi.enabled correctly per bidder', function () { config.setConfig({ bidderSequence: 'fixed', - [configNS]: { + paapi: { enabled: true, bidders: ['appnexus'], defaultForSlots: 1, } }); - expectFledgeFlags({enabled: true, ae: 1}, {enabled: false, ae: undefined}); + expectFledgeFlags({enabled: true, ae: 1}, {enabled: false, ae: 0}); }); - it('should set fledgeEnabled correctly for all bidders', function () { + it('should set paapi.enabled correctly for all bidders', function () { config.setConfig({ bidderSequence: 'fixed', - [configNS]: { + paapi: { enabled: true, defaultForSlots: 1, } @@ -744,7 +726,7 @@ describe('paapi module', () => { }).forEach(([t, {cfg, componentSeller}]) => { it(`should set request paapi.componentSeller = ${componentSeller} when config componentSeller is ${t}`, () => { config.setConfig({ - [configNS]: { + paapi: { enabled: true, defaultForSlots: 1, ...cfg @@ -753,64 +735,134 @@ describe('paapi module', () => { Object.values(mark()).forEach(br => expect(br.paapi?.componentSeller).to.eql(componentSeller)); }); }); + }); + }); + describe('addPaapiData', () => { + function getEnrichedAdUnits() { + const next = sinon.stub(); + addPaapiData(next, adUnits); + sinon.assert.calledWith(next, adUnits); + return adUnits; + } - it('should not override pub-defined ext.ae', () => { - config.setConfig({ - bidderSequence: 'fixed', - [configNS]: { - enabled: true, - defaultForSlots: 1, - } - }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 0}}}); - expectFledgeFlags({enabled: true, ae: 0}, {enabled: true, ae: 0}); + function getImpExt() { + const next = sinon.stub(); + addPaapiData(next, adUnits); + sinon.assert.calledWith(next, adUnits); + return { + global: adUnits[0].ortb2Imp?.ext, + ...Object.fromEntries(adUnits[0].bids.map(bid => [bid.bidder, bid.ortb2Imp?.ext])) + } + } + + it('should not override pub-defined ext.ae', () => { + config.setConfig({ + paapi: { + enabled: true, + defaultForSlots: 1, + } + }); + Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 0}}}); + sinon.assert.match(getImpExt(), { + global: { + ae: 0, + }, + rubicon: undefined, + appnexus: undefined }); + }); - it('should populate ext.igs when request has ext.ae', () => { - config.setConfig({ - bidderSequence: 'fixed', - [configNS]: { - enabled: true + it('should override per-bidder when excluded via paapi.bidders', () => { + config.setConfig({ + paapi: { + enabled: true, + defaultForSlots: 1, + bidders: ['rubicon'] + } + }) + sinon.assert.match(getImpExt(), { + global: { + ae: 1, + igs: { + ae: 1, + biddable: 1 } - }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 3}}}); - expectFledgeFlags({enabled: true, ae: 3}, {enabled: true, ae: 3}); - }); + }, + rubicon: undefined, + appnexus: { + ae: 0, + igs: { + ae: 0, + biddable: 0 + } + } + }) + }) - it('should not override pub-defined ext.igs', () => { - config.setConfig({ - [configNS]: { - enabled: true + it('should populate ext.igs when request has ext.ae', () => { + config.setConfig({ + paapi: { + enabled: true + } + }); + Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 3}}}); + sinon.assert.match(getImpExt(), { + global: { + ae: 3, + igs: { + ae: 3, + biddable: 1 } - }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 1, igs: {biddable: 0}}}}); - const bidReqs = mark(); - Object.values(bidReqs).flatMap(req => req.bids).forEach(bid => { - sinon.assert.match(bid.ortb2Imp.ext, { - ae: 1, - igs: { - ae: 1, - biddable: 0 - } - }); - }); + }, + rubicon: undefined, + appnexus: undefined, }); + }); - it('should fill ext.ae from ext.igs, if defined', () => { - config.setConfig({ - [configNS]: { - enabled: true + it('should not override pub-defined ext.igs', () => { + config.setConfig({ + paapi: { + enabled: true + } + }); + Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 1, igs: {biddable: 0}}}}); + sinon.assert.match(getImpExt(), { + global: { + ae: 1, + igs: { + ae: 1, + biddable: 0 } - }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {igs: {}}}}); - expectFledgeFlags({enabled: true, ae: 1}, {enabled: true, ae: 1}); + }, + rubicon: undefined, + appnexus: undefined + }) + }); + + it('should fill ext.ae from ext.igs, if defined', () => { + config.setConfig({ + paapi: { + enabled: true + } }); + Object.assign(adUnits[0], {ortb2Imp: {ext: {igs: {}}}}); + sinon.assert.match(getImpExt(), { + global: { + ae: 1, + igs: { + ae: 1, + biddable: 1 + } + }, + appnexus: undefined, + rubicon: undefined + }) }); describe('ortb2Imp.ext.paapi.requestedSize', () => { beforeEach(() => { config.setConfig({ - [configNS]: { + paapi: { enabled: true, defaultForSlots: 1, } @@ -819,13 +871,11 @@ describe('paapi module', () => { it('should default to value returned by getPAAPISize', () => { getPAAPISizeStub.returns([123, 321]); - Object.values(mark()).flatMap(b => b.bids).forEach(bidRequest => { - sinon.assert.match(bidRequest.ortb2Imp.ext.paapi, { - requestedSize: { - width: 123, - height: 321 - } - }); + expect(getImpExt().global.paapi).to.eql({ + requestedSize: { + width: 123, + height: 321 + } }); }); @@ -840,14 +890,12 @@ describe('paapi module', () => { } } }; - Object.values(mark()).flatMap(b => b.bids).forEach(bidRequest => { - sinon.assert.match(bidRequest.ortb2Imp.ext.paapi, { - requestedSize: { - width: '123px', - height: '321px' - } - }); - }); + expect(getImpExt().global.paapi).to.eql({ + requestedSize: { + width: '123px', + height: '321px' + } + }) sinon.assert.notCalled(getPAAPISizeStub); }); @@ -855,9 +903,7 @@ describe('paapi module', () => { adUnits[0].mediaTypes = { video: {} }; - Object.values(mark()).flatMap(b => b.bids).forEach(bidRequest => { - expect(bidRequest.ortb2Imp?.ext?.paapi?.requestedSize).to.not.exist; - }); + expect(getImpExt().global?.paapi?.requestedSize).to.not.exist; }); }); }); @@ -1093,7 +1139,7 @@ describe('paapi module', () => { }); it('imp.ext.ae should be left intact if fledge is enabled', () => { const imp = {ext: {ae: 2, igs: {biddable: 0}}}; - setImpExtAe(imp, {}, {bidderRequest: {fledgeEnabled: true}}); + setImpExtAe(imp, {}, {bidderRequest: {paapi: {enabled: true}}}); expect(imp.ext).to.eql({ ae: 2, igs: { diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js deleted file mode 100644 index 6886fa827c0..00000000000 --- a/test/spec/modules/parrableIdSystem_spec.js +++ /dev/null @@ -1,784 +0,0 @@ -import { expect } from 'chai'; -import {find} from 'src/polyfill.js'; -import { config } from 'src/config.js'; -import * as utils from 'src/utils.js'; -import { newStorageManager } from 'src/storageManager.js'; -import { getRefererInfo } from 'src/refererDetection.js'; -import { uspDataHandler } from 'src/adapterManager.js'; -import {attachIdSystem, init, requestBidsHook, setSubmoduleRegistry} from 'modules/userId/index.js'; -import { parrableIdSubmodule } from 'modules/parrableIdSystem.js'; -import { server } from 'test/mocks/xhr.js'; -import {mockGdprConsent} from '../../helpers/consentData.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import 'src/prebid.js'; -import {merkleIdSubmodule} from '../../../modules/merkleIdSystem.js'; - -const storage = newStorageManager(); - -const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; -const EXPIRE_COOKIE_TIME = 864000000; -const P_COOKIE_NAME = '_parrable_id'; -const P_COOKIE_EID = '01.1563917337.test-eid'; -const P_XHR_EID = '01.1588030911.test-new-eid' -const P_CONFIG_MOCK = { - name: 'parrableId', - params: { - partners: 'parrable_test_partner_123,parrable_test_partner_456' - } -}; -const RESPONSE_HEADERS = { 'Content-Type': 'application/json' }; - -function getConfigMock() { - return { - userSync: { - syncDelay: 0, - userIds: [P_CONFIG_MOCK] - } - } -} - -function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [ - [300, 200], - [300, 600] - ], - bids: [{ - bidder: 'sampleBidder', - params: { placementId: 'banner-only-bidder' } - }] - }; -} - -function serializeParrableId(parrableId) { - let str = ''; - if (parrableId.eid) { - str += 'eid:' + parrableId.eid; - } - if (parrableId.ibaOptout) { - str += ',ibaOptout:1'; - } - if (parrableId.ccpaOptout) { - str += ',ccpaOptout:1'; - } - if (parrableId.tpc !== undefined) { - const tpcSupportComponent = parrableId.tpc === true ? 'tpc:1' : 'tpc:0'; - str += `,${tpcSupportComponent}`; - str += `,tpcUntil:${parrableId.tpcUntil}`; - } - if (parrableId.filteredUntil) { - str += `,filteredUntil:${parrableId.filteredUntil}`; - str += `,filterHits:${parrableId.filterHits}`; - } - return str; -} - -function writeParrableCookie(parrableId) { - let cookieValue = encodeURIComponent(serializeParrableId(parrableId)); - storage.setCookie( - P_COOKIE_NAME, - cookieValue, - (new Date(Date.now() + EXPIRE_COOKIE_TIME).toUTCString()), - 'lax' - ); -} - -function removeParrableCookie() { - storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); -} - -function decodeBase64UrlSafe(encBase64) { - const DEC = { - '-': '+', - '_': '/', - '.': '=' - }; - return encBase64.replace(/[-_.]/g, (m) => DEC[m]); -} - -describe('Parrable ID System', function() { - after(() => { - // reset ID system to avoid delayed callbacks in other tests - config.resetConfig(); - init(config); - }); - - describe('parrableIdSystem.getId()', function() { - describe('response callback function', function() { - let logErrorStub; - let callbackSpy = sinon.spy(); - - beforeEach(function() { - logErrorStub = sinon.stub(utils, 'logError'); - callbackSpy.resetHistory(); - writeParrableCookie({ eid: P_COOKIE_EID }); - }); - - afterEach(function() { - removeParrableCookie(); - logErrorStub.restore(); - }) - - it('creates xhr to Parrable that synchronizes the ID', function() { - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - - getIdResult.callback(callbackSpy); - - let request = server.requests[0]; - let queryParams = utils.parseQS(request.url.split('?')[1]); - let data = JSON.parse(atob(decodeBase64UrlSafe(queryParams.data))); - - expect(getIdResult.callback).to.be.a('function'); - expect(request.url).to.contain('h.parrable.com'); - - expect(queryParams).to.not.have.property('us_privacy'); - expect(data).to.deep.equal({ - eid: P_COOKIE_EID, - trackers: P_CONFIG_MOCK.params.partners.split(','), - url: getRefererInfo().page, - prebidVersion: '$prebid.version$', - isIframe: true - }); - - server.requests[0].respond(200, - { 'Content-Type': 'text/plain' }, - JSON.stringify({ eid: P_XHR_EID }) - ); - expect(callbackSpy.lastCall.lastArg).to.deep.equal({ - eid: P_XHR_EID - }); - - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent('eid:' + P_XHR_EID) - ); - }); - - it('xhr passes the uspString to Parrable', function() { - let uspString = '1YNN'; - uspDataHandler.setConsentData(uspString); - parrableIdSubmodule.getId( - P_CONFIG_MOCK, - null, - null - ).callback(callbackSpy); - uspDataHandler.setConsentData(null); - expect(server.requests[0].url).to.contain('us_privacy=' + uspString); - }); - - it('xhr base64 safely encodes url data object', function() { - const urlSafeBase64EncodedData = '-_.'; - const btoaStub = sinon.stub(window, 'btoa').returns('+/='); - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - - getIdResult.callback(callbackSpy); - - let request = server.requests[0]; - let queryParams = utils.parseQS(request.url.split('?')[1]); - expect(queryParams.data).to.equal(urlSafeBase64EncodedData); - btoaStub.restore(); - }); - - it('should log an error and continue to callback if ajax request errors', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = parrableIdSubmodule.getId({ params: {partners: 'prebid'} }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('h.parrable.com'); - request.respond( - 503, - null, - 'Unavailable' - ); - expect(logErrorStub.calledOnce).to.be.true; - expect(callBackSpy.calledOnce).to.be.true; - }); - }); - - describe('response id', function() { - it('provides the stored Parrable values if a cookie exists', function() { - writeParrableCookie({ eid: P_COOKIE_EID }); - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - removeParrableCookie(); - - expect(getIdResult.id).to.deep.equal({ - eid: P_COOKIE_EID - }); - }); - - it('provides the stored legacy Parrable ID values if cookies exist', function() { - let oldEid = '01.111.old-eid'; - let oldEidCookieName = '_parrable_eid'; - let oldOptoutCookieName = '_parrable_optout'; - - storage.setCookie(oldEidCookieName, oldEid); - storage.setCookie(oldOptoutCookieName, 'true'); - - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - expect(getIdResult.id).to.deep.equal({ - eid: oldEid, - ibaOptout: true - }); - - // The ID system is expected to migrate old cookies to the new format - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent('eid:' + oldEid + ',ibaOptout:1') - ); - expect(storage.getCookie(oldEidCookieName)).to.equal(null); - expect(storage.getCookie(oldOptoutCookieName)).to.equal(null); - removeParrableCookie(); - }); - }); - - describe('GDPR consent', () => { - let callbackSpy = sinon.spy(); - - const config = { - params: { - partner: 'partner' - } - }; - - const gdprConsentTestCases = [ - { consentData: { gdprApplies: true, consentString: 'expectedConsentString' }, expected: { gdpr: 1, gdpr_consent: 'expectedConsentString' } }, - { consentData: { gdprApplies: false, consentString: 'expectedConsentString' }, expected: { gdpr: 0 } }, - { consentData: { gdprApplies: true, consentString: undefined }, expected: { gdpr: 1, gdpr_consent: '' } }, - { consentData: { gdprApplies: 'yes', consentString: 'expectedConsentString' }, expected: { gdpr: 0 } }, - { consentData: undefined, expected: { gdpr: 0 } } - ]; - - gdprConsentTestCases.forEach((testCase, index) => { - it(`should call user sync url with the gdprConsent - case ${index}`, () => { - parrableIdSubmodule.getId(config, testCase.consentData).callback(callbackSpy); - - if (testCase.expected.gdpr === 1) { - expect(server.requests[0].url).to.contain('gdpr=' + testCase.expected.gdpr); - expect(server.requests[0].url).to.contain('gdpr_consent=' + testCase.expected.gdpr_consent); - } else { - expect(server.requests[0].url).to.contain('gdpr=' + testCase.expected.gdpr); - expect(server.requests[0].url).to.not.contain('gdpr_consent'); - } - }) - }); - }); - - describe('third party cookie support', function () { - let logErrorStub; - let callbackSpy = sinon.spy(); - - beforeEach(function() { - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - callbackSpy.resetHistory(); - removeParrableCookie(); - }); - - afterEach(function() { - logErrorStub.restore(); - }); - - describe('when getting tpcSupport from XHR response', function () { - let request; - let dateNowStub; - const dateNowMock = Date.now(); - const tpcSupportTtl = 1; - - before(() => { - dateNowStub = sinon.stub(Date, 'now').returns(dateNowMock); - }); - - after(() => { - dateNowStub.restore(); - }); - - it('should set tpcSupport: true and tpcUntil in the cookie', function () { - let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK); - callback(callbackSpy); - request = server.requests[0]; - - request.respond( - 200, - RESPONSE_HEADERS, - JSON.stringify({ eid: P_XHR_EID, tpcSupport: true, tpcSupportTtl }) - ); - - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent('eid:' + P_XHR_EID + ',tpc:1,tpcUntil:' + Math.floor((dateNowMock / 1000) + tpcSupportTtl)) - ); - }); - - it('should set tpcSupport: false and tpcUntil in the cookie', function () { - let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK); - callback(callbackSpy); - request = server.requests[0]; - request.respond( - 200, - RESPONSE_HEADERS, - JSON.stringify({ eid: P_XHR_EID, tpcSupport: false, tpcSupportTtl }) - ); - - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent('eid:' + P_XHR_EID + ',tpc:0,tpcUntil:' + Math.floor((dateNowMock / 1000) + tpcSupportTtl)) - ); - }); - - it('should not set tpcSupport in the cookie', function () { - let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK); - callback(callbackSpy); - request = server.requests[0]; - - request.respond( - 200, - RESPONSE_HEADERS, - JSON.stringify({ eid: P_XHR_EID }) - ); - - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent('eid:' + P_XHR_EID) - ); - }); - }); - }); - - describe('request-filter status', function () { - let logErrorStub; - let callbackSpy = sinon.spy(); - - beforeEach(function() { - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - callbackSpy.resetHistory(); - removeParrableCookie(); - }); - - afterEach(function() { - logErrorStub.restore(); - }); - - describe('when getting filterTtl from XHR response', function () { - let request; - let dateNowStub; - const dateNowMock = Date.now(); - const filterTtl = 1000; - - before(() => { - dateNowStub = sinon.stub(Date, 'now').returns(dateNowMock); - }); - - after(() => { - dateNowStub.restore(); - }); - - it('should set filteredUntil in the cookie', function () { - let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK); - callback(callbackSpy); - request = server.requests[0]; - - request.respond( - 200, - RESPONSE_HEADERS, - JSON.stringify({ eid: P_XHR_EID, filterTtl }) - ); - - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent( - 'eid:' + P_XHR_EID + - ',filteredUntil:' + Math.floor((dateNowMock / 1000) + filterTtl) + - ',filterHits:0') - ); - }); - - it('should increment filterHits in the cookie', function () { - writeParrableCookie({ - eid: P_XHR_EID, - filteredUntil: Math.floor((dateNowMock / 1000) + filterTtl), - filterHits: 0 - }); - let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK); - callback(callbackSpy); - - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent( - 'eid:' + P_XHR_EID + - ',filteredUntil:' + Math.floor((dateNowMock / 1000) + filterTtl) + - ',filterHits:1') - ); - }); - - it('should send filterHits in the XHR', function () { - const filterHits = 1; - writeParrableCookie({ - eid: P_XHR_EID, - filteredUntil: Math.floor(dateNowMock / 1000), - filterHits - }); - let { callback } = parrableIdSubmodule.getId(P_CONFIG_MOCK); - callback(callbackSpy); - request = server.requests[0]; - - let queryParams = utils.parseQS(request.url.split('?')[1]); - let data = JSON.parse(atob(decodeBase64UrlSafe(queryParams.data))); - - expect(data.filterHits).to.equal(filterHits); - }); - }); - }); - }); - - describe('parrableIdSystem.decode()', function() { - it('provides the Parrable ID (EID) from a stored object', function() { - let eid = '01.123.4567890'; - let parrableId = { - eid, - ibaOptout: true - }; - - expect(parrableIdSubmodule.decode(parrableId)).to.deep.equal({ - parrableId - }); - }); - }); - - describe('timezone filtering', function() { - before(function() { - sinon.stub(Intl, 'DateTimeFormat'); - }); - - after(function() { - Intl.DateTimeFormat.restore(); - }); - - it('permits an impression when no timezoneFilter is configured', function() { - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - } })).to.have.property('callback'); - }); - - it('permits an impression from a blocked timezone when a cookie exists', function() { - const blockedZone = 'Antarctica/South_Pole'; - const resolvedOptions = sinon.stub().returns({ timeZone: blockedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - writeParrableCookie({ eid: P_COOKIE_EID }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(false); - - removeParrableCookie(); - }) - - it('permits an impression from an allowed timezone', function() { - const allowedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: allowedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedZones: [ allowedZone ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(true); - }); - - it('permits an impression from a lower cased allowed timezone', function() { - const allowedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: allowedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partner: 'prebid-test', - timezoneFilter: { - allowedZones: [ allowedZone.toLowerCase() ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(true); - }); - - it('permits an impression from a timezone that is not blocked', function() { - const blockedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: 'Iceland' }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(true); - }); - - it('does not permit an impression from a blocked timezone', function() { - const blockedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: blockedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone ] - } - } })).to.equal(null); - expect(resolvedOptions.called).to.equal(true); - }); - - it('does not permit an impression from a lower cased blocked timezone', function() { - const blockedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: blockedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partner: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone.toLowerCase() ] - } - } })).to.equal(null); - expect(resolvedOptions.called).to.equal(true); - }); - - it('does not permit an impression from a blocked timezone even when also allowed', function() { - const timezone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: timezone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedZones: [ timezone ], - blockedZones: [ timezone ] - } - } })).to.equal(null); - expect(resolvedOptions.called).to.equal(true); - }); - }); - - describe('timezone offset filtering', function() { - before(function() { - sinon.stub(Date.prototype, 'getTimezoneOffset'); - }); - - afterEach(function() { - Date.prototype.getTimezoneOffset.reset(); - }) - - after(function() { - Date.prototype.getTimezoneOffset.restore(); - }); - - it('permits an impression from a blocked offset when a cookie exists', function() { - const blockedOffset = -4; - Date.prototype.getTimezoneOffset.returns(blockedOffset * 60); - - writeParrableCookie({ eid: P_COOKIE_EID }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedOffsets: [ blockedOffset ] - } - } })).to.have.property('callback'); - - removeParrableCookie(); - }); - - it('permits an impression from an allowed offset', function() { - const allowedOffset = -5; - Date.prototype.getTimezoneOffset.returns(allowedOffset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedOffsets: [ allowedOffset ] - } - } })).to.have.property('callback'); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - - it('permits an impression from an offset that is not blocked', function() { - const allowedOffset = -5; - const blockedOffset = 5; - Date.prototype.getTimezoneOffset.returns(allowedOffset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedOffsets: [ blockedOffset ] - } - }})).to.have.property('callback'); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - - it('does not permit an impression from a blocked offset', function() { - const blockedOffset = -5; - Date.prototype.getTimezoneOffset.returns(blockedOffset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedOffsets: [ blockedOffset ] - } - } })).to.equal(null); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - - it('does not permit an impression from a blocked offset even when also allowed', function() { - const offset = -5; - Date.prototype.getTimezoneOffset.returns(offset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedOffset: [ offset ], - blockedOffsets: [ offset ] - } - } })).to.equal(null); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - }); - - describe('userId requestBids hook', function() { - let adUnits; - let sandbox; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - mockGdprConsent(sandbox); - adUnits = [getAdUnitMock()]; - writeParrableCookie({ eid: P_COOKIE_EID, ibaOptout: true }); - init(config); - setSubmoduleRegistry([parrableIdSubmodule]); - }); - - afterEach(function() { - removeParrableCookie(); - storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); - sandbox.restore(); - }); - - it('when a stored Parrable ID exists it is added to bids', function(done) { - config.setConfig(getConfigMock()); - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableId'); - expect(bid.userId.parrableId.eid).to.equal(P_COOKIE_EID); - expect(bid.userId.parrableId.ibaOptout).to.equal(true); - const parrableIdAsEid = find(bid.userIdAsEids, e => e.source == 'parrable.com'); - expect(parrableIdAsEid).to.deep.equal({ - source: 'parrable.com', - uids: [{ - id: P_COOKIE_EID, - atype: 1, - ext: { - ibaOptout: true - } - }] - }); - }); - }); - done(); - }, { adUnits }); - }); - - it('supplies an optout reason when the EID is missing due to CCPA non-consent', function(done) { - // the ID system itself will not write a cookie with an EID when CCPA=true - writeParrableCookie({ ccpaOptout: true }); - config.setConfig(getConfigMock()); - - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableId'); - expect(bid.userId.parrableId).to.not.have.property('eid'); - expect(bid.userId.parrableId.ccpaOptout).to.equal(true); - const parrableIdAsEid = find(bid.userIdAsEids, e => e.source == 'parrable.com'); - expect(parrableIdAsEid).to.deep.equal({ - source: 'parrable.com', - uids: [{ - id: '', - atype: 1, - ext: { - ccpaOptout: true - } - }] - }); - }); - }); - done(); - }, { adUnits }); - }); - }); - - describe('partners parsing', function () { - let callbackSpy = sinon.spy(); - - const partnersTestCase = [ - { - name: '"partners" as an array', - config: { params: { partners: ['parrable_test_partner_123', 'parrable_test_partner_456'] } }, - expected: ['parrable_test_partner_123', 'parrable_test_partner_456'] - }, - { - name: '"partners" as a string list', - config: { params: { partners: 'parrable_test_partner_123,parrable_test_partner_456' } }, - expected: ['parrable_test_partner_123', 'parrable_test_partner_456'] - }, - { - name: '"partners" as a string', - config: { params: { partners: 'parrable_test_partner_123' } }, - expected: ['parrable_test_partner_123'] - }, - { - name: '"partner" as a string list', - config: { params: { partner: 'parrable_test_partner_123,parrable_test_partner_456' } }, - expected: ['parrable_test_partner_123', 'parrable_test_partner_456'] - }, - { - name: '"partner" as string', - config: { params: { partner: 'parrable_test_partner_123' } }, - expected: ['parrable_test_partner_123'] - }, - ]; - partnersTestCase.forEach(testCase => { - it(`accepts config property ${testCase.name}`, () => { - parrableIdSubmodule.getId(testCase.config).callback(callbackSpy); - - let request = server.requests[0]; - let queryParams = utils.parseQS(request.url.split('?')[1]); - let data = JSON.parse(atob(decodeBase64UrlSafe(queryParams.data))); - - expect(data.trackers).to.deep.equal(testCase.expected); - }); - }); - }); - - describe('eid', () => { - before(() => { - attachIdSystem(merkleIdSubmodule); - }) - it('parrableId', function() { - const userId = { - parrableId: { - eid: 'some-random-id-value' - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'parrable.com', - uids: [{id: 'some-random-id-value', atype: 1}] - }); - }); - }) -}); diff --git a/test/spec/modules/permutiveRtdProvider_spec.js b/test/spec/modules/permutiveRtdProvider_spec.js index 73218fee7b9..51fbba7e936 100644 --- a/test/spec/modules/permutiveRtdProvider_spec.js +++ b/test/spec/modules/permutiveRtdProvider_spec.js @@ -484,7 +484,9 @@ describe('permutiveRtdProvider', function () { _psegs: [], _ppam: [], _pcrprs: [], - _pssps: { ssps: [], cohorts: [] } + _pindexs: [], + _pssps: { ssps: [], cohorts: [] }, + _ppsts: {}, }) setBidderRtb(bidderConfig, moduleConfig, segmentsData) @@ -568,6 +570,7 @@ describe('permutiveRtdProvider', function () { const data = transformedTargeting() expect(getSegments(250)).to.deep.equal(data) }) + it('should enforce max segments', function () { const max = 1 const segments = getSegments(max) @@ -584,6 +587,26 @@ describe('permutiveRtdProvider', function () { } } }) + + it('should coerce numbers to strings', function () { + setLocalStorage({ _prubicons: [1, 2, 3], _pssps: { ssps: ['foo', 'bar'], cohorts: [4, 5, 6] } }) + + const segments = getSegments(200) + + expect(segments.rubicon).to.deep.equal(['1', '2', '3']) + expect(segments.ssp.ssps).to.deep.equal(['foo', 'bar']) + expect(segments.ssp.cohorts).to.deep.equal(['4', '5', '6']) + }) + + it('should return empty values on unexpected format', function () { + setLocalStorage({ _prubicons: 'a string instead?', _pssps: 123 }) + + const segments = getSegments(200) + + expect(segments.rubicon).to.deep.equal([]) + expect(segments.ssp.ssps).to.deep.equal([]) + expect(segments.ssp.cohorts).to.deep.equal([]) + }) }) describe('Existing key-value targeting', function () { @@ -703,14 +726,25 @@ function getConfig () { } function transformedTargeting (data = getTargetingData()) { + const topics = (() => { + const topics = {} + for (const topic in data._ppsts) { + topics[topic] = data._ppsts[topic].map(String) + } + return topics + })() + return { - ac: [...data._pcrprs, ...data._ppam, ...data._psegs.filter(seg => seg >= 1000000)], - appnexus: data._papns, - ix: data._pindexs, - rubicon: data._prubicons, - gam: data._pdfps, - ssp: data._pssps, - topics: data._ppsts, + ac: [...data._pcrprs, ...data._ppam, ...data._psegs.filter(seg => seg >= 1000000)].map(String), + appnexus: data._papns.map(String), + ix: data._pindexs.map(String), + rubicon: data._prubicons.map(String), + gam: data._pdfps.map(String), + ssp: { + ssps: data._pssps.ssps.map(String), + cohorts: data._pssps.cohorts.map(String) + }, + topics, } } diff --git a/test/spec/modules/pgamsspBidAdapter_spec.js b/test/spec/modules/pgamsspBidAdapter_spec.js index 281a012fb7a..a90eadba8b0 100644 --- a/test/spec/modules/pgamsspBidAdapter_spec.js +++ b/test/spec/modules/pgamsspBidAdapter_spec.js @@ -3,9 +3,19 @@ import { spec } from '../../../modules/pgamsspBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; -const bidder = 'pgamssp' +const bidder = 'pgamssp'; describe('PGAMBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -16,8 +26,9 @@ describe('PGAMBidAdapter', function () { } }, params: { - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -30,8 +41,9 @@ describe('PGAMBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -53,8 +65,9 @@ describe('PGAMBidAdapter', function () { } }, params: { - placementId: 'testNative', - } + placementId: 'testNative' + }, + userIdAsEids } ]; @@ -74,10 +87,19 @@ describe('PGAMBidAdapter', function () { const bidderRequest = { uspConsent: '1---', gdprConsent: { - consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw' + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } }, timeout: 500 }; @@ -147,7 +169,56 @@ describe('PGAMBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); - expect(placement.eids).to.exist.and.to.be.an('array'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -174,6 +245,8 @@ describe('PGAMBidAdapter', function () { let data = serverRequest.data; expect(data.gdpr).to.exist; expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; @@ -189,12 +262,6 @@ describe('PGAMBidAdapter', function () { expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([], bidderRequest); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); }); describe('gpp consent', function () { diff --git a/test/spec/modules/pirIdSystem_spec.js b/test/spec/modules/pirIdSystem_spec.js deleted file mode 100644 index 5acc5a5eb9c..00000000000 --- a/test/spec/modules/pirIdSystem_spec.js +++ /dev/null @@ -1,77 +0,0 @@ -import { pirIdSubmodule, storage, readId } from 'modules/pirIdSystem.js'; -import sinon from 'sinon'; - -describe('pirIdSystem', () => { - let sandbox; - let getCookieStub; - let getDataFromLocalStorageStub; - - beforeEach(() => { - sandbox = sinon.createSandbox(); - getCookieStub = sandbox.stub(storage, 'getCookie'); - getDataFromLocalStorageStub = sandbox.stub(storage, 'getDataFromLocalStorage'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('getId', () => { - it('should return an object with id when pirIdToken is found', () => { - getDataFromLocalStorageStub.returns('testToken'); - getCookieStub.returns('testToken'); - - const result = pirIdSubmodule.getId(); - - expect(result).to.deep.equal({ id: 'testToken' }); - }); - - it('should return undefined when pirIdToken is not found', () => { - const result = pirIdSubmodule.getId(); - - expect(result).to.be.undefined; - }); - }); - - describe('decode', () => { - it('should return an object with pirId when value is a string', () => { - const result = pirIdSubmodule.decode('testId'); - - expect(result).to.deep.equal({ pirId: 'testId' }); - }); - - it('should return undefined when value is not a string', () => { - const result = pirIdSubmodule.decode({}); - - expect(result).to.be.undefined; - }); - }); - - describe('readId', () => { - it('should return data from local storage when it exists', () => { - getDataFromLocalStorageStub.returns('local_storage_data'); - - const result = readId(); - - expect(result).to.equal('local_storage_data'); - }); - - it('should return data from cookie when local storage data does not exist', () => { - getDataFromLocalStorageStub.returns(null); - getCookieStub.returns('cookie_data'); - - const result = readId(); - - expect(result).to.equal('cookie_data'); - }); - - it('should return null when neither local storage data nor cookie data exists', () => { - getDataFromLocalStorageStub.returns(null); - getCookieStub.returns(null); - - const result = readId(); - - expect(result).to.be.null; - }); - }); -}); diff --git a/test/spec/modules/pixfutureBidAdapter_spec.js b/test/spec/modules/pixfutureBidAdapter_spec.js index a236478c9b4..bdf40fbb06b 100644 --- a/test/spec/modules/pixfutureBidAdapter_spec.js +++ b/test/spec/modules/pixfutureBidAdapter_spec.js @@ -43,12 +43,12 @@ describe('PixFutureAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'pix_id': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/playdigoBidAdapter_spec.js b/test/spec/modules/playdigoBidAdapter_spec.js index 80fc3c96e81..62ae2796596 100644 --- a/test/spec/modules/playdigoBidAdapter_spec.js +++ b/test/spec/modules/playdigoBidAdapter_spec.js @@ -6,6 +6,16 @@ import { getUniqueIdentifierStr } from '../../../src/utils.js'; const bidder = 'playdigo' describe('PlaydigoBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -16,8 +26,9 @@ describe('PlaydigoBidAdapter', function () { } }, params: { - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -30,8 +41,9 @@ describe('PlaydigoBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -54,7 +66,8 @@ describe('PlaydigoBidAdapter', function () { }, params: { placementId: 'testNative' - } + }, + userIdAsEids } ]; @@ -78,8 +91,17 @@ describe('PlaydigoBidAdapter', function () { vendorData: {} }, refererInfo: { - referer: 'https://test.com' - } + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } + }, + timeout: 500 }; describe('isBidRequestValid', function () { @@ -105,6 +127,10 @@ describe('PlaydigoBidAdapter', function () { expect(serverRequest.method).to.equal('POST'); }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://server.playdigo.com/pbjs'); + }); + it('Returns general data valid', function () { let data = serverRequest.data; expect(data).to.be.an('object'); @@ -143,6 +169,7 @@ describe('PlaydigoBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -175,9 +202,10 @@ describe('PlaydigoBidAdapter', function () { }, params: { endpointId: 'testBanner', - } + }, + userIdAsEids } - ] + ]; let serverRequest = spec.buildRequests(bids, bidderRequest); @@ -190,6 +218,7 @@ describe('PlaydigoBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 3b433d34955..a6d91a6309b 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -21,7 +21,7 @@ import 'modules/currency.js'; // adServerCurrency test import 'modules/userId/index.js'; import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/schain.js'; import 'modules/paapi.js'; @@ -42,7 +42,6 @@ let CONFIG = { accountId: '1', enabled: true, bidders: ['appnexus'], - timeout: 1000, cacheMarkup: 2, endpoint: { p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', @@ -765,6 +764,7 @@ describe('S2S Adapter', function () { it('should set tmaxmax correctly when publisher has specified it', () => { const cfg = {...CONFIG}; + config.setConfig({s2sConfig: cfg}) // publisher has specified a tmaxmax in their setup const ortb2Fragments = { @@ -785,8 +785,9 @@ describe('S2S Adapter', function () { it('should set tmaxmax correctly when publisher has not specified it', () => { const cfg = {...CONFIG}; + config.setConfig({s2sConfig: cfg}) - // publisher has not specified a tmaxmax in their setup - so we should be + // publisher has not specified a tmaxmax in their setup - so we should be // falling back to requestBidsTimeout const ortb2Fragments = {}; const s2sCfg = {...REQUEST, cfg}; @@ -799,6 +800,46 @@ describe('S2S Adapter', function () { expect(req.ext.tmaxmax).to.eql(808); }); + describe('default tmax', () => { + [null, 3000].forEach(maxTimeout => { + describe(`when maxTimeout is ${maxTimeout}`, () => { + let cfg; + + beforeEach(() => { + cfg = {accountId: '1', endpoint: 'mock-endpoint', maxTimeout}; + config.setConfig({s2sConfig: cfg}); + maxTimeout = maxTimeout ?? s2sDefaultConfig.maxTimeout + }); + + it('should cap tmax to maxTimeout', () => { + adapter.callBids({...REQUEST, requestBidsTimeout: maxTimeout * 2, s2sConfig: cfg}, BID_REQUESTS, addBidResponse, done, ajax); + const req = JSON.parse(server.requests[0].requestBody); + expect(req.tmax).to.eql(maxTimeout); + }); + + it('should be set to 0.75 * requestTimeout, if lower than maxTimeout', () => { + adapter.callBids({...REQUEST, requestBidsTimeout: maxTimeout / 2}, BID_REQUESTS, addBidResponse, done, ajax); + const req = JSON.parse(server.requests[0].requestBody); + expect(req.tmax).to.eql(maxTimeout / 2 * 0.75); + }) + }) + }) + }) + + it('should set customHeaders correctly when publisher has provided it', () => { + let configWithCustomHeaders = utils.deepClone(CONFIG); + configWithCustomHeaders.customHeaders = { customHeader1: 'customHeader1Value' }; + config.setConfig({ s2sConfig: configWithCustomHeaders }); + + let reqWithNewConfig = utils.deepClone(REQUEST); + reqWithNewConfig.s2sConfig = configWithCustomHeaders; + + adapter.callBids(reqWithNewConfig, BID_REQUESTS, addBidResponse, done, ajax); + const reqHeaders = server.requests[0].requestHeaders + expect(reqHeaders.customHeader1).to.exist; + expect(reqHeaders.customHeader1).to.equal('customHeader1Value'); + }); + it('should block request if config did not define p1Consent URL in endpoint object config', function () { let badConfig = utils.deepClone(CONFIG); badConfig.endpoint = { noP1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' }; @@ -864,22 +905,6 @@ describe('S2S Adapter', function () { expect(requestBid.imp[0].video).to.exist; }); - it('should default video placement if not defined and instream', function () { - let ortb2Config = utils.deepClone(CONFIG); - ortb2Config.endpoint.p1Consent = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'; - - config.setConfig({ s2sConfig: ortb2Config }); - - let videoBid = utils.deepClone(VIDEO_REQUEST); - videoBid.ad_units[0].mediaTypes.video.context = 'instream'; - adapter.callBids(videoBid, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.imp[0].banner).to.not.exist; - expect(requestBid.imp[0].video).to.exist; - expect(requestBid.imp[0].video.placement).to.equal(1); - }); - it('converts video mediaType properties into openRTB format', function () { let ortb2Config = utils.deepClone(CONFIG); ortb2Config.endpoint.p1Consent = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'; @@ -893,7 +918,6 @@ describe('S2S Adapter', function () { const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.imp[0].banner).to.not.exist; expect(requestBid.imp[0].video).to.exist; - expect(requestBid.imp[0].video.placement).to.equal(1); expect(requestBid.imp[0].video.w).to.equal(640); expect(requestBid.imp[0].video.h).to.equal(480); expect(requestBid.imp[0].video.playerSize).to.be.undefined; @@ -1049,12 +1073,18 @@ describe('S2S Adapter', function () { it('adds device and app objects to request', function () { const _config = { s2sConfig: CONFIG, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, }; - config.setConfig(_config); - adapter.callBids(addFpdEnrichmentsToS2SRequest(REQUEST, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); + const s2sreq = addFpdEnrichmentsToS2SRequest({ + ...REQUEST, + ortb2Fragments: { + global: { + device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, + app: { bundle: 'com.test.app' }, + } + } + }, BID_REQUESTS) + adapter.callBids(s2sreq, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); sinon.assert.match(requestBid.device, { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC', @@ -1073,15 +1103,20 @@ describe('S2S Adapter', function () { p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' } }); - const _config = { s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, }; - config.setConfig(_config); - adapter.callBids(addFpdEnrichmentsToS2SRequest(REQUEST, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); + const s2sReq = addFpdEnrichmentsToS2SRequest({ + ...REQUEST, + ortb2Fragments: { + global: { + device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, + app: { bundle: 'com.test.app' }, + } + } + }, BID_REQUESTS) + adapter.callBids(s2sReq, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); sinon.assert.match(requestBid.device, { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC', @@ -1440,9 +1475,7 @@ describe('S2S Adapter', function () { it('adds device.w and device.h even if the config lacks a device object', function () { const _config = { s2sConfig: CONFIG, - app: { bundle: 'com.test.app' }, }; - config.setConfig(_config); adapter.callBids(addFpdEnrichmentsToS2SRequest(REQUEST, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); @@ -1450,10 +1483,6 @@ describe('S2S Adapter', function () { w: window.innerWidth, h: window.innerHeight }) - sinon.assert.match(requestBid.app, { - bundle: 'com.test.app', - publisher: { 'id': '1' } - }); expect(requestBid.imp[0].native.ver).to.equal('1.2'); }); @@ -1537,19 +1566,26 @@ describe('S2S Adapter', function () { it('adds site if app is not present', function () { const _config = { s2sConfig: CONFIG, - site: { - publisher: { - id: '1234', - domain: 'test.com' - }, - content: { - language: 'en' - } - } }; config.setConfig(_config); - adapter.callBids(addFpdEnrichmentsToS2SRequest(REQUEST, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); + const s2sReq = addFpdEnrichmentsToS2SRequest({ + ...REQUEST, + ortb2Fragments: { + global: { + site: { + publisher: { + id: '1234', + domain: 'test.com' + }, + content: { + language: 'en' + } + } + } + } + }, BID_REQUESTS); + adapter.callBids(s2sReq, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.site).to.exist.and.to.be.a('object'); expect(requestBid.site.publisher).to.exist.and.to.be.a('object'); @@ -1574,23 +1610,31 @@ describe('S2S Adapter', function () { it('site should not be present when app is present', function () { const _config = { s2sConfig: CONFIG, - app: { bundle: 'com.test.app' }, - site: { - publisher: { - id: '1234', - domain: 'test.com' - }, - content: { - language: 'en' - } - } }; config.setConfig(_config); - adapter.callBids(addFpdEnrichmentsToS2SRequest(REQUEST, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); + + const s2sReq = addFpdEnrichmentsToS2SRequest({ + ...REQUEST, + ortb2Fragments: { + global: { + app: { bundle: 'com.test.app' }, + site: { + publisher: { + id: '1234', + domain: 'test.com' + }, + content: { + language: 'en' + } + } + } + } + }, BID_REQUESTS) + adapter.callBids(s2sReq, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.site).to.not.exist; - expect(requestBid.app).to.exist.and.to.be.a('object'); + expect(requestBid.app.bundle).to.eql('com.test.app'); }); it('adds appnexus aliases to request', function () { @@ -1754,39 +1798,6 @@ describe('S2S Adapter', function () { }); }); - it('converts appnexus params to expected format for PBS', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }); - config.setConfig({ s2sConfig: s2sConfig }); - - Object.assign(BID_REQUESTS[0].bids[0].params, { - usePaymentRule: true, - keywords: { - foo: ['bar', 'baz'], - fizz: ['buzz'] - } - }) - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - const requestParams = requestBid.imp[0].ext.prebid.bidder; - expect(requestParams.appnexus).to.exist; - expect(requestParams.appnexus.placement_id).to.exist.and.to.equal(10433394); - expect(requestParams.appnexus.use_pmt_rule).to.exist.and.to.be.true; - expect(requestParams.appnexus.member).to.exist; - expect(requestParams.appnexus.keywords).to.exist.and.to.deep.equal([{ - key: 'foo', - value: ['bar', 'baz'] - }, { - key: 'fizz', - value: ['buzz'] - }]); - }); - describe('cookie sync', () => { let s2sConfig, bidderReqs; @@ -2004,15 +2015,21 @@ describe('S2S Adapter', function () { it('and overrides publisher and page', function () { config.setConfig({ s2sConfig: s2sConfig, - site: { - domain: 'nytimes.com', - page: 'http://www.nytimes.com', - publisher: { id: '2' } - }, - device: device }); - - adapter.callBids(addFpdEnrichmentsToS2SRequest(s2sBidRequest, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); + const s2sReq = addFpdEnrichmentsToS2SRequest({ + ...s2sBidRequest, + ortb2Fragments: { + global: { + site: { + domain: 'nytimes.com', + page: 'http://www.nytimes.com', + publisher: { id: '2' } + }, + device, + } + } + }, BID_REQUESTS); + adapter.callBids(s2sReq, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.site).to.exist.and.to.be.a('object'); @@ -2025,13 +2042,19 @@ describe('S2S Adapter', function () { it('and merges domain and page with the config site value', function () { config.setConfig({ s2sConfig: s2sConfig, - site: { - foo: 'bar' - }, - device: device }); - - adapter.callBids(addFpdEnrichmentsToS2SRequest(s2sBidRequest, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); + const s2sReq = addFpdEnrichmentsToS2SRequest({ + ...s2sBidRequest, + ortb2Fragments: { + global: { + site: { + foo: 'bar' + }, + device: device + } + } + }, BID_REQUESTS); + adapter.callBids(s2sReq, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.site).to.exist.and.to.be.a('object'); @@ -3524,12 +3547,15 @@ describe('S2S Adapter', function () { beforeEach(function () { fledgeStub = sinon.stub(); - config.setConfig({CONFIG}); + config.setConfig({ + s2sConfig: CONFIG, + }); bidderRequests = deepClone(BID_REQUESTS); - AU bidderRequests.forEach(req => { Object.assign(req, { - fledgeEnabled: true, + paapi: { + enabled: true + }, ortb2: { fpd: 1 } @@ -3537,7 +3563,7 @@ describe('S2S Adapter', function () { req.bids.forEach(bid => { Object.assign(bid, { ortb2Imp: { - fpd: 2 + fpd: 2, } }) }) @@ -3548,22 +3574,36 @@ describe('S2S Adapter', function () { function expectFledgeCalls() { const auctionId = bidderRequests[0].auctionId; - sinon.assert.calledWith(fledgeStub, sinon.match({auctionId, adUnitCode: AU, ortb2: bidderRequests[0].ortb2, ortb2Imp: bidderRequests[0].bids[0].ortb2Imp}), {config: {id: 1}}) - sinon.assert.calledWith(fledgeStub, sinon.match({auctionId, adUnitCode: AU, ortb2: undefined, ortb2Imp: undefined}), {config: {id: 2}}) + sinon.assert.calledWith(fledgeStub, sinon.match({auctionId, adUnitCode: AU, ortb2: bidderRequests[0].ortb2, ortb2Imp: bidderRequests[0].bids[0].ortb2Imp}), sinon.match({config: {id: 1}})) + sinon.assert.calledWith(fledgeStub, sinon.match({auctionId, adUnitCode: AU, ortb2: undefined, ortb2Imp: undefined}), sinon.match({config: {id: 2}})) } - it('calls addComponentAuction alongside addBidResponse', function () { + it('calls addPaapiConfig alongside addBidResponse', function () { adapter.callBids(request, bidderRequests, addBidResponse, done, ajax); server.requests[0].respond(200, {}, JSON.stringify(mergeDeep({}, RESPONSE_OPENRTB, FLEDGE_RESP))); expect(addBidResponse.called).to.be.true; expectFledgeCalls(); }); - it('calls addComponentAuction when there is no bid in the response', () => { + it('calls addPaapiConfig when there is no bid in the response', () => { adapter.callBids(request, bidderRequests, addBidResponse, done, ajax); server.requests[0].respond(200, {}, JSON.stringify(FLEDGE_RESP)); expect(addBidResponse.called).to.be.false; expectFledgeCalls(); + }); + + it('wraps call in runWithBidder', () => { + let fail = false; + fledgeStub.callsFake(({bidder}) => { + try { + expect(bidder).to.exist.and.to.eql(config.getCurrentBidder()); + } catch (e) { + fail = true; + } + }); + adapter.callBids(request, bidderRequests, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(FLEDGE_RESP)); + expect(fail).to.be.false; }) }); }); @@ -3712,181 +3752,135 @@ describe('S2S Adapter', function () { config.setConfig({ s2sConfig: options }); sinon.assert.calledOnce(logErrorSpy); }); + describe('vendor: appnexuspsp', () => { + it('should configure the s2sConfig object with appnexuspsp vendor defaults unless specified by user', function () { + const options = { + accountId: '123', + bidders: ['appnexus'], + defaultVendor: 'appnexuspsp', + timeout: 750 + }; - it('should configure the s2sConfig object with appnexuspsp vendor defaults unless specified by user', function () { - const options = { - accountId: '123', - bidders: ['appnexus'], - defaultVendor: 'appnexuspsp', - timeout: 750 - }; - - config.setConfig({ s2sConfig: options }); - sinon.assert.notCalled(logErrorSpy); - - let vendorConfig = config.getConfig('s2sConfig'); - expect(vendorConfig).to.have.property('accountId', '123'); - expect(vendorConfig).to.have.property('adapter', 'prebidServer'); - expect(vendorConfig.bidders).to.deep.equal(['appnexus']); - expect(vendorConfig.enabled).to.be.true; - expect(vendorConfig.endpoint).to.deep.equal({ - p1Consent: 'https://ib.adnxs.com/openrtb2/prebid', - noP1Consent: 'https://ib.adnxs-simple.com/openrtb2/prebid' - }); - expect(vendorConfig.syncEndpoint).to.deep.equal({ - p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync', - noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/cookie_sync' + config.setConfig({ s2sConfig: options }); + sinon.assert.notCalled(logErrorSpy); + + let vendorConfig = config.getConfig('s2sConfig'); + expect(vendorConfig).to.have.property('accountId', '123'); + expect(vendorConfig).to.have.property('adapter', 'prebidServer'); + expect(vendorConfig.bidders).to.deep.equal(['appnexus']); + expect(vendorConfig.enabled).to.be.true; + expect(vendorConfig.endpoint).to.deep.equal({ + p1Consent: 'https://ib.adnxs.com/openrtb2/prebid', + noP1Consent: 'https://ib.adnxs-simple.com/openrtb2/prebid' + }); + expect(vendorConfig.syncEndpoint).to.deep.equal({ + p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync', + noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/cookie_sync' + }); + expect(vendorConfig).to.have.property('timeout', 750); }); - expect(vendorConfig).to.have.property('timeout', 750); - }); - - it('should configure the s2sConfig object with rubicon vendor defaults unless specified by user', function () { - const options = { - accountId: 'abc', - bidders: ['rubicon'], - defaultVendor: 'rubicon', - timeout: 750 - }; + }) - config.setConfig({ s2sConfig: options }); - sinon.assert.notCalled(logErrorSpy); - - let vendorConfig = config.getConfig('s2sConfig'); - expect(vendorConfig).to.have.property('accountId', 'abc'); - expect(vendorConfig).to.have.property('adapter', 'prebidServer'); - expect(vendorConfig.bidders).to.deep.equal(['rubicon']); - expect(vendorConfig.enabled).to.be.true; - expect(vendorConfig.endpoint).to.deep.equal({ - p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', - noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction' - }); - expect(vendorConfig.syncEndpoint).to.deep.equal({ - p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', - noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync' - }); - expect(vendorConfig).to.have.property('timeout', 750); - }); + describe('vendor: rubicon', () => { + it('should configure the s2sConfig object with rubicon vendor defaults unless specified by user', function () { + const options = { + accountId: 'abc', + bidders: ['rubicon'], + defaultVendor: 'rubicon', + timeout: 750 + }; - it('should return proper defaults', function () { - const options = { - accountId: 'abc', - bidders: ['rubicon'], - defaultVendor: 'rubicon', - timeout: 750 - }; + config.setConfig({ s2sConfig: options }); + sinon.assert.notCalled(logErrorSpy); - config.setConfig({ s2sConfig: options }); - expect(config.getConfig('s2sConfig')).to.deep.equal({ - 'accountId': 'abc', - 'adapter': 'prebidServer', - 'bidders': ['rubicon'], - 'defaultVendor': 'rubicon', - 'enabled': true, - 'endpoint': { + let vendorConfig = config.getConfig('s2sConfig'); + expect(vendorConfig).to.have.property('accountId', 'abc'); + expect(vendorConfig).to.have.property('adapter', 'prebidServer'); + expect(vendorConfig.bidders).to.deep.equal(['rubicon']); + expect(vendorConfig.enabled).to.be.true; + expect(vendorConfig.endpoint).to.deep.equal({ p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction' - }, - 'syncEndpoint': { + }); + expect(vendorConfig.syncEndpoint).to.deep.equal({ p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync' - }, - 'timeout': 750 - }) - }); - - it('should return default adapterOptions if not set', function () { - config.setConfig({ - s2sConfig: { + }); + expect(vendorConfig).to.have.property('timeout', 750); + }); + it('should return proper defaults', function () { + const options = { accountId: 'abc', bidders: ['rubicon'], defaultVendor: 'rubicon', timeout: 750 - } - }); - expect(config.getConfig('s2sConfig')).to.deep.equal({ - enabled: true, - timeout: 750, - adapter: 'prebidServer', - accountId: 'abc', - bidders: ['rubicon'], - defaultVendor: 'rubicon', - endpoint: { - p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', - noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction' - }, - syncEndpoint: { - p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', - noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync' - }, - }) - }); - - it('should configure the s2sConfig object with openwrap vendor defaults unless specified by user', function () { - const options = { - accountId: '1234', - bidders: ['pubmatic'], - defaultVendor: 'openwrap' - }; + }; - config.setConfig({ s2sConfig: options }); - sinon.assert.notCalled(logErrorSpy); - - let vendorConfig = config.getConfig('s2sConfig'); - expect(vendorConfig).to.have.property('accountId', '1234'); - expect(vendorConfig).to.have.property('adapter', 'prebidServer'); - expect(vendorConfig.bidders).to.deep.equal(['pubmatic']); - expect(vendorConfig.enabled).to.be.true; - expect(vendorConfig.endpoint).to.deep.equal({ - p1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs', - noP1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs' + config.setConfig({ s2sConfig: options }); + expect(config.getConfig('s2sConfig')).to.deep.equal({ + 'accountId': 'abc', + 'adapter': 'prebidServer', + 'bidders': ['rubicon'], + 'defaultVendor': 'rubicon', + 'enabled': true, + 'endpoint': { + p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', + noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction' + }, + 'syncEndpoint': { + p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', + noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync' + }, + 'timeout': 750, + maxTimeout: 500, + }) }); - expect(vendorConfig).to.have.property('timeout', 500); - }); + }) - it('should return proper defaults', function () { - const options = { - accountId: '1234', - bidders: ['pubmatic'], - defaultVendor: 'openwrap', - timeout: 500 - }; + describe('vendor: openwrap', () => { + it('should configure the s2sConfig object with openwrap vendor defaults unless specified by user', function () { + const options = { + accountId: '1234', + bidders: ['pubmatic'], + defaultVendor: 'openwrap' + }; - config.setConfig({ s2sConfig: options }); - expect(config.getConfig('s2sConfig')).to.deep.equal({ - 'accountId': '1234', - 'adapter': 'prebidServer', - 'bidders': ['pubmatic'], - 'defaultVendor': 'openwrap', - 'enabled': true, - 'endpoint': { + config.setConfig({ s2sConfig: options }); + sinon.assert.notCalled(logErrorSpy); + + let vendorConfig = config.getConfig('s2sConfig'); + expect(vendorConfig).to.have.property('accountId', '1234'); + expect(vendorConfig).to.have.property('adapter', 'prebidServer'); + expect(vendorConfig.bidders).to.deep.equal(['pubmatic']); + expect(vendorConfig.enabled).to.be.true; + expect(vendorConfig.endpoint).to.deep.equal({ p1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs', noP1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs' - }, - 'timeout': 500 - }) - }); - - it('should return default adapterOptions if not set', function () { - config.setConfig({ - s2sConfig: { + }); + }); + it('should return proper defaults', function () { + const options = { accountId: '1234', bidders: ['pubmatic'], defaultVendor: 'openwrap', timeout: 500 - } + }; + + config.setConfig({ s2sConfig: options }); + expect(config.getConfig('s2sConfig')).to.deep.equal({ + 'accountId': '1234', + 'adapter': 'prebidServer', + 'bidders': ['pubmatic'], + 'defaultVendor': 'openwrap', + 'enabled': true, + 'endpoint': { + p1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs', + noP1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs' + }, + 'timeout': 500, + maxTimeout: 500, + }) }); - expect(config.getConfig('s2sConfig')).to.deep.equal({ - enabled: true, - timeout: 500, - adapter: 'prebidServer', - accountId: '1234', - bidders: ['pubmatic'], - defaultVendor: 'openwrap', - endpoint: { - p1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs', - noP1Consent: 'https://ow.pubmatic.com/openrtb2/auction?source=pbjs' - }, - }) }); it('should set adapterOptions', function () { diff --git a/test/spec/modules/prismaBidAdapter_spec.js b/test/spec/modules/prismaBidAdapter_spec.js index be1c16c9059..b0d068e5614 100644 --- a/test/spec/modules/prismaBidAdapter_spec.js +++ b/test/spec/modules/prismaBidAdapter_spec.js @@ -3,7 +3,7 @@ import {spec} from 'modules/prismaBidAdapter.js'; import {newBidder} from 'src/adapters/bidderFactory.js'; import {config} from 'src/config.js'; import * as utils from 'src/utils.js'; -import { requestBidsHook } from 'modules/consentManagement.js'; +import { requestBidsHook } from 'modules/consentManagementTcf.js'; describe('Prisma bid adapter tests', function () { const DISPLAY_BID_REQUEST = [{ diff --git a/test/spec/modules/proxistoreBidAdapter_spec.js b/test/spec/modules/proxistoreBidAdapter_spec.js index bcddb9e8b04..92e68f60b85 100644 --- a/test/spec/modules/proxistoreBidAdapter_spec.js +++ b/test/spec/modules/proxistoreBidAdapter_spec.js @@ -81,7 +81,7 @@ describe('ProxistoreBidAdapter', function () { it('should contain a valid url', function () { // has gdpr consent expect(request.url).equal(url.cookieBase); - // doens't have gpdr consent + // doens't have gdpr consent bidderRequest.gdprConsent.vendorData = null; request = spec.buildRequests([bid], bidderRequest); diff --git a/test/spec/modules/pubCircleBidAdapter_spec.js b/test/spec/modules/pubCircleBidAdapter_spec.js index 8aaa023ee1c..aa880c206fa 100644 --- a/test/spec/modules/pubCircleBidAdapter_spec.js +++ b/test/spec/modules/pubCircleBidAdapter_spec.js @@ -1,11 +1,21 @@ import { expect } from 'chai'; -import { spec } from '../../../modules/pubCircleBidAdapter'; +import { spec } from '../../../modules/pubCircleBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; -const bidder = 'pubcircle' +const bidder = 'pubcircle'; describe('PubCircleBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -16,8 +26,9 @@ describe('PubCircleBidAdapter', function () { } }, params: { - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -30,8 +41,9 @@ describe('PubCircleBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -53,8 +65,9 @@ describe('PubCircleBidAdapter', function () { } }, params: { - placementId: 'testNative', - } + placementId: 'testNative' + }, + userIdAsEids } ]; @@ -73,9 +86,20 @@ describe('PubCircleBidAdapter', function () { const bidderRequest = { uspConsent: '1---', - gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } }, timeout: 500 }; @@ -129,7 +153,7 @@ describe('PubCircleBidAdapter', function () { expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); expect(data.coppa).to.be.a('number'); - expect(data.gdpr).to.be.a('string'); + expect(data.gdpr).to.be.a('object'); expect(data.ccpa).to.be.a('string'); expect(data.tmax).to.be.a('number'); expect(data.placements).to.have.lengthOf(3); @@ -145,6 +169,7 @@ describe('PubCircleBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -170,8 +195,10 @@ describe('PubCircleBidAdapter', function () { serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); @@ -186,12 +213,38 @@ describe('PubCircleBidAdapter', function () { expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); + }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([], bidderRequest); + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) }); describe('interpretResponse', function () { @@ -395,5 +448,17 @@ describe('PubCircleBidAdapter', function () { expect(syncData[0].url).to.be.a('string') expect(syncData[0].url).to.equal('https://cs.pubcircle.ai/image?pbjs=1&ccpa_consent=1---&coppa=0') }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://cs.pubcircle.ai/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0') + }); }); }); diff --git a/test/spec/modules/pubgeniusBidAdapter_spec.js b/test/spec/modules/pubgeniusBidAdapter_spec.js index 86c8794dc4c..e1d579aaa4a 100644 --- a/test/spec/modules/pubgeniusBidAdapter_spec.js +++ b/test/spec/modules/pubgeniusBidAdapter_spec.js @@ -383,7 +383,6 @@ describe('pubGENIUS adapter', () => { w: 200, h: 100, startdelay: -1, - placement: 1, skip: 1, skipafter: 1, playbackmethod: [3, 4], diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js index 002b7fb3063..f77b167a3e9 100755 --- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js @@ -568,7 +568,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tgid).to.equal(15); expect(data.fmv).to.equal('floorModelTest'); expect(data.ft).to.equal(1); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); // slot 1 @@ -786,7 +786,7 @@ describe('pubmatic analytics adapter', function () { expect(data.pid).to.equal('1111'); expect(data.fmv).to.equal('floorModelTest'); expect(data.ft).to.equal(1); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); expect(data.tgid).to.equal(0); @@ -866,7 +866,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tgid).to.equal(0);// test group id should be between 0-15 else set to 0 expect(data.fmv).to.equal('floorModelTest'); expect(data.ft).to.equal(1); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); // slot 1 @@ -1434,7 +1434,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tst).to.equal(1519767016); expect(data.tgid).to.equal(15); expect(data.fmv).to.equal('floorModelTest'); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.ft).to.equal(1); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); @@ -1566,7 +1566,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tst).to.equal(1519767016); expect(data.tgid).to.equal(15); expect(data.fmv).to.equal('floorModelTest'); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.ft).to.equal(1); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); @@ -1657,8 +1657,55 @@ describe('pubmatic analytics adapter', function () { expect(data.origbidid).to.equal('partnerImpressionID-1'); }); + it('Logger: should use originalRequestId to find the bid', function() { + MOCK.BID_RESPONSE[1]['originalRequestId'] = '3bd4ebb1c900e2'; + MOCK.BID_RESPONSE[1]['requestId'] = '54d4ebb1c9003e'; + sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { + return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]] + }); + + config.setConfig({ + testGroupId: 15 + }); + + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); + events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); + events.emit(AUCTION_END, MOCK.AUCTION_END); + events.emit(SET_TARGETING, MOCK.SET_TARGETING); + events.emit(BID_WON, MOCK.BID_WON[0]); + events.emit(BID_WON, MOCK.BID_WON[1]); + + clock.tick(2000 + 1000); + expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker + let request = requests[2]; // logger is executed late, trackers execute first + expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); + let data = getLoggerJsonFromRequest(request.requestBody); + expect(data.s).to.be.an('array'); + expect(data.s.length).to.equal(2); + + // slot 1 + expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); + expect(data.s[0].ps[0].origbidid).to.equal('partnerImpressionID-1'); + + // slot 2 + expect(data.s[1].ps[0].bidid).to.equal('54d4ebb1c9003e'); + expect(data.s[1].ps[0].origbidid).to.equal('partnerImpressionID-2'); + + // tracker slot1 + let firstTracker = requests[0].url; + expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); + data = {}; + firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); + expect(data.bidid).to.equal('2ecff0db240757'); + expect(data.origbidid).to.equal('partnerImpressionID-1'); + }); + it('Logger: best case + win tracker. Log bidId when partnerimpressionid is missing', function() { delete MOCK.BID_RESPONSE[1]['partnerImpId']; + MOCK.BID_RESPONSE[1]['requestId'] = '3bd4ebb1c900e2'; MOCK.BID_RESPONSE[1]['prebidBidId'] = 'Prebid-bid-id-1'; sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]] diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 745def57f4e..82715ac518a 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -2948,7 +2948,7 @@ describe('PubMatic adapter', function () { bidRequest[0].ortb2Imp = { ext: { ae: 1 } }; - const req = spec.buildRequests(bidRequest, { ...bidRequest, fledgeEnabled: false }); + const req = spec.buildRequests(bidRequest, { ...bidRequest, paapi: {enabled: false} }); let data = JSON.parse(req.data); if (data.imp[0].ext) { expect(data.imp[0].ext).to.not.have.property('ae'); @@ -2961,7 +2961,7 @@ describe('PubMatic adapter', function () { bidRequest[0].ortb2Imp = { ext: { ae: 1 } }; - const req = spec.buildRequests(bidRequest, { ...bidRequest, fledgeEnabled: true }); + const req = spec.buildRequests(bidRequest, { ...bidRequest, paapi: {enabled: true} }); let data = JSON.parse(req.data); expect(data.imp[0].ext.ae).to.equal(1); }); @@ -3786,9 +3786,9 @@ describe('PubMatic adapter', function () { response = spec.interpretResponse({ body: bidResponse }, bidRequest); it('should return FLEDGE auction_configs alongside bids', function () { expect(response).to.have.property('bids'); - expect(response).to.have.property('fledgeAuctionConfigs'); - expect(response.fledgeAuctionConfigs.length).to.equal(1); - expect(response.fledgeAuctionConfigs[0].bidId).to.equal('test_bid_id'); + expect(response).to.have.property('paapi'); + expect(response.paapi.length).to.equal(1); + expect(response.paapi[0].bidId).to.equal('test_bid_id'); }); }); @@ -4084,6 +4084,46 @@ describe('PubMatic adapter', function () { }) }); } + + describe('Banner Request param battr checking', function() { + it('should add battr params to bannerObj if present in ortb2Imp.banner', function() { + let originalBidRequests = utils.deepClone(bidRequests); + let bannerObj = utils.deepClone(originalBidRequests[0].ortb2Imp.banner); + originalBidRequests[0].ortb2Imp.banner = Object.assign(bannerObj, { + battr: [1, 2] + }); + + const req = spec.buildRequests(originalBidRequests, { + auctionId: 'new-auction-id' + }); + let data = JSON.parse(req.data); + expect(data.imp[0]['banner']['battr']).to.exist.and.to.be.an('array'); + expect(data.imp[0]['banner']['battr'][0]).to.equal(originalBidRequests[0].ortb2Imp.banner['battr'][0]); + expect(data.imp[0]['banner']['battr'][1]).to.equal(originalBidRequests[0].ortb2Imp.banner['battr'][1]); + }); + + it('should not add battr params to bannerObj if not present in ortb2Imp.banner', function() { + const req = spec.buildRequests(bidRequests, { + auctionId: 'new-auction-id' + }); + let data = JSON.parse(req.data); + expect(data.imp[0]['banner']['battr']).to.equal(undefined); + }); + + it('should not add battr params if _checkParamDataType returns undefined (Mismatch data type)', function() { + let originalBidRequests = utils.deepClone(bidRequests); + let bannerObj = utils.deepClone(originalBidRequests[0].ortb2Imp.banner); + originalBidRequests[0].ortb2Imp.banner = Object.assign(bannerObj, { + battr: 1 + }); + + const req = spec.buildRequests(originalBidRequests, { + auctionId: 'new-auction-id' + }); + let data = JSON.parse(req.data); + expect(data.imp[0]['banner']['battr']).to.equal(undefined); + }); + }); }); if (FEATURES.VIDEO) { diff --git a/test/spec/modules/pubxBidAdapter_spec.js b/test/spec/modules/pubxBidAdapter_spec.js index b387264bf91..38efccac2a6 100644 --- a/test/spec/modules/pubxBidAdapter_spec.js +++ b/test/spec/modules/pubxBidAdapter_spec.js @@ -26,10 +26,10 @@ describe('pubxAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js b/test/spec/modules/pubxaiAnalyticsAdapter_spec.js index 9af1ef185e1..237a2d32d54 100644 --- a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubxaiAnalyticsAdapter_spec.js @@ -1,675 +1,731 @@ -import pubxaiAnalyticsAdapter, {getBrowser, getDeviceType, getOS} from 'modules/pubxaiAnalyticsAdapter.js'; -import {expect} from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import * as utils from 'src/utils.js'; -import {server} from 'test/mocks/xhr.js'; -import {getGptSlotInfoForAdUnitCode} from '../../../libraries/gptUtils/gptUtils.js'; +/* globals describe, beforeEach, afterEach, sinon */ +import { expect } from 'chai'; +import { getGptSlotInfoForAdUnitCode } from 'libraries/gptUtils/gptUtils.js'; +import { getDeviceType, getBrowser, getOS } from 'libraries/userAgentUtils'; +import pubxaiAnalyticsAdapter, { + auctionCache, +} from 'modules/pubxaiAnalyticsAdapter.js'; import { EVENTS } from 'src/constants.js'; +import adapterManager from 'src/adapterManager.js'; +import { getWindowLocation } from 'src/utils.js'; +import { getGlobal } from 'src/prebidGlobal.js'; +import * as events from 'src/events.js' -let events = require('src/events'); +const readBlobSafariCompat = (blob) => { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result) + reader.onerror = reject + reader.readAsText(blob) + }) +} -describe('pubxai analytics adapter', function() { - beforeEach(function() { +describe('pubxai analytics adapter', () => { + beforeEach(() => { + getGlobal().refreshUserIds() sinon.stub(events, 'getEvents').returns([]); }); - afterEach(function() { + afterEach(() => { events.getEvents.restore(); }); - describe('track', function() { + describe('track', () => { let initOptions = { samplingRate: '1', - pubxId: '6c415fc0-8b0e-4cf5-be73-01526a4db625' + pubxId: '6c415fc0-8b0e-4cf5-be73-01526a4db625', }; - let location = utils.getWindowLocation(); - let storage = window.top['sessionStorage']; + let originalVS; + + let location = getWindowLocation(); + + const replaceProperty = (obj, params) => { + let strObj = JSON.stringify(obj); + params.forEach(({ field, updated, replaced }) => { + strObj = strObj.replace( + new RegExp('"' + field + '":' + replaced, 'g'), + '"' + field + '":' + updated + ); + }); + return JSON.parse(strObj); + }; let prebidEvent = { - 'auctionInit': { - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'timestamp': 1603865707180, - 'auctionStatus': 'inProgress', - 'adUnits': [{ - 'code': '/19968336/header-bid-tag-1', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 + auctionInit: { + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + timestamp: 1603865707180, + auctionStatus: 'inProgress', + adUnits: [ + { + code: '/19968336/header-bid-tag-1', + mediaTypes: { + banner: { + sizes: [[300, 250]], + }, }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' - } - }], - 'sizes': [ - [ - 300, - 250 - ] - ], - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294' - }], - 'adUnitCodes': [ - '/19968336/header-bid-tag-1' + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 13144370, + }, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + floorData: { + skipped: false, + skipRate: 0, + modelVersion: 'test model 1.0', + location: 'fetch', + floorProvider: 'PubXFloorProvider', + fetchStatus: 'success', + }, + }, + ], + sizes: [[300, 250]], + transactionId: '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', + }, ], - 'bidderRequests': [{ - 'bidderCode': 'appnexus', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderRequestId': '184cbc05bb90ba', - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' + adUnitCodes: ['/19968336/header-bid-tag-1'], + bidderRequests: [ + { + bidderCode: 'appnexus', + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + bidderRequestId: '184cbc05bb90ba', + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 13144370, + }, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + floorData: { + skipped: false, + skipRate: 0, + modelVersion: 'test model 1.0', + location: 'fetch', + floorProvider: 'PubXFloorProvider', + fetchStatus: 'success', + }, + mediaTypes: { + banner: { + sizes: [[300, 250]], + }, + }, + adUnitCode: '/19968336/header-bid-tag-1', + transactionId: '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', + sizes: [[300, 250]], + bidId: '248f9a4489835e', + bidderRequestId: '184cbc05bb90ba', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0, + }, + ], + ortb2: { + device: { + ext: { + cdep: true, + }, + }, }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } + auctionStart: 1603865707180, + timeout: 1000, + refererInfo: { + referer: 'http://local-pnh.net:8080/stream/', + reachedTop: true, + isAmp: false, + numIframes: 0, + stack: ['http://local-pnh.net:8080/stream/'], + canonicalUrl: null, }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '248f9a4489835e', - 'bidderRequestId': '184cbc05bb90ba', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }], - 'auctionStart': 1603865707180, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://local-pnh.net:8080/stream/', - 'reachedTop': true, - 'isAmp': false, - 'numIframes': 0, - 'stack': [ - 'http://local-pnh.net:8080/stream/' - ], - 'canonicalUrl': null + start: 1603865707182, }, - 'start': 1603865707182 - }], - 'noBids': [], - 'bidsReceived': [], - 'winningBids': [], - 'timeout': 1000, - 'config': { - 'samplingRate': '1', - 'pubxId': '6c415fc0-8b0e-4cf5-be73-01526a4db625' - } + ], + noBids: [], + bidsReceived: [], + winningBids: [], + timeout: 1000, + config: { + samplingRate: '1', + pubxId: '6c415fc0-8b0e-4cf5-be73-01526a4db625', + }, }, - 'bidRequested': { - 'bidderCode': 'appnexus', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderRequestId': '184cbc05bb90ba', - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' + bidRequested: { + bidderCode: 'appnexus', + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + bidderRequestId: '184cbc05bb90ba', + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 13144370, + }, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + floorData: { + skipped: false, + skipRate: 0, + modelVersion: 'test model 1.0', + location: 'fetch', + floorProvider: 'PubXFloorProvider', + fetchStatus: 'success', + }, + mediaTypes: { + banner: { + sizes: [[300, 250]], + }, + }, + adUnitCode: '/19968336/header-bid-tag-1', + transactionId: '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', + sizes: [[300, 250]], + bidId: '248f9a4489835e', + bidderRequestId: '184cbc05bb90ba', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0, }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } + ], + ortb2: { + device: { + ext: { + cdep: true, + }, }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '248f9a4489835e', - 'bidderRequestId': '184cbc05bb90ba', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }], - 'auctionStart': 1603865707180, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://local-pnh.net:8080/stream/', - 'reachedTop': true, - 'isAmp': false, - 'numIframes': 0, - 'stack': [ - 'http://local-pnh.net:8080/stream/' - ], - 'canonicalUrl': null }, - 'start': 1603865707182 + auctionStart: 1603865707180, + timeout: 1000, + refererInfo: { + referer: 'http://local-pnh.net:8080/stream/', + reachedTop: true, + isAmp: false, + numIframes: 0, + stack: ['http://local-pnh.net:8080/stream/'], + canonicalUrl: null, + }, + start: 1603865707182, }, - 'bidTimeout': [], - 'bidResponse': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '32780c4bc382cb', - 'requestId': '248f9a4489835e', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'appnexus': { - 'buyerMemberId': 9325 + bidTimeout: [], + bidResponse: { + bidderCode: 'appnexus', + width: 300, + height: 250, + statusMessage: 'Bid available', + adId: '32780c4bc382cb', + requestId: '248f9a4489835e', + mediaType: 'banner', + source: 'client', + cpm: 0.5, + creativeId: 96846035, + currency: 'USD', + netRevenue: true, + ttl: 300, + adUnitCode: '/19968336/header-bid-tag-1', + appnexus: { + buyerMemberId: 9325, }, - 'meta': { - 'advertiserId': 2529885 + meta: { + advertiserId: 2529885, }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true + ad: '', + originalCpm: 0.5, + originalCurrency: 'USD', + floorData: { + fetchStatus: 'success', + floorProvider: 'PubXFloorProvider', + location: 'fetch', + modelVersion: 'test model 1.0', + skipRate: 0, + skipped: false, + floorValue: 0.4, + floorRule: '/19968336/header-bid-tag-1|banner', + floorCurrency: 'USD', + cpmAfterAdjustments: 0.5, + enforcements: { + enforceJS: true, + enforcePBS: false, + floorDeals: true, + bidAdjustment: true, + }, + matchedFields: { + gptSlot: '/19968336/header-bid-tag-1', + mediaType: 'banner', }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'bidder': 'appnexus', - 'timeToRespond': 267, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '0.50', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '32780c4bc382cb', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + responseTimestamp: 1616654313071, + requestTimestamp: 1616654312804, + bidder: 'appnexus', + timeToRespond: 267, + pbLg: '0.50', + pbMg: '0.50', + pbHg: '0.50', + pbAg: '0.50', + pbDg: '0.50', + pbCg: '0.50', + size: '300x250', + adserverTargeting: { + hb_bidder: 'appnexus', + hb_adid: '32780c4bc382cb', + hb_pb: '0.50', + hb_size: '300x250', + hb_source: 'client', + hb_format: 'banner', }, }, - 'auctionEnd': { - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'timestamp': 1616654312804, - 'auctionEnd': 1616654313090, - 'auctionStatus': 'completed', - 'adUnits': [{ - 'code': '/19968336/header-bid-tag-1', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } + auctionEnd: { + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + timestamp: 1616654312804, + auctionEnd: 1616654313090, + auctionStatus: 'completed', + adUnits: [ + { + code: '/19968336/header-bid-tag-1', + mediaTypes: { + banner: { + sizes: [[300, 250]], + }, + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 13144370, + }, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + floorData: { + skipped: false, + skipRate: 0, + modelVersion: 'test model 1.0', + location: 'fetch', + floorProvider: 'PubXFloorProvider', + fetchStatus: 'success', + }, + }, + ], + sizes: [[300, 250]], + transactionId: '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', }, - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 + ], + adUnitCodes: ['/19968336/header-bid-tag-1'], + bidderRequests: [ + { + bidderCode: 'appnexus', + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + bidderRequestId: '184cbc05bb90ba', + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 13144370, + }, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + floorData: { + skipped: false, + skipRate: 0, + modelVersion: 'test model 1.0', + location: 'fetch', + floorProvider: 'PubXFloorProvider', + fetchStatus: 'success', + }, + mediaTypes: { + banner: { + sizes: [[300, 250]], + }, + }, + adUnitCode: '/19968336/header-bid-tag-1', + transactionId: '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', + sizes: [[300, 250]], + bidId: '248f9a4489835e', + bidderRequestId: '184cbc05bb90ba', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0, + }, + ], + ortb2: { + device: { + ext: { + cdep: true, + }, + }, }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' - } - }], - 'sizes': [ - [ - 300, - 250 - ] - ], - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294' - }], - 'adUnitCodes': [ - '/19968336/header-bid-tag-1' + auctionStart: 1603865707180, + timeout: 1000, + refererInfo: { + referer: 'http://local-pnh.net:8080/stream/', + reachedTop: true, + isAmp: false, + numIframes: 0, + stack: ['http://local-pnh.net:8080/stream/'], + canonicalUrl: null, + }, + start: 1603865707182, + }, ], - 'bidderRequests': [{ - 'bidderCode': 'appnexus', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderRequestId': '184cbc05bb90ba', - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 + noBids: [], + bidsReceived: [ + { + bidderCode: 'appnexus', + width: 300, + height: 250, + statusMessage: 'Bid available', + adId: '32780c4bc382cb', + requestId: '248f9a4489835e', + mediaType: 'banner', + source: 'client', + cpm: 0.5, + creativeId: 96846035, + currency: 'USD', + netRevenue: true, + ttl: 300, + adUnitCode: '/19968336/header-bid-tag-1', + appnexus: { + buyerMemberId: 9325, }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' + meta: { + advertiserId: 2529885, }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } + ad: '', + originalCpm: 0.5, + originalCurrency: 'USD', + floorData: { + fetchStatus: 'success', + floorProvider: 'PubXFloorProvider', + location: 'fetch', + modelVersion: 'test model 1.0', + skipRate: 0, + skipped: false, + floorValue: 0.4, + floorRule: '/19968336/header-bid-tag-1|banner', + floorCurrency: 'USD', + cpmAfterAdjustments: 0.5, + enforcements: { + enforceJS: true, + enforcePBS: false, + floorDeals: true, + bidAdjustment: true, + }, + matchedFields: { + gptSlot: '/19968336/header-bid-tag-1', + mediaType: 'banner', + }, }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '248f9a4489835e', - 'bidderRequestId': '184cbc05bb90ba', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }], - 'auctionStart': 1603865707180, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://local-pnh.net:8080/stream/', - 'reachedTop': true, - 'isAmp': false, - 'numIframes': 0, - 'stack': [ - 'http://local-pnh.net:8080/stream/' - ], - 'canonicalUrl': null - }, - 'start': 1603865707182 - }], - 'noBids': [], - 'bidsReceived': [{ - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '32780c4bc382cb', - 'requestId': '248f9a4489835e', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + responseTimestamp: 1616654313071, + requestTimestamp: 1616654312804, + bidder: 'appnexus', + timeToRespond: 267, + pbLg: '0.50', + pbMg: '0.50', + pbHg: '0.50', + pbAg: '0.50', + pbDg: '0.50', + pbCg: '0.50', + size: '300x250', + adserverTargeting: { + hb_bidder: 'appnexus', + hb_adid: '32780c4bc382cb', + hb_pb: '0.50', + hb_size: '300x250', + hb_source: 'client', + hb_format: 'banner', }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'bidder': 'appnexus', - 'timeToRespond': 267, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '0.50', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '32780c4bc382cb', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' + status: 'rendered', + params: [ + { + placementId: 13144370, + }, + ], }, - 'status': 'rendered', - 'params': [{ - 'placementId': 13144370 - }] - }], - 'winningBids': [], - 'timeout': 1000 + ], + winningBids: [], + timeout: 1000, }, - 'bidWon': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '32780c4bc382cb', - 'requestId': '248f9a4489835e', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'appnexus': { - 'buyerMemberId': 9325 + bidWon: { + bidderCode: 'appnexus', + width: 300, + height: 250, + statusMessage: 'Bid available', + adId: '32780c4bc382cb', + requestId: '248f9a4489835e', + mediaType: 'banner', + source: 'client', + cpm: 0.5, + creativeId: 96846035, + currency: 'USD', + netRevenue: true, + ttl: 300, + adUnitCode: '/19968336/header-bid-tag-1', + appnexus: { + buyerMemberId: 9325, }, - 'meta': { - 'advertiserId': 2529885 + meta: { + advertiserId: 2529885, }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true + ad: '', + originalCpm: 0.5, + originalCurrency: 'USD', + floorData: { + fetchStatus: 'success', + floorProvider: 'PubXFloorProvider', + location: 'fetch', + modelVersion: 'test model 1.0', + skipRate: 0, + skipped: false, + floorValue: 0.4, + floorRule: '/19968336/header-bid-tag-1|banner', + floorCurrency: 'USD', + cpmAfterAdjustments: 0.5, + enforcements: { + enforceJS: true, + enforcePBS: false, + floorDeals: true, + bidAdjustment: true, + }, + matchedFields: { + gptSlot: '/19968336/header-bid-tag-1', + mediaType: 'banner', }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'bidder': 'appnexus', - 'timeToRespond': 267, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '0.50', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '32780c4bc382cb', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + responseTimestamp: 1616654313071, + requestTimestamp: 1616654312804, + bidder: 'appnexus', + timeToRespond: 267, + pbLg: '0.50', + pbMg: '0.50', + pbHg: '0.50', + pbAg: '0.50', + pbDg: '0.50', + pbCg: '0.50', + size: '300x250', + adserverTargeting: { + hb_bidder: 'appnexus', + hb_adid: '32780c4bc382cb', + hb_pb: '0.50', + hb_size: '300x250', + hb_source: 'client', + hb_format: 'banner', }, - 'status': 'rendered', - 'params': [{ - 'placementId': 13144370 - }] - }, - 'pageDetail': { - 'host': location.host, - 'path': location.pathname, - 'search': location.search + status: 'rendered', + params: [ + { + placementId: 13144370, + }, + ], }, - 'pmcDetail': { - 'bidDensity': storage.getItem('pbx:dpbid'), - 'maxBid': storage.getItem('pbx:mxbid'), - 'auctionId': storage.getItem('pbx:aucid') - } }; let expectedAfterBid = { - 'bids': [{ - 'bidderCode': 'appnexus', - 'bidId': '248f9a4489835e', - 'adUnitCode': '/19968336/header-bid-tag-1', - 'gptSlotCode': getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || null, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'sizes': '300x250', - 'renderStatus': 2, - 'requestTimestamp': 1616654312804, - 'creativeId': 96846035, - 'currency': 'USD', - 'cpm': 0.5, - 'netRevenue': true, - 'mediaType': 'banner', - 'statusMessage': 'Bid available', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true + bids: [ + { + bidderCode: 'appnexus', + bidId: '248f9a4489835e', + adUnitCode: '/19968336/header-bid-tag-1', + gptSlotCode: + getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || + null, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + sizes: '300x250', + renderStatus: 2, + requestTimestamp: 1616654312804, + creativeId: 96846035, + currency: 'USD', + cpm: 0.5, + netRevenue: true, + mediaType: 'banner', + statusMessage: 'Bid available', + floorData: { + fetchStatus: 'success', + floorProvider: 'PubXFloorProvider', + location: 'fetch', + modelVersion: 'test model 1.0', + skipRate: 0, + skipped: false, + floorValue: 0.4, + floorRule: '/19968336/header-bid-tag-1|banner', + floorCurrency: 'USD', + cpmAfterAdjustments: 0.5, + enforcements: { + enforceJS: true, + enforcePBS: false, + floorDeals: true, + bidAdjustment: true, + }, + matchedFields: { + gptSlot: '/19968336/header-bid-tag-1', + mediaType: 'banner', + }, }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } + placementId: null, + timeToRespond: 267, + source: 'client', + responseTimestamp: 1616654313071, }, - 'timeToRespond': 267, - 'responseTimestamp': 1616654313071 - }], - 'pageDetail': { - 'host': location.host, - 'path': location.pathname, - 'search': location.search, - 'adUnits': [ - '/19968336/header-bid-tag-1' - ] + ], + auctionDetail: { + adUnitCodes: ['/19968336/header-bid-tag-1'], + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + refreshRank: 0, + timestamp: 1616654312804, + }, + pageDetail: { + host: location.host, + path: location.pathname, + search: location.search, }, - 'floorDetail': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false + floorDetail: { + fetchStatus: 'success', + floorProvider: 'PubXFloorProvider', + location: 'fetch', + modelVersion: 'test model 1.0', + skipRate: 0, + skipped: false, }, - 'deviceDetail': { - 'platform': navigator.platform, - 'deviceType': getDeviceType(), - 'deviceOS': getOS(), - 'browser': getBrowser() + deviceDetail: { + platform: navigator.platform, + deviceType: getDeviceType(), + deviceOS: getOS(), + browser: getBrowser(), + cdep: true, }, - 'pmcDetail': { - 'bidDensity': storage.getItem('pbx:dpbid'), - 'maxBid': storage.getItem('pbx:mxbid'), - 'auctionId': storage.getItem('pbx:aucid') + userDetail: { + userIdTypes: Object.keys(getGlobal().getUserIds?.() || {}), + }, + consentDetail: { + consentTypes: Object.keys(getGlobal().getConsentMetadata?.() || {}), + }, + pmacDetail: {}, + initOptions: { + ...initOptions, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', }, - 'initOptions': initOptions }; let expectedAfterBidWon = { - 'winningBid': { - 'adUnitCode': '/19968336/header-bid-tag-1', - 'gptSlotCode': getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || null, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderCode': 'appnexus', - 'bidId': '248f9a4489835e', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true + winningBid: { + adUnitCode: '/19968336/header-bid-tag-1', + gptSlotCode: + getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || + null, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + bidderCode: 'appnexus', + bidId: '248f9a4489835e', + cpm: 0.5, + creativeId: 96846035, + currency: 'USD', + floorData: { + fetchStatus: 'success', + floorProvider: 'PubXFloorProvider', + location: 'fetch', + modelVersion: 'test model 1.0', + skipRate: 0, + skipped: false, + floorValue: 0.4, + floorRule: '/19968336/header-bid-tag-1|banner', + floorCurrency: 'USD', + cpmAfterAdjustments: 0.5, + enforcements: { + enforceJS: true, + enforcePBS: false, + floorDeals: true, + bidAdjustment: true, + }, + matchedFields: { + gptSlot: '/19968336/header-bid-tag-1', + mediaType: 'banner', }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } }, - 'floorProvider': 'PubXFloorProvider', - 'floorFetchStatus': 'success', - 'floorLocation': 'fetch', - 'floorModelVersion': 'test model 1.0', - 'floorSkipRate': 0, - 'isFloorSkipped': false, - 'isWinningBid': true, - 'mediaType': 'banner', - 'netRevenue': true, - 'placementId': 13144370, - 'renderedSize': '300x250', - 'renderStatus': 4, - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'status': 'rendered', - 'statusMessage': 'Bid available', - 'timeToRespond': 267 + adServerData: {}, + floorProvider: 'PubXFloorProvider', + floorFetchStatus: 'success', + floorLocation: 'fetch', + floorModelVersion: 'test model 1.0', + floorSkipRate: 0, + isFloorSkipped: false, + isWinningBid: true, + mediaType: 'banner', + netRevenue: true, + placementId: 13144370, + renderedSize: '300x250', + sizes: '300x250', + renderStatus: 4, + responseTimestamp: 1616654313071, + requestTimestamp: 1616654312804, + status: 'rendered', + statusMessage: 'Bid available', + timeToRespond: 267, + source: 'client', + }, + auctionDetail: { + adUnitCodes: ['/19968336/header-bid-tag-1'], + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + refreshRank: 0, + timestamp: 1616654312804, + }, + pageDetail: { + host: location.host, + path: location.pathname, + search: location.search, }, - 'pageDetail': { - 'host': location.host, - 'path': location.pathname, - 'search': location.search + floorDetail: { + fetchStatus: 'success', + floorProvider: 'PubXFloorProvider', + location: 'fetch', + modelVersion: 'test model 1.0', + skipRate: 0, + skipped: false, }, - 'deviceDetail': { - 'platform': navigator.platform, - 'deviceType': getDeviceType(), - 'deviceOS': getOS(), - 'browser': getBrowser() + deviceDetail: { + platform: navigator.platform, + deviceType: getDeviceType(), + deviceOS: getOS(), + browser: getBrowser(), + cdep: true, }, - 'initOptions': initOptions - } + userDetail: { + userIdTypes: Object.keys(getGlobal().getUserIds?.() || {}), + }, + consentDetail: { + consentTypes: Object.keys(getGlobal().getConsentMetadata?.() || {}), + }, + pmacDetail: {}, + initOptions: { + ...initOptions, + auctionId: 'bc3806e4-873e-453c-8ae5-204f35e923b4', + }, + }; adapterManager.registerAnalyticsAdapter({ code: 'pubxai', - adapter: pubxaiAnalyticsAdapter + adapter: pubxaiAnalyticsAdapter, }); - beforeEach(function() { + beforeEach(() => { adapterManager.enableAnalytics({ provider: 'pubxai', - options: initOptions + options: initOptions, + }); + sinon.stub(navigator, 'sendBeacon').returns(true); + originalVS = document.visibilityState; + document['__defineGetter__']('visibilityState', function () { + return 'hidden'; }); }); - afterEach(function() { + afterEach(() => { pubxaiAnalyticsAdapter.disableAnalytics(); + navigator.sendBeacon.restore(); + delete auctionCache['bc3806e4-873e-453c-8ae5-204f35e923b4']; + delete auctionCache['auction2']; + document['__defineGetter__']('visibilityState', function () { + return originalVS; + }); }); - it('builds and sends auction data', function() { + it('builds and sends auction data', async () => { // Step 1: Send auction init event events.emit(EVENTS.AUCTION_INIT, prebidEvent['auctionInit']); @@ -685,20 +741,331 @@ describe('pubxai analytics adapter', function() { // Step 5: Send auction end event events.emit(EVENTS.AUCTION_END, prebidEvent['auctionEnd']); - expect(server.requests.length).to.equal(1); - - let realAfterBid = JSON.parse(server.requests[0].requestBody); + // Simulate "navigate away" behaviour + document.dispatchEvent(new Event('visibilitychange')); - expect(realAfterBid).to.deep.equal(expectedAfterBid); + expect(navigator.sendBeacon.callCount).to.equal(0); // Step 6: Send auction bid won event events.emit(EVENTS.BID_WON, prebidEvent['bidWon']); - expect(server.requests.length).to.equal(2); + // Simulate end of session + document.dispatchEvent(new Event('visibilitychange')); + + expect(navigator.sendBeacon.callCount).to.equal(2); + + for (const [index, arg] of navigator.sendBeacon.args.entries()) { + const [expectedUrl, expectedData] = arg; + const parsedUrl = new URL(expectedUrl); + expect(parsedUrl.pathname).to.equal( + ['/analytics/bidwon', '/analytics/auction'][index] + ); + expect(Object.fromEntries(parsedUrl.searchParams)).to.deep.equal({ + auctionTimestamp: '1616654312804', + pubxaiAnalyticsVersion: 'v2.0.0', + prebidVersion: '$prebid.version$', + }); + expect(expectedData.type).to.equal('text/json'); + expect(JSON.parse(await readBlobSafariCompat(expectedData))).to.deep.equal([ + [expectedAfterBidWon, expectedAfterBid][index], + ]); + } + }); + + it('auction with no bids', async () => { + // Step 1: Send auction init event + events.emit(EVENTS.AUCTION_INIT, prebidEvent['auctionInit']); + + // Step 2: Send bid requested event + events.emit(EVENTS.BID_REQUESTED, prebidEvent['bidRequested']); + + // Step 3: Send bid time out event + events.emit(EVENTS.BID_TIMEOUT, prebidEvent['bidTimeout']); + + // Simulate "navigate away" behaviour + document.dispatchEvent(new Event('visibilitychange')); + + // Step 4: check the number of calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(0); + + // Step 5: Send auction end event + events.emit(EVENTS.AUCTION_END, prebidEvent['auctionEnd']); + + // Simulate end of session + document.dispatchEvent(new Event('visibilitychange')); + + // Step 6: check the number of calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(1); + + // Step 7: check the pathname of the calls is correct (sent only to the auction endpoint) + const [expectedUrl, expectedData] = navigator.sendBeacon.args[0]; + const parsedUrl = new URL(expectedUrl); + expect(parsedUrl.pathname).to.equal('/analytics/auction'); + + // Step 8: check that the meta information in the call is correct + expect(Object.fromEntries(parsedUrl.searchParams)).to.deep.equal({ + auctionTimestamp: '1616654312804', + pubxaiAnalyticsVersion: 'v2.0.0', + prebidVersion: '$prebid.version$', + }); + + // Step 9: check that the data sent in the request is correct + expect(expectedData.type).to.equal('text/json'); + expect(JSON.parse(await readBlobSafariCompat(expectedData))).to.deep.equal([ + { + ...expectedAfterBid, + bids: [], + }, + ]); + }); + + it('2 concurrent auctions', async () => { + // Step 1: Send auction init event for auction 1 + events.emit(EVENTS.AUCTION_INIT, prebidEvent['auctionInit']); + + // Step 2: Send bid requested event for auction 1 + events.emit(EVENTS.BID_REQUESTED, prebidEvent['bidRequested']); + + // Step 3: Send auction init event for auction 2 + events.emit( + EVENTS.AUCTION_INIT, + replaceProperty(prebidEvent['auctionInit'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 4: Send bid requested event for auction 2 + events.emit( + EVENTS.BID_REQUESTED, + replaceProperty(prebidEvent['bidRequested'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 5: Send bid response event for auction 1 + events.emit(EVENTS.BID_RESPONSE, prebidEvent['bidResponse']); + + // Step 6: Send bid time out event for auction 1 + events.emit(EVENTS.BID_TIMEOUT, prebidEvent['bidTimeout']); + + // Step 7: Send bid response event for auction 2 + events.emit( + EVENTS.BID_RESPONSE, + replaceProperty(prebidEvent['bidResponse'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 8: Send auction end event for auction 1 + events.emit(EVENTS.AUCTION_END, prebidEvent['auctionEnd']); + + // Simulate "navigate away" behaviour + document.dispatchEvent(new Event('visibilitychange')); + + // Step 9: check the number of calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(0); + + // Step 10: Send auction bid won event for auction 1 + events.emit(EVENTS.BID_WON, prebidEvent['bidWon']); + + // Simulate "navigate away" behaviour + document.dispatchEvent(new Event('visibilitychange')); + + // Step 11: check the number of calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(2); + + // Step 12: Send auction end event for auction 2 + events.emit( + EVENTS.AUCTION_END, + replaceProperty(prebidEvent['auctionEnd'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Simulate "navigate away" behaviour + document.dispatchEvent(new Event('visibilitychange')); - let winEventData = JSON.parse(server.requests[1].requestBody); + // Step 13: check the number of calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(2); - expect(winEventData).to.deep.equal(expectedAfterBidWon); + // Step 14: Send auction bid won event for auction 2 + events.emit( + EVENTS.BID_WON, + replaceProperty(prebidEvent['bidWon'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Simulate end of session + document.dispatchEvent(new Event('visibilitychange')); + + // Step 15: check the calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(4); + for (const [index, arg] of navigator.sendBeacon.args.entries()) { + const [expectedUrl, expectedData] = arg; + const parsedUrl = new URL(expectedUrl); + const auctionIdMapFn = index < 2 ? (i, _) => i : replaceProperty; + expect(parsedUrl.pathname).to.equal( + ['/analytics/bidwon', '/analytics/auction'][index % 2] + ); + expect(Object.fromEntries(parsedUrl.searchParams)).to.deep.equal({ + auctionTimestamp: '1616654312804', + pubxaiAnalyticsVersion: 'v2.0.0', + prebidVersion: '$prebid.version$', + }); + expect(expectedData.type).to.equal('text/json'); + expect(JSON.parse(await readBlobSafariCompat(expectedData))).to.deep.equal([ + auctionIdMapFn([expectedAfterBidWon, expectedAfterBid][index % 2], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + { + field: 'refreshRank', + updated: '1', + replaced: '0', + }, + ]), + ]); + } + }); + + it('2 concurrent auctions with batch sending', async () => { + // Step 1: Send auction init event for auction 1 + events.emit(EVENTS.AUCTION_INIT, prebidEvent['auctionInit']); + + // Step 2: Send bid requested event for auction 1 + events.emit(EVENTS.BID_REQUESTED, prebidEvent['bidRequested']); + + // Step 3: Send auction init event for auction 2 + events.emit( + EVENTS.AUCTION_INIT, + replaceProperty(prebidEvent['auctionInit'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 4: Send bid requested event for auction 2 + events.emit( + EVENTS.BID_REQUESTED, + replaceProperty(prebidEvent['bidRequested'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 5: Send bid response event for auction 1 + events.emit(EVENTS.BID_RESPONSE, prebidEvent['bidResponse']); + + // Step 6: Send bid time out event for auction 1 + events.emit(EVENTS.BID_TIMEOUT, prebidEvent['bidTimeout']); + + // Step 7: Send bid response event for auction 2 + events.emit( + EVENTS.BID_RESPONSE, + replaceProperty(prebidEvent['bidResponse'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 8: Send auction end event for auction 1 + events.emit(EVENTS.AUCTION_END, prebidEvent['auctionEnd']); + + // Step 9: Send auction bid won event for auction 1 + events.emit(EVENTS.BID_WON, prebidEvent['bidWon']); + + // Step 10: Send auction end event for auction 2 + events.emit( + EVENTS.AUCTION_END, + replaceProperty(prebidEvent['auctionEnd'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 11: Send auction bid won event for auction 2 + events.emit( + EVENTS.BID_WON, + replaceProperty(prebidEvent['bidWon'], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + ]) + ); + + // Step 12: check the number of calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(0); + + // Simulate end of session + document.dispatchEvent(new Event('visibilitychange')); + + // Step 13: check the calls made to pubx.ai + expect(navigator.sendBeacon.callCount).to.equal(2); + for (const [index, arg] of navigator.sendBeacon.args.entries()) { + const [expectedUrl, expectedData] = arg; + const parsedUrl = new URL(expectedUrl); + expect(parsedUrl.pathname).to.equal( + ['/analytics/bidwon', '/analytics/auction'][index] + ); + expect(Object.fromEntries(parsedUrl.searchParams)).to.deep.equal({ + auctionTimestamp: '1616654312804', + pubxaiAnalyticsVersion: 'v2.0.0', + prebidVersion: '$prebid.version$', + }); + expect(expectedData.type).to.equal('text/json'); + expect(JSON.parse(await readBlobSafariCompat(expectedData))).to.deep.equal([ + [expectedAfterBidWon, expectedAfterBid][index], + replaceProperty([expectedAfterBidWon, expectedAfterBid][index], [ + { + field: 'auctionId', + updated: '"auction2"', + replaced: '"bc3806e4-873e-453c-8ae5-204f35e923b4"', + }, + { + field: 'refreshRank', + updated: '1', + replaced: '0', + }, + ]), + ]); + } }); }); }); diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js index 8db7e909771..da8b6d8473a 100644 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -362,7 +362,7 @@ describe('PulsePoint Adapter Tests', function () { const bidderRequestGdpr = { gdprConsent: { gdprApplies: true, - consentString: 'serialized_gpdr_data' + consentString: 'serialized_gdpr_data' } }; const request = spec.buildRequests(slotConfigs, syncAddFPDToBidderRequest(Object.assign({}, bidderRequest, bidderRequestGdpr))); @@ -372,7 +372,7 @@ describe('PulsePoint Adapter Tests', function () { // user object expect(ortbRequest.user).to.not.equal(null); expect(ortbRequest.user.ext).to.not.equal(null); - expect(ortbRequest.user.ext.consent).to.equal('serialized_gpdr_data'); + expect(ortbRequest.user.ext.consent).to.equal('serialized_gdpr_data'); // regs object expect(ortbRequest.regs).to.not.equal(null); expect(ortbRequest.regs.ext).to.not.equal(null); @@ -518,7 +518,7 @@ describe('PulsePoint Adapter Tests', function () { }, gdprConsent: { gdprApplies: true, - consentString: 'serialized_gpdr_data' + consentString: 'serialized_gdpr_data' }, ortb2: { user: { @@ -545,7 +545,7 @@ describe('PulsePoint Adapter Tests', function () { registered: true, interests: ['cars'] }, - consent: 'serialized_gpdr_data' + consent: 'serialized_gdpr_data' } }); }); diff --git a/test/spec/modules/pxyzBidAdapter_spec.js b/test/spec/modules/pxyzBidAdapter_spec.js index 36e7a1e9ad6..87dc5ff0783 100644 --- a/test/spec/modules/pxyzBidAdapter_spec.js +++ b/test/spec/modules/pxyzBidAdapter_spec.js @@ -39,12 +39,12 @@ describe('pxyzBidAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/qtBidAdapter_spec.js b/test/spec/modules/qtBidAdapter_spec.js index e573a6ae0e9..8bd8730c7a9 100644 --- a/test/spec/modules/qtBidAdapter_spec.js +++ b/test/spec/modules/qtBidAdapter_spec.js @@ -26,7 +26,7 @@ describe('QTBidAdapter', function () { } }, params: { - placementId: 'testBanner', + placementId: 'testBanner' }, userIdAsEids }, @@ -41,7 +41,7 @@ describe('QTBidAdapter', function () { } }, params: { - placementId: 'testVideo', + placementId: 'testVideo' }, userIdAsEids }, @@ -91,7 +91,15 @@ describe('QTBidAdapter', function () { vendorData: {} }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } }, timeout: 500 }; @@ -119,6 +127,10 @@ describe('QTBidAdapter', function () { expect(serverRequest.method).to.equal('POST'); }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://endpoint1.qt.io/pbjs'); + }); + it('Returns general data valid', function () { let data = serverRequest.data; expect(data).to.be.an('object'); diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index d10fea829bc..fdde8d290f4 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -181,7 +181,6 @@ describe('Quantcast adapter', function () { maxbitrate: 10, // optional playbackmethod: [1], // optional delivery: [1], // optional - placement: 1, // optional api: [2, 3] // optional }, { context: 'instream', @@ -205,7 +204,6 @@ describe('Quantcast adapter', function () { maxbitrate: 10, playbackmethod: [1], delivery: [1], - placement: 1, api: [2, 3], w: 600, h: 300 @@ -242,7 +240,6 @@ describe('Quantcast adapter', function () { maxbitrate: 10, // optional playbackmethod: [1], // optional delivery: [1], // optional - placement: 1, // optional api: [2, 3], // optional context: 'instream', playerSize: [600, 300] @@ -265,7 +262,6 @@ describe('Quantcast adapter', function () { maxbitrate: 10, playbackmethod: [1], delivery: [1], - placement: 1, api: [2, 3], w: 600, h: 300 diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js index 3ad7ada2ae7..4a64e2922f1 100644 --- a/test/spec/modules/radsBidAdapter_spec.js +++ b/test/spec/modules/radsBidAdapter_spec.js @@ -32,12 +32,12 @@ describe('radsAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'someIncorrectParam': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/rakutenBidAdapter_spec.js b/test/spec/modules/rakutenBidAdapter_spec.js index 15b22afbe29..2a9fcb9f83b 100644 --- a/test/spec/modules/rakutenBidAdapter_spec.js +++ b/test/spec/modules/rakutenBidAdapter_spec.js @@ -40,10 +40,10 @@ describe('rakutenBidAdapter', function() { }); it('should return false when required params are not passed', () => { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false) + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false) }) }); diff --git a/test/spec/modules/raynRtdProvider_spec.js b/test/spec/modules/raynRtdProvider_spec.js index 69ea316e8b5..3920d090550 100644 --- a/test/spec/modules/raynRtdProvider_spec.js +++ b/test/spec/modules/raynRtdProvider_spec.js @@ -152,6 +152,7 @@ describe('rayn RTD Submodule', function () { 2: ['71', '313'], 4: ['33', '145', '712'] }; + TEST_SEGMENTS['103015'] = ['agdv23', 'avscg3']; const bidderOrtb2 = {}; const bidders = RTD_CONFIG.dataProviders[0].params.bidders; @@ -174,6 +175,9 @@ describe('rayn RTD Submodule', function () { TEST_SEGMENTS['4']['3'].forEach((id) => { expect(ortb2.user.data[0].segment.find(segment => segment.id === id)).to.exist; }); + TEST_SEGMENTS['103015'].forEach((id) => { + expect(ortb2.user.data[1].segment.find(segment => segment.id === id)).to.exist; + }); }); }); }); @@ -229,6 +233,27 @@ describe('rayn RTD Submodule', function () { logMessageSpy.restore(); }); + it('should update reqBidsConfigObj and execute callback using persona segment from localStorage', function () { + const callbackSpy = sinon.spy(); + const logMessageSpy = sinon.spy(utils, 'logMessage'); + const testSegments = { + 103015: ['agdv23', 'avscg3'] + }; + + getDataFromLocalStorageStub + .withArgs(raynRTD.RAYN_LOCAL_STORAGE_KEY) + .returns(JSON.stringify(testSegments)); + + const reqBidsConfigObj = { ortb2Fragments: { bidder: {} } }; + + raynRTD.raynSubmodule.getBidRequestData(reqBidsConfigObj, callbackSpy, RTD_CONFIG.dataProviders[0]); + + expect(callbackSpy.calledOnce).to.be.true; + expect(logMessageSpy.lastCall.lastArg).to.equal(`Segtax data from localStorage: ${JSON.stringify(testSegments)}`); + + logMessageSpy.restore(); + }); + it('should update reqBidsConfigObj and execute callback using segments from raynJS', function () { const callbackSpy = sinon.spy(); const logMessageSpy = sinon.spy(utils, 'logMessage'); diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js index 4a07c84a494..5cb47eb8f51 100644 --- a/test/spec/modules/relaidoBidAdapter_spec.js +++ b/test/spec/modules/relaidoBidAdapter_spec.js @@ -115,6 +115,11 @@ describe('RelaidoAdapter', function () { }] } }; + window.RelaidoPlayer = { + renderAd: function() { + return null; + } + }; }); afterEach(() => { @@ -569,4 +574,20 @@ describe('RelaidoAdapter', function () { expect(query.ref).to.include(window.location.href); }); }); + + describe('spec.outstreamRender', function () { + it('Should to pass a Bid to renderAd', function () { + const bidResponses = spec.interpretResponse(serverResponse, serverRequest); + const response = bidResponses[0]; + sinon.spy(window.RelaidoPlayer, 'renderAd'); + response.renderer.render(response); + const renderCall = window.RelaidoPlayer.renderAd.getCall(0); + const arg = renderCall.args[0]; + expect(arg.width).to.equal(640); + expect(arg.height).to.equal(360); + expect(arg.vastXml).to.equal(''); + expect(arg.mediaType).to.equal(VIDEO); + expect(arg.placementId).to.equal(100000); + }); + }); }); diff --git a/test/spec/modules/relevatehealthBidAdapter_spec.js b/test/spec/modules/relevatehealthBidAdapter_spec.js new file mode 100644 index 00000000000..ef974bc3ac1 --- /dev/null +++ b/test/spec/modules/relevatehealthBidAdapter_spec.js @@ -0,0 +1,239 @@ +import { + expect +} from 'chai'; +import { + spec +} from '../../../modules/relevatehealthBidAdapter.js'; +import * as utils from '../../../src/utils.js'; + +describe('relevatehealth adapter', function() { + let request; + let bannerResponse, invalidResponse; + + beforeEach(function() { + request = [{ + bidder: 'relevatehealth', + mediaTypes: { + banner: { + sizes: [ + [160, 600] + ] + } + }, + params: { + placement_id: 110011, + user_id: '11211', + width: 160, + height: 600, + domain: '', + bid_floor: 0.5 + } + }]; + bannerResponse = { + 'body': { + 'id': 'a48b79e7-7104-4213-99f3-55f3234f2e54', + 'seatbid': [{ + 'bid': [{ + 'id': '3d7dd6dc-7665-4cdc-96a4-5ea192df32b8', + 'impid': '285b9c53b2c662', + 'price': 20.68, + 'adid': '3389', + 'adm': "", + 'adomain': ['google.com'], + 'iurl': 'https://rtb.relevate.health/prebid/relevate', + 'cid': '1431/3389', + 'crid': '3389', + 'w': 160, + 'h': 600, + 'cat': ['IAB1-15'] + }], + 'seat': '00001', + 'group': 0 + }], + 'cur': 'USD', + 'bidid': 'BIDDER_1276' + } + }; + invalidResponse = { + 'body': { + 'id': 'a48b79e7-7104-4213-99f3-55f3234f2e54', + 'seatbid': [{ + 'bid': [{ + 'id': '3d7dd6dc-7665-4cdc-96a4-5ea192df32b8', + 'impid': '285b9c53b2c662', + 'price': 20.68, + 'adid': '3389', + 'adm': 'invalid response', + 'adomain': ['google.com'], + 'iurl': 'https://rtb.relevate.health/prebid/relevate', + 'cid': '1431/3389', + 'crid': '3389', + 'w': 160, + 'h': 600, + 'cat': ['IAB1-15'] + }], + 'seat': '00001', + 'group': 0 + }], + 'cur': 'USD', + 'bidid': 'BIDDER_1276' + } + }; + }); + + describe('validations', function() { + it('isBidValid : placement_id and user_id are passed', function() { + let bid = { + bidder: 'relevatehealth', + params: { + placement_id: 110011, + user_id: '11211' + } + }, + isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equals(true); + }); + it('isBidValid : placement_id and user_id are not passed', function() { + let bid = { + bidder: 'relevatehealth', + params: { + width: 160, + height: 600, + domain: '', + bid_floor: 0.5 + } + }, + isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equals(false); + }); + it('isBidValid : placement_id is passed but user_id is not passed', function() { + let bid = { + bidder: 'relevatehealth', + params: { + placement_id: 110011, + width: 160, + height: 600, + domain: '', + bid_floor: 0.5 + } + }, + isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equals(false); + }); + it('isBidValid : user_id is passed but placement_id is not passed', function() { + let bid = { + bidder: 'relevatehealth', + params: { + width: 160, + height: 600, + domain: '', + bid_floor: 0.5, + user_id: '11211' + } + }, + isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equals(false); + }); + }); + describe('Validate Request', function() { + it('Immutable bid request validate', function() { + let _Request = utils.deepClone(request), + bidRequest = spec.buildRequests(request); + expect(request).to.deep.equal(_Request); + }); + it('Validate bidder connection', function() { + let _Request = spec.buildRequests(request); + expect(_Request.url).to.equal('https://rtb.relevate.health/prebid/relevate'); + expect(_Request.method).to.equal('POST'); + expect(_Request.options.contentType).to.equal('application/json'); + }); + it('Validate bid request : Impression', function() { + let _Request = spec.buildRequests(request); + let data = JSON.parse(_Request.data); + expect(data[0].imp[0].id).to.equal(request[0].bidId); + expect(data[0].placementId).to.equal(110011); + }); + it('Validate bid request : ad size', function() { + let _Request = spec.buildRequests(request); + let data = JSON.parse(_Request.data); + expect(data[0].imp[0].banner).to.be.a('object'); + expect(data[0].imp[0].banner.w).to.equal(160); + expect(data[0].imp[0].banner.h).to.equal(600); + }); + it('Validate bid request : user object', function() { + let _Request = spec.buildRequests(request); + let data = JSON.parse(_Request.data); + expect(data[0].user).to.be.a('object'); + expect(data[0].user.id).to.be.a('string'); + }); + it('Validate bid request : CCPA Check', function() { + let bidRequest = { + uspConsent: '1NYN' + }; + let _Request = spec.buildRequests(request, bidRequest); + let data = JSON.parse(_Request.data); + expect(data[0].us_privacy).to.equal('1NYN'); + }); + }); + describe('Validate response ', function() { + it('Validate bid response : valid bid response', function() { + let bResponse = spec.interpretResponse(bannerResponse, request); + expect(bResponse).to.be.an('array').with.length.above(0); + expect(bResponse[0].requestId).to.equal(bannerResponse.body.seatbid[0].bid[0].impid); + expect(bResponse[0].width).to.equal(bannerResponse.body.seatbid[0].bid[0].w); + expect(bResponse[0].height).to.equal(bannerResponse.body.seatbid[0].bid[0].h); + expect(bResponse[0].currency).to.equal('USD'); + expect(bResponse[0].netRevenue).to.equal(false); + expect(bResponse[0].mediaType).to.equal('banner'); + expect(bResponse[0].meta.advertiserDomains).to.deep.equal(['google.com']); + expect(bResponse[0].ttl).to.equal(300); + expect(bResponse[0].creativeId).to.equal(bannerResponse.body.seatbid[0].bid[0].crid); + expect(bResponse[0].dealId).to.equal(bannerResponse.body.seatbid[0].bid[0].dealId); + }); + it('Invalid bid response check ', function() { + let bRequest = spec.buildRequests(request); + let response = spec.interpretResponse(invalidResponse, bRequest); + expect(response[0].ad).to.equal('invalid response'); + }); + }); + describe('GPP and coppa', function() { + it('Request params check with GPP Consent', function() { + let bidderReq = { + gppConsent: { + gppString: 'gpp-string-test', + applicableSections: [5] + } + }; + let _Request = spec.buildRequests(request, bidderReq); + let data = JSON.parse(_Request.data); + expect(data[0].gpp).to.equal('gpp-string-test'); + expect(data[0].gpp_sid[0]).to.equal(5); + }); + it('Request params check with GPP Consent read from ortb2', function() { + let bidderReq = { + ortb2: { + regs: { + gpp: 'gpp-test-string', + gpp_sid: [5] + } + } + }; + let _Request = spec.buildRequests(request, bidderReq); + let data = JSON.parse(_Request.data); + expect(data[0].gpp).to.equal('gpp-test-string'); + expect(data[0].gpp_sid[0]).to.equal(5); + }); + it(' Bid request should have coppa flag if its true', () => { + let bidderReq = { + ortb2: { + regs: { + coppa: 1 + } + } + }; + let _Request = spec.buildRequests(request, bidderReq); + let data = JSON.parse(_Request.data); + expect(data[0].coppa).to.equal(1); + }); + }); +}); diff --git a/test/spec/modules/retailspotBidAdapter_spec.js b/test/spec/modules/retailspotBidAdapter_spec.js index 39cddb323b8..f1fb5ae3fd3 100644 --- a/test/spec/modules/retailspotBidAdapter_spec.js +++ b/test/spec/modules/retailspotBidAdapter_spec.js @@ -286,19 +286,19 @@ describe('RetailSpot Adapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.size; + let invalidBid = Object.assign({}, bid); + delete invalidBid.sizes; - expect(!!spec.isBidRequestValid(bid)).to.equal(false); + expect(!!spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placement': 0 }; - expect(!!spec.isBidRequestValid(bid)).to.equal(false); + expect(!!spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/rasBidAdapter_spec.js b/test/spec/modules/ringieraxelspringerBidAdapter_spec.js similarity index 89% rename from test/spec/modules/rasBidAdapter_spec.js rename to test/spec/modules/ringieraxelspringerBidAdapter_spec.js index f172d192221..3539dad9362 100644 --- a/test/spec/modules/rasBidAdapter_spec.js +++ b/test/spec/modules/ringieraxelspringerBidAdapter_spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; -import { spec } from 'modules/rasBidAdapter.js'; +import { spec } from 'modules/ringieraxelspringerBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; const CSR_ENDPOINT = 'https://csr.onet.pl/4178463/csr-006/csr.json?nid=4178463&'; -describe('rasBidAdapter', function () { +describe('ringieraxelspringerBidAdapter', function () { const adapter = newBidder(spec); describe('inherited functions', function () { @@ -17,7 +17,7 @@ describe('rasBidAdapter', function () { it('should return true when required params found', function () { const bid = { sizes: [[300, 250], [300, 600]], - bidder: 'ras', + bidder: 'ringieraxelspringer', params: { slot: 'slot', area: 'areatest', @@ -31,7 +31,7 @@ describe('rasBidAdapter', function () { it('should return false when required params not found', function () { const failBid = { sizes: [[300, 250], [300, 300]], - bidder: 'ras', + bidder: 'ringieraxelspringer', params: { site: 'test', network: '4178463' @@ -43,7 +43,7 @@ describe('rasBidAdapter', function () { it('should return nothing when bid request is malformed', function () { const failBid = { sizes: [[300, 250], [300, 300]], - bidder: 'ras', + bidder: 'ringieraxelspringer', }; expect(spec.isBidRequestValid(failBid)).to.equal(undefined); }); @@ -52,7 +52,7 @@ describe('rasBidAdapter', function () { describe('buildRequests', function () { const bid = { sizes: [[300, 250], [300, 600]], - bidder: 'ras', + bidder: 'ringieraxelspringer', bidId: 1, params: { slot: 'test', @@ -81,7 +81,7 @@ describe('rasBidAdapter', function () { }; const bid2 = { sizes: [[750, 300]], - bidder: 'ras', + bidder: 'ringieraxelspringer', bidId: 2, params: { slot: 'test2', @@ -157,8 +157,10 @@ describe('rasBidAdapter', function () { expect(requests[0].url).to.have.string('id0=1'); expect(requests[0].url).to.have.string('iusizes0=300x250%2C300x600'); expect(requests[0].url).to.have.string('slot1=test2'); + expect(requests[0].url).to.have.string('kvhb_format0=banner'); expect(requests[0].url).to.have.string('id1=2'); expect(requests[0].url).to.have.string('iusizes1=750x300'); + expect(requests[0].url).to.have.string('kvhb_format1=banner'); expect(requests[0].url).to.have.string('site=test'); expect(requests[0].url).to.have.string('area=areatest'); expect(requests[0].url).to.have.string('cre_format=html'); @@ -299,14 +301,14 @@ describe('rasBidAdapter', function () { } }]; const resp = spec.interpretResponse({body: {gctx: '1234567890'}}, bidRequest); - expect(resp).to.deep.equal({bids: [], fledgeAuctionConfigs: auctionConfigs}); + expect(resp).to.deep.equal({bids: [], paapi: auctionConfigs}); }); }); describe('buildNativeRequests', function () { const bid = { sizes: 'fluid', - bidder: 'ras', + bidder: 'ringieraxelspringer', bidId: 1, params: { slot: 'nativestd', @@ -365,6 +367,7 @@ describe('rasBidAdapter', function () { expect(requests[0].url).to.have.string('dr=https%3A%2F%2Fexample.org%2F'); expect(requests[0].url).to.have.string('test=name%3Dvalue'); expect(requests[0].url).to.have.string('cre_format0=native'); + expect(requests[0].url).to.have.string('kvhb_format0=native'); expect(requests[0].url).to.have.string('iusizes0=fluid'); }); }); @@ -407,6 +410,8 @@ describe('rasBidAdapter', function () { title: 'Headline', image: '//img.url', url: '//link.url', + partner_logo: '//logo.url', + adInfo: 'REKLAMA', impression: '//impression.url', impression1: '//impression1.url', impressionJs1: '//impressionJs1.url' @@ -444,9 +449,10 @@ describe('rasBidAdapter', function () { Calltoaction: 'Calltoaction', Headline: 'Headline', Image: '//img.url', - Sponsorlabel: 'nie', + adInfo: 'REKLAMA', Thirdpartyclicktracker: '//link.url', - imp: '//imp.url' + imp: '//imp.url', + thirdPartyClickTracker2: '//thirdPartyClickTracker.url' }, meta: { slot: 'nativestd', @@ -465,29 +471,54 @@ describe('rasBidAdapter', function () { ver: '1.2', assets: [ { - id: 2, + id: 0, + data: { + value: '', + type: 2 + }, + }, + { + id: 1, + data: { + value: 'REKLAMA', + type: 10 + }, + }, + { + id: 3, img: { - url: '//img.url', + type: 1, + url: '//logo.url', w: 1, h: 1 } }, { id: 4, - title: { - text: 'Headline' + img: { + type: 3, + url: '//img.url', + w: 1, + h: 1 } }, { - id: 3, + id: 5, data: { value: 'Test Onet', type: 1 + }, + }, + { + id: 6, + title: { + text: 'Headline' } - } + }, ], link: { - url: '//adclick.url//link.url' + url: '//adclick.url//link.url', + clicktrackers: [] }, eventtrackers: [ { @@ -521,9 +552,15 @@ describe('rasBidAdapter', function () { width: 1, height: 1 }, + icon: { + url: '//logo.url', + width: 1, + height: 1 + }, clickUrl: '//adclick.url//link.url', cta: '', body: 'BODY', + body2: 'REKLAMA', sponsoredBy: 'Test Onet', ortb: expectedTeaserStandardOrtbResponse, privacyLink: '//dsa.url' @@ -532,29 +569,54 @@ describe('rasBidAdapter', function () { ver: '1.2', assets: [ { - id: 2, + id: 0, + data: { + value: '', + type: 2 + }, + }, + { + id: 1, + data: { + value: 'REKLAMA', + type: 10 + }, + }, + { + id: 3, img: { - url: '//img.url', + type: 1, + url: '', w: 1, h: 1 } }, { id: 4, - title: { - text: 'Headline' + img: { + type: 3, + url: '//img.url', + w: 1, + h: 1 } }, { - id: 3, + id: 5, data: { value: 'Test Onet', type: 1 + }, + }, + { + id: 6, + title: { + text: 'Headline' } - } + }, ], link: { - url: '//adclick.url//link.url' + url: '//adclick.url//link.url', + clicktrackers: ['//thirdPartyClickTracker.url'] }, eventtrackers: [ { @@ -578,9 +640,15 @@ describe('rasBidAdapter', function () { width: 1, height: 1 }, + icon: { + url: '', + width: 1, + height: 1 + }, clickUrl: '//adclick.url//link.url', cta: 'Calltoaction', body: 'BODY', + body2: 'REKLAMA', sponsoredBy: 'Test Onet', ortb: expectedNativeInFeedOrtbResponse, privacyLink: '//dsa.url' diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js index 77b746b9b69..cc303dc2f96 100644 --- a/test/spec/modules/rtbhouseBidAdapter_spec.js +++ b/test/spec/modules/rtbhouseBidAdapter_spec.js @@ -43,12 +43,12 @@ describe('RTBHouseAdapter', () => { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'someIncorrectParam': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); @@ -460,7 +460,7 @@ describe('RTBHouseAdapter', () => { let bidRequest = Object.assign([], bidRequests); delete bidRequest[0].params.test; config.setConfig({ fledgeConfig: true }); - const request = spec.buildRequests(bidRequest, { ...bidderRequest, fledgeEnabled: true }); + const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: true} }); expect(request.url).to.equal('https://prebid-eu.creativecdn.com/bidder/prebidfledge/bids'); expect(request.method).to.equal('POST'); }); @@ -470,7 +470,7 @@ describe('RTBHouseAdapter', () => { delete bidRequest[0].params.test; config.setConfig({ fledgeConfig: false }); - const request = spec.buildRequests(bidRequest, { ...bidderRequest, fledgeEnabled: true }); + const request = spec.buildRequests(bidRequest, {...bidderRequest, paapi: {enabled: true}}); const data = JSON.parse(request.data); expect(data.ext).to.exist.and.to.be.a('object'); expect(data.ext.fledge_config).to.exist.and.to.be.a('object'); @@ -490,7 +490,7 @@ describe('RTBHouseAdapter', () => { decisionLogicUrl: 'https://sellers.domain/decision.url' } }); - const request = spec.buildRequests(bidRequest, { ...bidderRequest, fledgeEnabled: true }); + const request = spec.buildRequests(bidRequest, {...bidderRequest, paapi: {enabled: true}}); const data = JSON.parse(request.data); expect(data.ext).to.exist.and.to.be.a('object'); expect(data.ext.fledge_config).to.exist.and.to.be.a('object'); @@ -506,7 +506,7 @@ describe('RTBHouseAdapter', () => { bidRequest[0].ortb2Imp = { ext: { ae: 2 } }; - const request = spec.buildRequests(bidRequest, { ...bidderRequest, fledgeEnabled: false }); + const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: false} }); let data = JSON.parse(request.data); if (data.imp[0].ext) { expect(data.imp[0].ext).to.not.have.property('ae'); @@ -519,7 +519,7 @@ describe('RTBHouseAdapter', () => { bidRequest[0].ortb2Imp = { ext: { ae: 2 } }; - const request = spec.buildRequests(bidRequest, { ...bidderRequest, fledgeEnabled: true }); + const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: true} }); let data = JSON.parse(request.data); expect(data.imp[0].ext.ae).to.equal(2); }); @@ -782,9 +782,9 @@ describe('RTBHouseAdapter', () => { it('should return FLEDGE auction_configs alongside bids', function () { expect(response).to.have.property('bids'); - expect(response).to.have.property('fledgeAuctionConfigs'); - expect(response.fledgeAuctionConfigs.length).to.equal(1); - expect(response.fledgeAuctionConfigs[0].bidId).to.equal('test-bid-id'); + expect(response).to.have.property('paapi'); + expect(response.paapi.length).to.equal(1); + expect(response.paapi[0].bidId).to.equal('test-bid-id'); }); }); diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 494943f9f7d..9e25300e10b 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -14,7 +14,7 @@ import * as utils from 'src/utils.js'; import {find} from 'src/polyfill.js'; import {createEidsArray} from 'modules/userId/eids.js'; import 'modules/schain.js'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/userId/index.js'; import 'modules/priceFloors.js'; @@ -3695,14 +3695,14 @@ describe('the rubicon adapter', function () { }] }; - let {bids, fledgeAuctionConfigs} = spec.interpretResponse({body: response}, { + let {bids, paapi} = spec.interpretResponse({body: response}, { bidRequest: bidderRequest.bids[0] }); expect(bids).to.be.lengthOf(1); - expect(fledgeAuctionConfigs[0].bidId).to.equal('5432'); - expect(fledgeAuctionConfigs[0].config.random).to.equal('value'); - expect(fledgeAuctionConfigs[1].bidId).to.equal('6789'); + expect(paapi[0].bidId).to.equal('5432'); + expect(paapi[0].config.random).to.equal('value'); + expect(paapi[1].bidId).to.equal('6789'); }); it('should handle an error', function () { diff --git a/test/spec/modules/seedingAllianceAdapter_spec.js b/test/spec/modules/seedingAllianceAdapter_spec.js index 03548cf923a..45d1544d100 100755 --- a/test/spec/modules/seedingAllianceAdapter_spec.js +++ b/test/spec/modules/seedingAllianceAdapter_spec.js @@ -1,5 +1,6 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; +import {getStorageManager} from 'src/storageManager.js'; import {spec} from 'modules/seedingAllianceBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; @@ -100,6 +101,84 @@ describe('SeedingAlliance adapter', function () { }); }); + describe('check user ID functionality', function () { + let storage = getStorageManager({ bidderCode: 'seedingAlliance' }); + let localStorageIsEnabledStub = sinon.stub(storage, 'localStorageIsEnabled'); + let getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); + const bidRequests = [{ + bidId: 'bidId', + params: {} + }]; + const bidderRequest = { + refererInfo: { referer: 'page' }, + gdprConsent: 'CP0j9IAP0j9IAAGABCENAYEgAP_gAAAAAAYgIxBVBCpNDWFAMHBVAJIgCYAU1sARIAQAABCAAyAFAAOA8IAA0QECEAQAAAACAAAAgVABAAAAAABEAACAAAAEAQFkAAQQgAAIAAAAAAEQQgBQAAgAAAAAEAAIgAABAwQAkACQIYLEBUCAhIAgCgAAAIgBgICAAgMACEAYAAAAAAIAAIBAAgIEMIAAAAECAQAAAFhIEoACAAKgAcgA-AEAAMgAaABEACYAG8APwAhIBDAESAJYATQAw4B9gH6ARQAjQBKQC5gF6AMUAbQA3ACdgFDgLzAYMAw0BmYDVwGsgOCAcmA8cCEMELQQuCAAgGQgQMHQKAAKgAcgA-AEAAMgAaABEACYAG8AP0AhgCJAEsAJoAYYA0YB9gH6ARQAiwBIgCUgFzAL0AYoA2gBuAEXgJkATsAocBeYDBgGGgMqAZYAzMBpoDVwHFgOTAeOBC0cAHAAQABcAKACEAF0AMEAZCQgFABMADeARQAlIBcwDFAG0AeOBCgCFpAAGAAgBggEMyUAwABAAHAAPgBEACZAIYAiQB-AFzAMUAi8BeYEISQAMAC4DLAIZlIEAAFQAOQAfACAAGQANAAiABMACkAH6AQwBEgDRgH4AfoBFgCRAEpALmAYoA2gBuAEXgJ2AUOAvMBhoDLAGsgOCAcmA8cCEIELQIZlAAoAFwB9gLoAYIBAwtADAL0AzMB44AAA.f_wAAAAAAAAA' + } + let request; + + before(function () { + storage.removeDataFromLocalStorage('nativendo_id'); + const localStorageData = { + nativendo_id: '123' + }; + + getDataFromLocalStorageStub.callsFake(function (key) { + return localStorageData[key]; + }); + }); + + it('should return an empty array if local storage is not enabled', function () { + localStorageIsEnabledStub.returns(false); + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: false + } + }; + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + expect(request.user.ext.eids).to.be.an('array').that.is.empty; + }); + + it('should return an empty array if local storage is enabled but storageAllowed is false', function () { + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: false + } + }; + localStorageIsEnabledStub.returns(true); + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + expect(request.user.ext.eids).to.be.an('array').that.is.empty; + }); + + it('should return a non empty array if local storage is enabled and storageAllowed is true', function () { + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: true + } + }; + localStorageIsEnabledStub.returns(true); + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + expect(request.user.ext.eids).to.be.an('array').that.is.not.empty; + }); + + it('should return an array containing the nativendoUserEid', function () { + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: true + } + }; + localStorageIsEnabledStub.returns(true); + + let nativendoUserEid = { source: 'nativendo.de', uids: [{ id: '123', atype: 1 }] }; + storage.setDataInLocalStorage('nativendo_id', '123'); + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + + expect(request.user.ext.eids).to.deep.include(nativendoUserEid); + }); + }); + describe('interpretResponse', function () { const goodNativeResponse = { body: { diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js index ed3e2c9be0b..3cd21c122eb 100644 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ b/test/spec/modules/seedtagBidAdapter_spec.js @@ -37,6 +37,7 @@ function getSlotConfigs(mediaTypes, params) { ortb2Imp: { ext: { tid: 'd704d006-0d6e-4a09-ad6c-179e7e758096', + gpid: 'some-gpid' } }, adUnitCode: adUnitCode, @@ -299,6 +300,7 @@ describe('Seedtag Adapter', function () { expect(data.ttfb).to.be.greaterThanOrEqual(0); expect(data.bidRequests[0].adUnitCode).to.equal(adUnitCode); + expect(data.bidRequests[0].gpid).to.equal('some-gpid'); }); describe('GDPR params', function () { @@ -626,6 +628,33 @@ describe('Seedtag Adapter', function () { expect(data.badv).to.be.undefined; }); }); + + describe('device.sua param', function () { + it('should add device.sua param to payload when bidderRequest has ortb2 device.sua info', function () { + const sua = 1 + var ortb2 = { + device: { + sua: sua + } + } + bidderRequest['ortb2'] = ortb2 + + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + expect(data.sua).to.equal(sua); + }); + + it('should not add device.sua param to payload when bidderRequest does not have ortb2 device.sua info', function () { + var ortb2 = { + device: {} + } + bidderRequest['ortb2'] = ortb2 + + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + expect(data.sua).to.be.undefined; + }); + }); }) describe('interpret response method', function () { it('should return a void array, when the server response are not correct.', function () { diff --git a/test/spec/modules/setupadBidAdapter_spec.js b/test/spec/modules/setupadBidAdapter_spec.js index d4ff73d005f..3a184c50922 100644 --- a/test/spec/modules/setupadBidAdapter_spec.js +++ b/test/spec/modules/setupadBidAdapter_spec.js @@ -1,4 +1,4 @@ -import { spec } from 'modules/setupadBidAdapter.js'; +import { spec, biddersCreativeIds } from 'modules/setupadBidAdapter.js'; describe('SetupadAdapter', function () { const userIdAsEids = [ @@ -42,9 +42,104 @@ describe('SetupadAdapter', function () { }, userIdAsEids, }, + { + adUnitCode: 'test-div-2', + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidId: '22c4871113f461', + bidder: 'rubicon', + bidderRequestId: '15246a574e859f', + uspConsent: 'usp-context-string', + gdprConsent: { + consentString: 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA', + gdprApplies: true, + }, + params: { + placement_id: '123', + account_id: 'test-account-id', + }, + sizes: [[300, 250]], + ortb2: { + device: { + w: 1500, + h: 1000, + }, + site: { + domain: 'test.com', + page: 'http://test.com', + }, + }, + userIdAsEids, + }, ]; const bidderRequest = { + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + auctionStart: 1579746300522, + bidderCode: 'setupad', + bidderRequestId: '15246a574e859f', + bids: [ + { + adUnitCode: 'test-div', + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidId: '22c4871113f461', + bidder: 'rubicon', + bidderRequestId: '15246a574e859f', + uspConsent: 'usp-context-string', + gdprConsent: { + consentString: 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA', + gdprApplies: true, + }, + params: { + placement_id: '123', + account_id: 'test-account-id', + }, + sizes: [[300, 250]], + ortb2: { + device: { + w: 1500, + h: 1000, + }, + site: { + domain: 'test.com', + page: 'http://test.com', + }, + }, + userIdAsEids, + }, + { + adUnitCode: 'test-div-2', + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidId: '22c4871113f461', + bidder: 'rubicon', + bidderRequestId: '15246a574e859f', + uspConsent: 'usp-context-string', + gdprConsent: { + consentString: 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA', + gdprApplies: true, + }, + params: { + placement_id: '123', + account_id: 'test-account-id', + }, + sizes: [[300, 250]], + ortb2: { + device: { + w: 1500, + h: 1000, + }, + site: { + domain: 'test.com', + page: 'http://test.com', + }, + }, + userIdAsEids, + }, + ], + gdprConsent: { + consentString: 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA', + vendorData: {}, + gdprApplies: true, + }, ortb2: { device: { w: 1500, @@ -52,39 +147,27 @@ describe('SetupadAdapter', function () { }, }, refererInfo: { + canonicalUrl: null, domain: 'test.com', page: 'http://test.com', - ref: '', + referer: null, }, }; const serverResponse = { body: { - id: 'f7b3d2da-e762-410c-b069-424f92c4c4b2', seatbid: [ { - bid: [ - { - id: 'test-bid-id', - price: 0.8, - adm: 'this is an ad', - adid: 'test-ad-id', - adomain: ['test.addomain.com'], - w: 300, - h: 250, - }, - ], - seat: 'testBidder', + bid: [{ crid: 123 }, { crid: 1234 }], + seat: 'pubmatic', }, - ], - cur: 'USD', - ext: { - sync: { - image: ['urlA?gdpr={{.GDPR}}'], - iframe: ['urlB'], + { + bid: [{ crid: 12345 }], + seat: 'setupad', }, - }, + ], }, + testCase: 1, }; describe('isBidRequestValid', function () { @@ -92,11 +175,26 @@ describe('SetupadAdapter', function () { bidder: 'setupad', params: { placement_id: '123', + account_id: '123', }, }; + it('should return true when required params found', function () { expect(spec.isBidRequestValid(bid)).to.equal(true); }); + + it('should return false when placement_id is missing', function () { + const bidWithoutPlacementId = { ...bid }; + delete bidWithoutPlacementId.params.placement_id; + expect(spec.isBidRequestValid(bidWithoutPlacementId)).to.equal(false); + }); + + it('should return false when account_id is missing', function () { + const bidWithoutAccountId = { ...bid }; + delete bidWithoutAccountId.params.account_id; + expect(spec.isBidRequestValid(bidWithoutAccountId)).to.equal(false); + }); + it('should return false when required params are not passed', function () { delete bid.params.placement_id; expect(spec.isBidRequestValid(bid)).to.equal(false); @@ -104,77 +202,25 @@ describe('SetupadAdapter', function () { }); describe('buildRequests', function () { - it('check request params with GDPR and USP', function () { - const request = spec.buildRequests(bidRequests, bidRequests[0]); - expect(JSON.parse(request[0].data).user.ext.consent).to.equal( - 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA' - ); - expect(JSON.parse(request[0].data).regs.ext.gdpr).to.equal(1); - expect(JSON.parse(request[0].data).regs.ext.us_privacy).to.equal('usp-context-string'); - }); - - it('check request params without GDPR', function () { - let bidRequestsWithoutGDPR = Object.assign({}, bidRequests[0]); - delete bidRequestsWithoutGDPR.gdprConsent; - const request = spec.buildRequests([bidRequestsWithoutGDPR], bidRequestsWithoutGDPR); - expect(JSON.parse(request[0].data).regs.ext.gdpr).to.be.undefined; - expect(JSON.parse(request[0].data).regs.ext.us_privacy).to.equal('usp-context-string'); + it('should return correct storedrequest id for bids if placement_id is provided', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.imp[0].ext.prebid.storedrequest.id).to.equal('123'); }); it('should return correct storedrequest id if account_id is provided', function () { - const request = spec.buildRequests(bidRequests, bidRequests[0]); - expect(JSON.parse(request[0].data).ext.prebid.storedrequest.id).to.equal('test-account-id'); - }); - - it('should return correct storedrequest id if account_id is not provided', function () { - let bidRequestsWithoutAccountId = Object.assign({}, bidRequests[0]); - delete bidRequestsWithoutAccountId.params.account_id; - const request = spec.buildRequests( - [bidRequestsWithoutAccountId], - bidRequestsWithoutAccountId - ); - expect(JSON.parse(request[0].data).ext.prebid.storedrequest.id).to.equal('default'); - }); - - it('validate generated params', function () { - const request = spec.buildRequests(bidRequests); - expect(request[0].bidId).to.equal('22c4871113f461'); - expect(JSON.parse(request[0].data).id).to.equal('15246a574e859f'); - }); - - it('check if correct site object was added', function () { const request = spec.buildRequests(bidRequests, bidderRequest); - const siteObj = JSON.parse(request[0].data).site; - - expect(siteObj.domain).to.equal('test.com'); - expect(siteObj.page).to.equal('http://test.com'); - expect(siteObj.ref).to.equal(''); + expect(request.data.ext.prebid.storedrequest.id).to.equal('test-account-id'); }); - it('check if correct device object was added', function () { + it('should return setupad custom adapter param', function () { const request = spec.buildRequests(bidRequests, bidderRequest); - const deviceObj = JSON.parse(request[0].data).device; - - expect(deviceObj.w).to.equal(1500); - expect(deviceObj.h).to.equal(1000); - }); - - it('check if imp object was added', function () { - const request = spec.buildRequests(bidRequests); - expect(JSON.parse(request[0].data).imp).to.be.an('array'); - }); - - it('should send "user.ext.eids" in the request for Prebid.js supported modules only', function () { - const request = spec.buildRequests(bidRequests); - expect(JSON.parse(request[0].data).user.ext.eids).to.deep.equal(userIdAsEids); + expect(request.data.setupad).to.equal('adapter'); }); - it('should send an undefined "user.ext.eids" in the request if userId module is unsupported', function () { - let bidRequestsUnsupportedUserIdModule = Object.assign({}, bidRequests[0]); - delete bidRequestsUnsupportedUserIdModule.userIdAsEids; - const request = spec.buildRequests(bidRequestsUnsupportedUserIdModule); - - expect(JSON.parse(request[0].data).user.ext.eids).to.be.undefined; + // Change this to 1 whenever TEST_REQUEST = 1. This is allowed only for testing requests locally + it('should return correct test attribute value from global value', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.test).to.equal(0); }); }); @@ -241,25 +287,21 @@ describe('SetupadAdapter', function () { describe('interpretResponse', function () { it('should return empty array if error during parsing', () => { const wrongServerResponse = 'wrong data'; - let request = spec.buildRequests(bidRequests, bidRequests[0]); + let request = spec.buildRequests(bidRequests, bidderRequest); let result = spec.interpretResponse(wrongServerResponse, request); expect(result).to.be.instanceof(Array); expect(result.length).to.equal(0); }); - it('should get correct bid response', function () { - const result = spec.interpretResponse(serverResponse, bidRequests[0]); - expect(result).to.be.an('array').with.lengthOf(1); - expect(result[0].requestId).to.equal('22c4871113f461'); - expect(result[0].cpm).to.equal(0.8); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].creativeId).to.equal('test-bid-id'); - expect(result[0].currency).to.equal('USD'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].ttl).to.equal(360); - expect(result[0].ad).to.equal('this is an ad'); + it('should update biddersCreativeIds correctly', function () { + spec.interpretResponse(serverResponse, bidderRequest); + + expect(biddersCreativeIds).to.deep.equal({ + 123: 'pubmatic', + 1234: 'pubmatic', + 12345: 'setupad', + }); }); }); diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js index ab099d87429..8fc29a2cef3 100644 --- a/test/spec/modules/sharethroughBidAdapter_spec.js +++ b/test/spec/modules/sharethroughBidAdapter_spec.js @@ -755,7 +755,7 @@ describe('sharethrough adapter spec', function () { const EXPECTED_AE_VALUE = 1; // ACT - bidderRequest['fledgeEnabled'] = true; + bidderRequest.paapi = {enabled: true}; const builtRequests = spec.buildRequests(bidRequests, bidderRequest); const ACTUAL_AE_VALUE = builtRequests[0].data.imp[0].ext.ae; diff --git a/test/spec/modules/shinezRtbBidAdapter_spec.js b/test/spec/modules/shinezRtbBidAdapter_spec.js index 3965cd69c5f..2e4c35cb065 100644 --- a/test/spec/modules/shinezRtbBidAdapter_spec.js +++ b/test/spec/modules/shinezRtbBidAdapter_spec.js @@ -2,6 +2,9 @@ import {expect} from 'chai'; import { spec as adapter, createDomain, + storage +} from 'modules/shinezRtbBidAdapter'; +import { hashCode, extractPID, extractCID, @@ -10,15 +13,14 @@ import { setStorageItem, tryParseJSON, getUniqueDealId, -} from 'modules/shinezRtbBidAdapter'; -import * as utils from 'src/utils.js'; +} from '../../../libraries/vidazooUtils/bidderUtils.js'; +import {parseUrl, deepClone} from 'src/utils.js'; import {version} from 'package.json'; import {useFakeTimers} from 'sinon'; import {BANNER, VIDEO} from '../../../src/mediaTypes'; import {config} from '../../../src/config'; -import {deepAccess} from 'src/utils.js'; -export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId', 'digitrustid']; +export const TEST_ID_SYSTEMS = ['criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'pubcid', 'tdid', 'pubProvidedId']; const SUB_DOMAIN = 'exchange'; @@ -181,7 +183,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); return parsedUrl.search; } catch (e) { return ''; @@ -328,7 +330,12 @@ describe('ShinezRtbBidAdapter', function () { startdelay: 0 } }, - gpid: '0123456789' + gpid: '0123456789', + cat: [], + contentData: [], + isStorageAllowed: true, + pagecat: [], + userData: [] } }); }); @@ -390,6 +397,11 @@ describe('ShinezRtbBidAdapter', function () { uqs: getTopWindowQueryParams(), 'ext.param1': 'loremipsum', 'ext.param2': 'dolorsitamet', + cat: [], + contentData: [], + isStorageAllowed: true, + pagecat: [], + userData: [] } }); }); @@ -463,7 +475,7 @@ describe('ShinezRtbBidAdapter', function () { }); it('should get meta from response metaData', function () { - const serverResponse = utils.deepClone(SERVER_RESPONSE); + const serverResponse = deepClone(SERVER_RESPONSE); serverResponse.body.results[0].metaData = { advertiserDomains: ['sweetgum.io'], agencyName: 'Agency Name', @@ -496,7 +508,7 @@ describe('ShinezRtbBidAdapter', function () { }); it('should take default TTL', function () { - const serverResponse = utils.deepClone(SERVER_RESPONSE); + const serverResponse = deepClone(SERVER_RESPONSE); delete serverResponse.body.results[0].exp; const responses = adapter.interpretResponse(serverResponse, REQUEST); expect(responses).to.have.length(1); @@ -507,16 +519,12 @@ describe('ShinezRtbBidAdapter', function () { describe('user id system', function () { TEST_ID_SYSTEMS.forEach((idSystemProvider) => { const id = Date.now().toString(); - const bid = utils.deepClone(BID); + const bid = deepClone(BID); const userId = (function () { switch (idSystemProvider) { - case 'digitrustid': - return {data: {id}}; case 'lipb': return {lipbid: id}; - case 'parrableId': - return {eid: id}; case 'id5id': return {uid: id}; default: @@ -569,13 +577,13 @@ describe('ShinezRtbBidAdapter', function () { const key = 'myKey'; let uniqueDealId; beforeEach(() => { - uniqueDealId = getUniqueDealId(key, 0); + uniqueDealId = getUniqueDealId(storage, key, 0); }) it('should get current unique deal id', function (done) { // waiting some time so `now` will become past setTimeout(() => { - const current = getUniqueDealId(key); + const current = getUniqueDealId(storage, key); expect(current).to.be.equal(uniqueDealId); done(); }, 200); @@ -583,7 +591,7 @@ describe('ShinezRtbBidAdapter', function () { it('should get new unique deal id on expiration', function (done) { setTimeout(() => { - const current = getUniqueDealId(key, 100); + const current = getUniqueDealId(storage, key, 100); expect(current).to.not.be.equal(uniqueDealId); done(); }, 200) @@ -607,8 +615,8 @@ describe('ShinezRtbBidAdapter', function () { shouldAdvanceTime: true, now }); - setStorageItem('myKey', 2020); - const {value, created} = getStorageItem('myKey'); + setStorageItem(storage, 'myKey', 2020); + const {value, created} = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -619,7 +627,7 @@ describe('ShinezRtbBidAdapter', function () { it('should get external stored value', function () { const value = 'superman' window.localStorage.setItem('myExternalKey', value); - const item = getStorageItem('myExternalKey'); + const item = getStorageItem(storage, 'myExternalKey'); expect(item).to.be.equal(value); }); diff --git a/test/spec/modules/sigmoidAnalyticsAdapter_spec.js b/test/spec/modules/sigmoidAnalyticsAdapter_spec.js deleted file mode 100644 index 1d8e38f19ec..00000000000 --- a/test/spec/modules/sigmoidAnalyticsAdapter_spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import sigmoidAnalytic from 'modules/sigmoidAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {expectEvents} from '../../helpers/analytics.js'; - -let events = require('src/events'); -let adapterManager = require('src/adapterManager').default; - -describe('sigmoid Prebid Analytic', function () { - after(function () { - sigmoidAnalytic.disableAnalytics(); - }); - - describe('enableAnalytics', function () { - beforeEach(function () { - sinon.spy(sigmoidAnalytic, 'track'); - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - sigmoidAnalytic.track.restore(); - events.getEvents.restore(); - }); - it('should catch all events', function () { - adapterManager.registerAnalyticsAdapter({ - code: 'sigmoid', - adapter: sigmoidAnalytic - }); - - adapterManager.enableAnalytics({ - provider: 'sigmoid', - options: { - publisherIds: ['test_sigmoid_prebid_analytid_publisher_id'] - } - }); - - expectEvents().to.beTrackedBy(sigmoidAnalytic.track); - }); - }); - describe('build utm tag data', function () { - beforeEach(function () { - localStorage.setItem('sigmoid_analytics_utm_source', 'utm_source'); - localStorage.setItem('sigmoid_analytics_utm_medium', 'utm_medium'); - localStorage.setItem('sigmoid_analytics_utm_campaign', ''); - localStorage.setItem('sigmoid_analytics_utm_term', ''); - localStorage.setItem('sigmoid_analytics_utm_content', ''); - localStorage.setItem('sigmoid_analytics_utm_timeout', Date.now()); - }); - it('should build utm data from local storage', function () { - let utmTagData = sigmoidAnalytic.buildUtmTagData(); - expect(utmTagData.utm_source).to.equal('utm_source'); - expect(utmTagData.utm_medium).to.equal('utm_medium'); - expect(utmTagData.utm_campaign).to.equal(''); - expect(utmTagData.utm_term).to.equal(''); - expect(utmTagData.utm_content).to.equal(''); - }); - }); -}); diff --git a/test/spec/modules/silvermobBidAdapter_spec.js b/test/spec/modules/silvermobBidAdapter_spec.js index 7d7fbacc04e..3ff3dfbfe2d 100644 --- a/test/spec/modules/silvermobBidAdapter_spec.js +++ b/test/spec/modules/silvermobBidAdapter_spec.js @@ -11,7 +11,7 @@ import 'modules/currency.js'; import 'modules/userId/index.js'; import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/schain.js'; diff --git a/test/spec/modules/slimcutBidAdapter_spec.js b/test/spec/modules/slimcutBidAdapter_spec.js index da0fee48936..64ddac71899 100644 --- a/test/spec/modules/slimcutBidAdapter_spec.js +++ b/test/spec/modules/slimcutBidAdapter_spec.js @@ -35,26 +35,26 @@ describe('slimcutBidAdapter', function() { expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should return false when placementId is not valid (letters)', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': 'ABCD' }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when placementId < 0', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': -1 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when required params are not passed', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); describe('buildRequests', function() { diff --git a/test/spec/modules/smaatoBidAdapter_spec.js b/test/spec/modules/smaatoBidAdapter_spec.js index 2ac2a1e5c33..302a5fa1aa6 100644 --- a/test/spec/modules/smaatoBidAdapter_spec.js +++ b/test/spec/modules/smaatoBidAdapter_spec.js @@ -8,10 +8,12 @@ import 'modules/currency.js'; import 'modules/userId/index.js'; import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/schain.js'; +const SYNC_URL = 'https://s.ad.smaato.net/c/?adExInit=p' + const ADTYPE_IMG = 'Img'; const ADTYPE_VIDEO = 'Video'; const ADTYPE_NATIVE = 'Native'; @@ -296,6 +298,33 @@ describe('smaatoBidAdapterTest', () => { expect(req.site.page).to.equal(page); expect(req.site.ref).to.equal(ref); expect(req.site.publisher.id).to.equal('publisherId'); + expect(req.dooh).to.be.undefined; + }) + + it('sends correct dooh from ortb2', () => { + const name = 'name'; + const domain = 'domain'; + const keywords = 'keyword1,keyword2'; + const venuetypetax = 1; + const ortb2 = { + dooh: { + name: name, + domain: domain, + keywords: keywords, + venuetypetax: venuetypetax + }, + }; + + const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + + const req = extractPayloadOfFirstAndOnlyRequest(reqs); + expect(req.dooh.id).to.exist.and.to.be.a('string'); + expect(req.dooh.name).to.equal(name); + expect(req.dooh.domain).to.equal(domain); + expect(req.dooh.keywords).to.equal(keywords); + expect(req.dooh.venuetypetax).to.equal(venuetypetax); + expect(req.dooh.publisher.id).to.equal('publisherId'); + expect(req.site).to.be.undefined; }) it('sends correct device from ortb2', () => { @@ -462,6 +491,48 @@ describe('smaatoBidAdapterTest', () => { const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.user.ext.eids).to.not.exist; }); + + it('sends dsa', () => { + const ortb2 = { + regs: { + ext: { + dsa: { + dsarequired: 2, + pubrender: 0, + datatopub: 1, + transparency: [ + { + domain: 'testdomain.com', + dsaparams: [1, 2, 3] + } + ] + } + } + } + }; + + const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + + const req = extractPayloadOfFirstAndOnlyRequest(reqs); + expect(req.regs.ext.dsa.dsarequired).to.eql(2); + expect(req.regs.ext.dsa.pubrender).to.eql(0); + expect(req.regs.ext.dsa.datatopub).to.eql(1); + expect(req.regs.ext.dsa.transparency[0].domain).to.eql('testdomain.com'); + expect(req.regs.ext.dsa.transparency[0].dsaparams).to.eql([1, 2, 3]); + }); + + it('sends no dsa', () => { + const ortb2 = { + regs: { + ext: {} + } + }; + + const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + + const req = extractPayloadOfFirstAndOnlyRequest(reqs); + expect(req.regs.ext.dsa).to.be.undefined; + }); }); describe('multiple requests', () => { @@ -1566,11 +1637,73 @@ describe('smaatoBidAdapterTest', () => { expect(bids[0].netRevenue).to.equal(false); }); + + it('uses dsa object sent from server', () => { + const resp = buildOpenRtbBidResponse(ADTYPE_IMG); + const dsa = { + behalf: 'advertiser', + paid: 'advertiser', + adrender: 1, + transparency: [ + { + domain: 'dsp1domain.com', + dsaparams: [1, 2] + } + ] + }; + resp.body.seatbid[0].bid[0].ext.dsa = dsa; + + const bids = spec.interpretResponse(resp, buildBidRequest()); + + expect(bids[0].meta.dsa).to.deep.equal(dsa); + }); + + it('does not use dsa object if not sent from server', () => { + const resp = buildOpenRtbBidResponse(ADTYPE_IMG); + resp.body.seatbid[0].bid[0].ext = {} + + const bids = spec.interpretResponse(resp, buildBidRequest()); + + expect(bids[0].meta.dsa).to.be.undefined; + }); }); describe('getUserSyncs', () => { - it('returns no pixels', () => { + it('when pixelEnabled false then returns no pixels', () => { expect(spec.getUserSyncs()).to.be.empty }) + + it('when pixelEnabled true then returns pixel', () => { + expect(spec.getUserSyncs({pixelEnabled: true}, null, null, null)).to.deep.equal( + [ + { + type: 'image', + url: SYNC_URL + } + ] + ) + }) + + it('when pixelEnabled true and gdprConsent then returns pixel with gdpr params', () => { + expect(spec.getUserSyncs({pixelEnabled: true}, null, {gdprApplies: true, consentString: CONSENT_STRING}, null)).to.deep.equal( + [ + { + type: 'image', + url: `${SYNC_URL}&gdpr=1&gdpr_consent=${CONSENT_STRING}` + } + ] + ) + }) + + it('when pixelEnabled true and gdprConsent without gdpr then returns pixel with gdpr_consent', () => { + expect(spec.getUserSyncs({pixelEnabled: true}, null, {consentString: CONSENT_STRING}, null), null).to.deep.equal( + [ + { + type: 'image', + url: `${SYNC_URL}&gdpr_consent=${CONSENT_STRING}` + } + ] + ) + }) }) }); diff --git a/test/spec/modules/smartadserverBidAdapter_spec.js b/test/spec/modules/smartadserverBidAdapter_spec.js index b01d95e2a4c..2f06331f616 100644 --- a/test/spec/modules/smartadserverBidAdapter_spec.js +++ b/test/spec/modules/smartadserverBidAdapter_spec.js @@ -458,6 +458,13 @@ describe('Smart bid adapter tests', function () { expect(syncs).to.have.lengthOf(0); }); + it('should set browsingTopics=false in request.options', () => { + const requests = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL); + expect(requests[0]).to.have.property('options').and.to.deep.equal({ + browsingTopics: false + }); + }); + describe('gdpr tests', function () { afterEach(function () { config.setConfig({ ortb2: undefined }); diff --git a/test/spec/modules/smarthubBidAdapter_spec.js b/test/spec/modules/smarthubBidAdapter_spec.js index a5e8787e21a..eb5fe58093d 100644 --- a/test/spec/modules/smarthubBidAdapter_spec.js +++ b/test/spec/modules/smarthubBidAdapter_spec.js @@ -106,7 +106,9 @@ describe('SmartHubBidAdapter', function () { const bidderRequest = { uspConsent: '1---', - gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw' + }, refererInfo: { page: 'https://test.com' }, @@ -166,7 +168,7 @@ describe('SmartHubBidAdapter', function () { expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); expect(data.coppa).to.be.a('number'); - expect(data.gdpr).to.be.a('string'); + expect(data.gdpr.consentString).to.be.a('string'); expect(data.ccpa).to.be.a('string'); expect(data.tmax).to.be.a('number'); expect(data.placements).to.have.lengthOf(3); @@ -212,8 +214,8 @@ describe('SmartHubBidAdapter', function () { serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest[0].data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr.consentString).to.be.a('string'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); diff --git a/test/spec/modules/smartxBidAdapter_spec.js b/test/spec/modules/smartxBidAdapter_spec.js index c3d0711632e..d8ddf7a398b 100644 --- a/test/spec/modules/smartxBidAdapter_spec.js +++ b/test/spec/modules/smartxBidAdapter_spec.js @@ -178,7 +178,6 @@ describe('The smartx adapter', function () { 2, 3, 5, 6 ], startdelay: 0, - placement: 1, pos: 1 }); @@ -208,10 +207,6 @@ describe('The smartx adapter', function () { sdk_name: 'Prebid 1+' }); - expect(request.data.imp[0].video).to.contain({ - placement: 1 - }); - bid.mediaTypes.video.context = 'outstream'; bid.params = { @@ -251,10 +246,6 @@ describe('The smartx adapter', function () { expect(request.data.imp[0].video.startdelay).to.equal(1); - expect(request.data.imp[0].video).to.contain({ - placement: 3 - }); - expect(request.data.imp[0].bidfloor).to.equal(55); expect(request.data.imp[0].bidfloorcur).to.equal('foo'); diff --git a/test/spec/modules/smartyadsAnalyticsAdapter_spec.js b/test/spec/modules/smartyadsAnalyticsAdapter_spec.js new file mode 100644 index 00000000000..de7e08a8a77 --- /dev/null +++ b/test/spec/modules/smartyadsAnalyticsAdapter_spec.js @@ -0,0 +1,441 @@ +import smartyadsAnalytics from 'modules/smartyadsAnalyticsAdapter.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; +import { EVENTS } from '../../../src/constants'; + +let adapterManager = require('src/adapterManager').default; +let events = require('src/events'); + +describe('SmartyAds Analytics', function () { + const auctionEnd = { + 'auctionId': '1e8b993d-8f0a-4232-83eb-3639ddf3a44b', + 'timestamp': 1647424261187, + 'auctionEnd': 1647424261714, + 'auctionStatus': 'completed', + 'adUnits': [ + { + 'code': 'tag_200124_banner', + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 600 + ] + ] + } + }, + 'bids': [ + { + 'bidder': 'smartyads', + 'params': { + 'placementId': 123456 + } + }, + { + 'bidder': 'smartyadsAst', + 'params': { + 'placementId': 234567 + } + } + ], + 'sizes': [ + [ + 300, + 600 + ] + ], + 'transactionId': 'de664ccb-e18b-4436-aeb0-362382eb1b40' + } + ], + 'adUnitCodes': [ + 'tag_200124_banner' + ], + 'bidderRequests': [ + { + 'bidderCode': 'smartyads', + 'auctionId': '1e8b993d-8f0a-4232-83eb-3639ddf3a44b', + 'bidderRequestId': '11dc6ff6378de7', + 'bids': [ + { + 'bidder': 'smartyads', + 'params': { + 'placementId': 123456 + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 600 + ] + ] + } + }, + 'adUnitCode': 'tag_200124_banner', + 'transactionId': '8b2a8629-d1ea-4bb1-aff0-e335b96dd002', + 'sizes': [ + [ + 300, + 600 + ] + ], + 'bidId': '2bd3e8ff8a113f', + 'bidderRequestId': '11dc6ff6378de7', + 'auctionId': '1e8b993d-8f0a-4232-83eb-3639ddf3a44b', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0, + 'ova': 'cleared' + } + ], + 'auctionStart': 1647424261187, + 'timeout': 1000, + 'gdprConsent': { + 'consentString': 'CONSENT', + 'gdprApplies': true, + 'apiVersion': 2, + 'vendorData': 'a lot of borring stuff', + }, + 'start': 1647424261189 + }, + ], + 'noBids': [ + { + 'bidder': 'smartyadsAst', + 'params': { + 'placementId': 10471298 + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 600 + ] + ] + } + }, + 'adUnitCode': 'tag_200124_banner', + 'transactionId': 'de664ccb-e18b-4436-aeb0-362382eb1b40', + 'sizes': [ + [ + 300, + 600 + ] + ], + 'bidId': '5fe418f2d70364', + 'bidderRequestId': '4229a45ab8ea87', + 'auctionId': '1e8b993d-8f0a-4232-83eb-3639ddf3a44b', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0 + } + ], + 'bidsReceived': [ + { + 'bidderCode': 'smartyads', + 'width': 970, + 'height': 250, + 'statusMessage': 'Bid available', + 'adId': '65d16ef039a97a', + 'requestId': '2bd3e8ff8a113f', + 'transactionId': '8b2a8629-d1ea-4bb1-aff0-e335b96dd002', + 'auctionId': '1e8b993d-8f0a-4232-83eb-3639ddf3a44b', + 'mediaType': 'video', + 'source': 'client', + 'cpm': 27.4276, + 'creativeId': '158534630', + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 2000, + 'ad': 'some html', + 'meta': { + 'advertiserDomains': [ + 'example.com' + ], + 'demandSource': 'something' + }, + 'renderer': 'something', + 'originalCpm': 25.02521, + 'originalCurrency': 'EUR', + 'responseTimestamp': 1647424261559, + 'requestTimestamp': 1647424261189, + 'bidder': 'smartyads', + 'adUnitCode': 'tag_200124_banner', + 'timeToRespond': 370, + 'pbLg': '5.00', + 'pbMg': '20.00', + 'pbHg': '20.00', + 'pbAg': '20.00', + 'pbDg': '20.00', + 'pbCg': '20.000000', + 'size': '300x600', + 'adserverTargeting': { + 'hb_bidder': 'smartyads', + 'hb_adid': '65d16ef039a97a', + 'hb_pb': '20.000000', + 'hb_size': '300x600', + 'hb_source': 'client', + 'hb_format': 'banner', + 'hb_adomain': 'example.com' + } + } + ], + 'winningBids': [ + + ], + 'timeout': 1000 + }; + + let bidWon = { + 'bidderCode': 'smartyads', + 'width': 970, + 'height': 250, + 'statusMessage': 'Bid available', + 'adId': '65d16ef039a97a', + 'requestId': '2bd3e8ff8a113f', + 'transactionId': '8b2a8629-d1ea-4bb1-aff0-e335b96dd002', + 'auctionId': '1e8b993d-8f0a-4232-83eb-3639ddf3a44b', + 'mediaType': 'banner', + 'source': 'client', + 'cpm': 27.4276, + 'creativeId': '158533702', + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 2000, + 'ad': 'some html', + 'meta': { + 'advertiserDomains': [ + 'example.com' + ] + }, + 'renderer': 'something', + 'originalCpm': 25.02521, + 'originalCurrency': 'EUR', + 'responseTimestamp': 1647424261558, + 'requestTimestamp': 1647424261189, + 'bidder': 'smartyads', + 'adUnitCode': 'tag_200123_banner', + 'timeToRespond': 369, + 'originalBidder': 'smartyads', + 'pbLg': '5.00', + 'pbMg': '20.00', + 'pbHg': '20.00', + 'pbAg': '20.00', + 'pbDg': '20.00', + 'pbCg': '20.000000', + 'size': '970x250', + 'adserverTargeting': { + 'hb_bidder': 'smartyads', + 'hb_adid': '65d16ef039a97a', + 'hb_pb': '20.000000', + 'hb_size': '970x250', + 'hb_source': 'client', + 'hb_format': 'banner', + 'hb_adomain': 'example.com' + }, + 'status': 'rendered', + 'params': [ + { + 'placementId': 123456 + } + ] + }; + + let renderData = { + 'doc': { + 'location': { + 'ancestorOrigins': { + '0': 'http://localhost:9999' + }, + 'href': 'http://localhost:9999/integrationExamples/gpt/gdpr_hello_world.html?pbjs_debug=true', + 'origin': 'http://localhost:9999', + 'protocol': 'http:', + 'host': 'localhost:9999', + 'hostname': 'localhost', + 'port': '9999', + 'pathname': '/integrationExamples/gpt/gdpr_hello_world.html', + 'search': '?pbjs_debug=true', + 'hash': '' + }, + '__reactEvents$ffsiznmtn3p': {} + }, + 'bid': { + 'bidderCode': 'smartyads', + 'width': 300, + 'height': 250, + 'statusMessage': 'Bid available', + 'adId': '3c81d46b03abb', + 'requestId': '2be8997209a61c', + 'transactionId': 'b3091239-660a-4b13-94a1-1737e11743c5', + 'adUnitId': '8097f75e-8c3c-4b3e-aebb-b261caa5e331', + 'auctionId': '5c0d10bf-96cb-4afa-92ac-2ef75470da22', + 'mediaType': 'banner', + 'source': 'client', + 'ad': "
\"test
", + 'cpm': 0.1, + 'ttl': 120, + 'creativeId': '123', + 'netRevenue': true, + 'currency': 'USD', + 'dealId': 'HASH', + 'sid': 1234, + 'meta': { + 'advertiserDomains': [ + 'smartyads.com' + ], + 'dchain': { + 'ver': '1.0', + 'complete': 0, + 'nodes': [ + { + 'name': 'smartyads' + } + ] + } + }, + 'metrics': { + 'requestBids.usp': 0.20000000298023224, + 'requestBids.gdpr': 67.19999999925494, + 'requestBids.fpd': 4.299999997019768, + 'requestBids.validate': 0.29999999701976776, + 'requestBids.makeRequests': 1.800000000745058, + 'requestBids.total': 740.9000000022352, + 'requestBids.callBids': 663, + 'adapter.client.validate': 0, + 'adapters.client.smartyads.validate': 0, + 'adapter.client.buildRequests': 1, + 'adapters.client.smartyads.buildRequests': 1, + 'adapter.client.total': 661.6999999992549, + 'adapters.client.smartyads.total': 661.6999999992549, + 'adapter.client.net': 657.8999999985099, + 'adapters.client.smartyads.net': 657.8999999985099, + 'adapter.client.interpretResponse': 0, + 'adapters.client.smartyads.interpretResponse': 0, + 'addBidResponse.validate': 0.19999999925494194, + 'addBidResponse.categoryTranslation': 0, + 'addBidResponse.dchain': 0.10000000149011612, + 'addBidResponse.dsa': 0, + 'addBidResponse.multibid': 0, + 'addBidResponse.total': 1.5999999977648258, + 'render.pending': 368.80000000074506, + 'render.e2e': 1109.7000000029802 + }, + 'adapterCode': 'smartyads', + 'originalCpm': 0.1, + 'originalCurrency': 'USD', + 'responseTimestamp': 1715350155081, + 'requestTimestamp': 1715350154420, + 'bidder': 'smartyads', + 'adUnitCode': 'div-gpt-ad-1460505748561-0', + 'timeToRespond': 661, + 'pbLg': '0.00', + 'pbMg': '0.10', + 'pbHg': '0.10', + 'pbAg': '0.10', + 'pbDg': '0.10', + 'pbCg': '', + 'size': '300x250', + 'adserverTargeting': { + 'hb_bidder': 'smartyads', + 'hb_adid': '3c81d46b03abb', + 'hb_pb': '0.10', + 'hb_size': '300x250', + 'hb_deal': 'HASH', + 'hb_source': 'client', + 'hb_format': 'banner', + 'hb_adomain': 'smartyads.com', + 'hb_crid': '123' + }, + 'latestTargetedAuctionId': '5c0d10bf-96cb-4afa-92ac-2ef75470da22', + 'status': 'rendered', + 'params': [ + { + 'sourceid': '983', + 'host': 'prebid', + 'accountid': '18349', + 'traffic': 'banner' + } + ] + } + }; + + after(function () { + smartyadsAnalytics.disableAnalytics(); + }); + + describe('main test', function () { + beforeEach(function () { + sinon.stub(events, 'getEvents').returns([]); + sinon.spy(smartyadsAnalytics, 'track'); + }); + + afterEach(function () { + events.getEvents.restore(); + smartyadsAnalytics.disableAnalytics(); + smartyadsAnalytics.track.restore(); + }); + + it('test auctionEnd', function () { + adapterManager.registerAnalyticsAdapter({ + code: 'smartyads', + adapter: smartyadsAnalytics + }); + + adapterManager.enableAnalytics({ + provider: 'smartyads', + }); + + events.emit(EVENTS.AUCTION_END, auctionEnd); + expect(server.requests.length).to.equal(1); + let message = JSON.parse(server.requests[0].requestBody); + expect(message).to.have.property('auctionData'); + expect(message).to.have.property('eventType').and.to.equal(EVENTS.AUCTION_END); + expect(message.auctionData).to.have.property('auctionId'); + expect(message.auctionData.bidderRequests).to.have.length(1); + }); + + it('test bidWon', function() { + adapterManager.registerAnalyticsAdapter({ + code: 'smartyads', + adapter: smartyadsAnalytics + }); + + adapterManager.enableAnalytics({ + provider: 'smartyads', + }); + + events.emit(EVENTS.BID_WON, bidWon); + expect(server.requests.length).to.equal(1); + let message = JSON.parse(server.requests[0].requestBody); + expect(message).to.have.property('eventType').and.to.equal(EVENTS.BID_WON); + expect(message).to.have.property('bid'); + expect(message.bid).to.have.property('bidder').and.to.equal('smartyads'); + expect(message.bid).to.have.property('cpm').and.to.equal(bidWon.cpm); + }); + + it('test adRender', function() { + adapterManager.registerAnalyticsAdapter({ + code: 'smartyads', + adapter: smartyadsAnalytics + }); + + adapterManager.enableAnalytics({ + provider: 'smartyads', + }); + + events.emit(EVENTS.AD_RENDER_SUCCEEDED, renderData); + expect(server.requests.length).to.equal(1); + let message = JSON.parse(server.requests[0].requestBody); + expect(message).to.have.property('eventType').and.to.equal(EVENTS.AD_RENDER_SUCCEEDED); + expect(message).to.have.property('renderData'); + expect(message.renderData).to.have.property('doc'); + expect(message.renderData).to.have.property('doc'); + expect(message.renderData).to.have.property('bid'); + expect(message.renderData.bid).to.have.property('adId').and.to.equal(renderData.bid.adId); + }); + }); +}); diff --git a/test/spec/modules/smartyadsBidAdapter_spec.js b/test/spec/modules/smartyadsBidAdapter_spec.js index 1b592e142c3..65480ee11e6 100644 --- a/test/spec/modules/smartyadsBidAdapter_spec.js +++ b/test/spec/modules/smartyadsBidAdapter_spec.js @@ -61,12 +61,10 @@ describe('SmartyadsAdapter', function () { it('Returns valid data if array of bids is valid', function () { let data = serverRequest.data; expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements', 'coppa', 'eeid', 'ifa'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'host', 'page', 'placements', 'coppa', 'eeid', 'ifa'); expect(data.deviceWidth).to.be.a('number'); expect(data.deviceHeight).to.be.a('number'); expect(data.coppa).to.be.a('number'); - expect(data.language).to.be.a('string'); - expect(data.secure).to.be.within(0, 1); expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); let placement = data['placements'][0]; @@ -126,8 +124,8 @@ describe('SmartyadsAdapter', function () { expect(dataItem.width).to.equal(300); expect(dataItem.height).to.equal(250); expect(dataItem.ad).to.equal('Test'); - expect(dataItem.meta).to.have.property('advertiserDomains') - expect(dataItem.meta.advertiserDomains).to.deep.equal(['example.com']); + expect(dataItem.meta).to.have.property('advertiserDomains'); + expect(dataItem.meta.advertiserDomains).to.be.an('array'); expect(dataItem.ttl).to.equal(120); expect(dataItem.creativeId).to.equal('2'); expect(dataItem.netRevenue).to.be.true; @@ -152,7 +150,7 @@ describe('SmartyadsAdapter', function () { let dataItem = videoResponses[0]; expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); expect(dataItem.requestId).to.equal('23fhj33i987f'); expect(dataItem.cpm).to.equal(0.5); expect(dataItem.vastUrl).to.equal('test.com'); @@ -183,7 +181,7 @@ describe('SmartyadsAdapter', function () { expect(nativeResponses).to.be.an('array').that.is.not.empty; let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta'); expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') expect(dataItem.requestId).to.equal('23fhj33i987f'); expect(dataItem.cpm).to.equal(0.4); @@ -263,7 +261,7 @@ describe('SmartyadsAdapter', function () { }); }); describe('getUserSyncs', function () { - const syncUrl = 'https://as.ck-ie.com/prebidjs?p=7c47322e527cf8bdeb7facc1bb03387a&gdpr=0&gdpr_consent=&type=iframe&us_privacy=&gpp='; + const syncUrl = 'https://as.ck-ie.com/prebidjs?p=7c47322e527cf8bdeb7facc1bb03387a/iframe?pbjs=1&coppa=0'; const syncOptions = { iframeEnabled: true }; @@ -277,79 +275,4 @@ describe('SmartyadsAdapter', function () { ]); }); }); - - describe('onBidWon', function () { - it('should exists', function () { - expect(spec.onBidWon).to.exist.and.to.be.a('function'); - }); - - it('should send a valid bid won notice', function () { - const bid = { - 'c': 'o', - 'm': 'prebid', - 'secret_key': 'prebid_js', - 'winTest': '1', - 'postData': [{ - 'bidder': 'smartyads', - 'params': [ - {'host': 'prebid', - 'accountid': '123', - 'sourceid': '12345' - }] - }] - }; - spec.onBidWon(bid); - expect(server.requests.length).to.equal(1); - }); - }); - - describe('onTimeout', function () { - it('should exists', function () { - expect(spec.onTimeout).to.exist.and.to.be.a('function'); - }); - - it('should send a valid bid timeout notice', function () { - const bid = { - 'c': 'o', - 'm': 'prebid', - 'secret_key': 'prebid_js', - 'bidTimeout': '1', - 'postData': [{ - 'bidder': 'smartyads', - 'params': [ - {'host': 'prebid', - 'accountid': '123', - 'sourceid': '12345' - }] - }] - }; - spec.onTimeout(bid); - expect(server.requests.length).to.equal(1); - }); - }); - - describe('onBidderError', function () { - it('should exists', function () { - expect(spec.onBidderError).to.exist.and.to.be.a('function'); - }); - - it('should send a valid bidder error notice', function () { - const bid = { - 'c': 'o', - 'm': 'prebid', - 'secret_key': 'prebid_js', - 'bidderError': '1', - 'postData': [{ - 'bidder': 'smartyads', - 'params': [ - {'host': 'prebid', - 'accountid': '123', - 'sourceid': '12345' - }] - }] - }; - spec.onBidderError(bid); - expect(server.requests.length).to.equal(1); - }); - }); }); diff --git a/test/spec/modules/smartytechBidAdapter_spec.js b/test/spec/modules/smartytechBidAdapter_spec.js index 6b3147859bf..3b6d5d0c5fc 100644 --- a/test/spec/modules/smartytechBidAdapter_spec.js +++ b/test/spec/modules/smartytechBidAdapter_spec.js @@ -204,7 +204,11 @@ function mockResponseData(requestData) { creativeId: `creative-id-${index}`, cpm: Math.floor(Math.random() * 100), currency: `UAH-${rndIndex}`, - mediaType: mediaType + mediaType: mediaType, + meta: { + primaryCatId: 'IAB2-2', + secondaryCatIds: ['IAB2-14', 'IAB2-6'] + } }; }); return { diff --git a/test/spec/modules/smilewantedBidAdapter_spec.js b/test/spec/modules/smilewantedBidAdapter_spec.js index 99c4034610f..1c71c7bee07 100644 --- a/test/spec/modules/smilewantedBidAdapter_spec.js +++ b/test/spec/modules/smilewantedBidAdapter_spec.js @@ -76,6 +76,49 @@ const DISPLAY_REQUEST_WITH_POSITION_TYPE = [{ }, }]; +const SCHAIN = { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + }, + { + 'asi': 'exchange2.com', + 'sid': 'abcd', + 'hp': 1, + 'rid': 'bid-request-2', + 'name': 'intermediary', + 'domain': 'intermediary.com' + } + ] +}; + +const DISPLAY_REQUEST_WITH_SCHAIN = [{ + adUnitCode: 'sw_300x250', + bidId: '12345', + sizes: [ + [300, 250], + [300, 200] + ], + bidder: 'smilewanted', + params: { + zoneId: 1, + }, + requestId: 'request_abcd1234', + ortb2Imp: { + ext: { + tid: 'trans_abcd1234', + } + }, + schain: SCHAIN, +}]; + const BID_RESPONSE_DISPLAY = { body: { cpm: 3, @@ -580,8 +623,21 @@ describe('smilewantedBidAdapterTests', function () { expect(requestContent).to.have.property('positionType').and.to.equal('infeed'); }); + it('SmileWanted - Verify if schain is well passed', function () { + const request = spec.buildRequests(DISPLAY_REQUEST_WITH_SCHAIN, {}); + const requestContent = JSON.parse(request[0].data); + expect(requestContent).to.have.property('schain').and.to.equal('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com,!exchange2.com,abcd,1,bid-request-2,intermediary,intermediary.com,'); + }); + + it('SmileWanted - Verify user sync - empty data', function () { + let syncs = spec.getUserSyncs({iframeEnabled: true}, {}, {}, null); + expect(syncs).to.have.lengthOf(1); + expect(syncs[0].type).to.equal('iframe'); + expect(syncs[0].url).to.equal('https://csync.smilewanted.com'); + }); + it('SmileWanted - Verify user sync', function () { - var syncs = spec.getUserSyncs({iframeEnabled: true}, {}, { + let syncs = spec.getUserSyncs({iframeEnabled: true}, {}, { consentString: 'foo' }, '1NYN'); expect(syncs).to.have.lengthOf(1); diff --git a/test/spec/modules/sonobiAnalyticsAdapter_spec.js b/test/spec/modules/sonobiAnalyticsAdapter_spec.js deleted file mode 100644 index c34de91dd9f..00000000000 --- a/test/spec/modules/sonobiAnalyticsAdapter_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import sonobiAnalytics, {DEFAULT_EVENT_URL} from 'modules/sonobiAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; -import { EVENTS } from 'src/constants.js'; - -let events = require('src/events'); -let adapterManager = require('src/adapterManager').default; - -describe('Sonobi Prebid Analytic', function () { - var clock; - - describe('enableAnalytics', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - clock = sinon.useFakeTimers(Date.now()); - }); - - afterEach(function () { - events.getEvents.restore(); - clock.restore(); - }); - - after(function () { - sonobiAnalytics.disableAnalytics(); - }); - - it('should catch all events', function (done) { - const initOptions = { - pubId: 'A3B254F', - siteId: '1234', - delay: 100 - }; - - sonobiAnalytics.enableAnalytics(initOptions) - - const bid = { - bidderCode: 'sonobi_test_bid', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '1234', - auctionId: '13', - responseTimestamp: 1496410856397, - requestTimestamp: 1496410856295, - cpm: 1.13, - bidder: 'sonobi', - adUnitCode: 'dom-sample-id', - timeToRespond: 100, - placementCode: 'placementtest' - }; - - // Step 1: Initialize adapter - adapterManager.enableAnalytics({ - provider: 'sonobi', - options: initOptions - }); - - // Step 2: Send init auction event - events.emit(EVENTS.AUCTION_INIT, { config: initOptions, auctionId: '13', timestamp: Date.now() }); - - expect(sonobiAnalytics.initOptions).to.have.property('pubId', 'A3B254F'); - expect(sonobiAnalytics.initOptions).to.have.property('siteId', '1234'); - expect(sonobiAnalytics.initOptions).to.have.property('delay', 100); - // Step 3: Send bid requested event - events.emit(EVENTS.BID_REQUESTED, { bids: [bid], auctionId: '13' }); - - // Step 4: Send bid response event - events.emit(EVENTS.BID_RESPONSE, bid); - - // Step 5: Send bid won event - events.emit(EVENTS.BID_WON, bid); - - // Step 6: Send bid timeout event - events.emit(EVENTS.BID_TIMEOUT, { auctionId: '13' }); - - // Step 7: Send auction end event - events.emit(EVENTS.AUCTION_END, { auctionId: '13', bidsReceived: [bid] }); - - clock.tick(5000); - const req = server.requests.find(req => req.url.indexOf(DEFAULT_EVENT_URL) !== -1); - expect(JSON.parse(req.requestBody)).to.have.length(3) - done(); - }); - }); -}); diff --git a/test/spec/modules/sovrnAnalyticsAdapter_spec.js b/test/spec/modules/sovrnAnalyticsAdapter_spec.js deleted file mode 100644 index 7945bdc9910..00000000000 --- a/test/spec/modules/sovrnAnalyticsAdapter_spec.js +++ /dev/null @@ -1,530 +0,0 @@ -import sovrnAnalyticsAdapter from '../../../modules/sovrnAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import adaptermanager from 'src/adapterManager.js'; -import {server} from 'test/mocks/xhr.js'; -import {expectEvents, fireEvents} from '../../helpers/analytics.js'; -import { EVENTS } from 'src/constants.js'; - -var assert = require('assert'); - -let events = require('src/events'); - -/** - * Emit analytics events - * @param {Array} eventType - array of objects to define the events that will fire - * @param {object} event - key is eventType, value is event - * @param {string} auctionId - the auction id to attached to the events - */ -function emitEvent(eventType, event, auctionId) { - event.auctionId = auctionId; - events.emit(EVENTS[eventType], event); -} - -let auctionStartTimestamp = Date.now(); -let timeout = 3000; -let auctionInit = { - timestamp: auctionStartTimestamp, - timeout: timeout -}; -let bidderCode = 'sovrn'; -let bidderRequestId = '123bri'; -let adUnitCode = 'div'; -let adUnitCode2 = 'div2'; -let bidId = 'bidid'; -let bidId2 = 'bidid2'; -let tId = '7aafa3ee-a80a-46d7-a4a0-cbcba463d97a'; -let tId2 = '99dca3ee-a80a-46d7-a4a0-cbcba463d97e'; -let bidRequested = { - auctionStart: auctionStartTimestamp, - bidderCode: bidderCode, - bidderRequestId: bidderRequestId, - bids: [ - { - adUnitCode: adUnitCode, - bidId: bidId, - bidder: bidderCode, - bidderRequestId: '10340af0c7dc72', - sizes: [[300, 250]], - startTime: auctionStartTimestamp + 100, - transactionId: tId - }, - { - adUnitCode: adUnitCode2, - bidId: bidId2, - bidder: bidderCode, - bidderRequestId: '10340af0c7dc72', - sizes: [[300, 250]], - startTime: auctionStartTimestamp + 100, - transactionId: tId2 - } - ], - doneCbCallCount: 1, - start: auctionStartTimestamp, - timeout: timeout -}; -let bidResponse = { - bidderCode: bidderCode, - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '3870e27a5752fb', - mediaType: 'banner', - source: 'client', - requestId: bidId, - cpm: 0.8584999918937682, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ad: '
divvy mcdiv
', - ttl: 60000, - responseTimestamp: auctionStartTimestamp + 150, - requestTimestamp: auctionStartTimestamp + 100, - bidder: bidderCode, - adUnitCode: adUnitCode, - timeToRespond: 50, - pbLg: '0.50', - pbMg: '0.80', - pbHg: '0.85', - pbAg: '0.85', - pbDg: '0.85', - pbCg: '', - size: '300x250', - adserverTargeting: { - hb_bidder: bidderCode, - hb_adid: '3870e27a5752fb', - hb_pb: '0.85' - }, - status: 'rendered' -}; - -let bidResponse2 = { - bidderCode: bidderCode, - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '9999e27a5752fb', - mediaType: 'banner', - source: 'client', - requestId: bidId2, - cpm: 0.12, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ad: '
divvy mcdiv
', - ttl: 60000, - responseTimestamp: auctionStartTimestamp + 150, - requestTimestamp: auctionStartTimestamp + 100, - bidder: bidderCode, - adUnitCode: adUnitCode2, - timeToRespond: 50, - pbLg: '0.10', - pbMg: '0.10', - pbHg: '0.10', - pbAg: '0.10', - pbDg: '0.10', - pbCg: '', - size: '300x250', - adserverTargeting: { - hb_bidder: bidderCode, - hb_adid: '9999e27a5752fb', - hb_pb: '0.10' - }, - status: 'rendered' -}; -let bidAdjustment = {}; -for (var k in bidResponse) bidAdjustment[k] = bidResponse[k]; -bidAdjustment.cpm = 0.8; -let bidAdjustmentNoMatchingRequest = { - bidderCode: 'not-sovrn', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '1', - mediaType: 'banner', - source: 'client', - requestId: '1', - cpm: 0.10, - creativeId: '', - dealId: null, - currency: 'USD', - netRevenue: true, - ad: '
divvy mcdiv
', - ttl: 60000, - responseTimestamp: auctionStartTimestamp + 150, - requestTimestamp: auctionStartTimestamp + 100, - bidder: 'not-sovrn', - adUnitCode: '', - timeToRespond: 50, - pbLg: '0.00', - pbMg: '0.10', - pbHg: '0.10', - pbAg: '0.10', - pbDg: '0.10', - pbCg: '', - size: '300x250', - adserverTargeting: { - hb_bidder: 'not-sovrn', - hb_adid: '1', - hb_pb: '0.10' - }, -}; -let bidResponseNoMatchingRequest = bidAdjustmentNoMatchingRequest; - -describe('Sovrn Analytics Adapter', function () { - beforeEach(() => { - sinon.stub(events, 'getEvents').returns([]); - }); - afterEach(() => { - events.getEvents.restore(); - }); - - describe('enableAnalytics ', function () { - beforeEach(() => { - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - - it('should catch all events if affiliate id present', function () { - adaptermanager.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - expectEvents().to.beTrackedBy(sovrnAnalyticsAdapter.track); - }); - - it('should catch no events if no affiliate id', function () { - adaptermanager.enableAnalytics({ - provider: 'sovrn', - options: { - } - }); - fireEvents(); - sinon.assert.callCount(sovrnAnalyticsAdapter.track, 0); - }); - }); - - describe('sovrnAnalyticsAdapter ', function() { - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should have correct type', function () { - assert.equal(sovrnAnalyticsAdapter.getAdapterType(), 'endpoint') - }) - }); - - describe('auction data collector ', function() { - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should create auctiondata record from init ', function () { - let auctionId = '123.123.123.123'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - assert(currentAuction); - let expectedTimeOutData = { - buffer: config.getConfig('timeoutBuffer'), - bidder: config.getConfig('bidderTimeout'), - }; - expect(currentAuction.auction.timeouts).to.deep.equal(expectedTimeOutData); - assert.equal(currentAuction.auction.payload, 'auction'); - assert.equal(currentAuction.auction.priceGranularity, config.getConfig('priceGranularity')) - assert.equal(currentAuction.auction.auctionId, auctionId); - assert.equal(currentAuction.auction.sovrnId, 123); - }); - it('should create a bidrequest object ', function() { - let auctionId = '234.234.234.234'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - assert(currentAuction); - let requests = currentAuction.auction.requests; - assert(requests); - assert.equal(requests.length, 1); - assert.equal(requests[0].bidderCode, bidderCode); - assert.equal(requests[0].bidderRequestId, bidderRequestId); - assert.equal(requests[0].timeout, timeout); - let bids = requests[0].bids; - assert(bids); - assert.equal(bids.length, 2); - assert.equal(bids[0].bidId, bidId); - assert.equal(bids[0].bidder, bidderCode); - assert.equal(bids[0].transactionId, tId); - assert.equal(bids[0].sizes.length, 1); - assert.equal(bids[0].sizes[0][0], 300); - assert.equal(bids[0].sizes[0][1], 250); - expect(requests[0]).to.not.have.property('doneCbCallCount'); - expect(requests[0]).to.not.have.property('auctionId'); - }); - it('should add results to the bid with response ', function () { - let auctionId = '345.345.345.345'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_RESPONSE', bidResponse, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - let returnedBid = currentAuction.auction.requests[0].bids[0]; - assert.equal(returnedBid.bidId, bidId); - assert.equal(returnedBid.bidder, bidderCode); - assert.equal(returnedBid.transactionId, tId); - assert.equal(returnedBid.sizes.length, 1); - assert.equal(returnedBid.sizes[0][0], 300); - assert.equal(returnedBid.sizes[0][1], 250); - assert.equal(returnedBid.adserverTargeting.hb_adid, '3870e27a5752fb'); - assert.equal(returnedBid.adserverTargeting.hb_bidder, bidderCode); - assert.equal(returnedBid.adserverTargeting.hb_pb, '0.85'); - assert.equal(returnedBid.cpm, 0.8584999918937682); - }); - it('should add new unsynced bid if no request exists for response ', function () { - let auctionId = '456.456.456.456'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_RESPONSE', bidResponseNoMatchingRequest, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - let requests = currentAuction.auction.requests; - assert(requests); - assert.equal(requests.length, 1); - let bidRequest = requests[0].bids[0]; - expect(bidRequest).to.not.have.property('adserverTargeting'); - expect(bidRequest).to.not.have.property('cpm'); - expect(currentAuction.auction.unsynced[0]).to.deep.equal(bidResponseNoMatchingRequest); - }); - it('should adjust the bid ', function () { - let auctionId = '567.567.567.567'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_ADJUSTMENT', bidResponse, auctionId); - emitEvent('BID_RESPONSE', bidAdjustment, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - let returnedBid = currentAuction.auction.requests[0].bids[0]; - assert.equal(returnedBid.cpm, 0.8); - assert.equal(returnedBid.originalValues.cpm, 0.8584999918937682); - }); - }); - describe('auction data send ', function() { - let expectedPostBody = { - sovrnId: 123, - auctionId: '678.678.678.678', - payload: 'auction', - priceGranularity: 'medium', - }; - let expectedRequests = { - bidderCode: 'sovrn', - bidderRequestId: '123bri', - timeout: 3000 - }; - let expectedBids = { - adUnitCode: 'div', - bidId: 'bidid', - bidder: 'sovrn', - bidderRequestId: '10340af0c7dc72', - transactionId: '7aafa3ee-a80a-46d7-a4a0-cbcba463d97a', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '3870e27a5752fb', - mediaType: 'banner', - source: 'client', - cpm: 0.8584999918937682, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60000, - timeToRespond: 50, - size: '300x250', - status: 'rendered', - isAuctionWinner: true - }; - let SecondAdUnitExpectedBids = { - adUnitCode: 'div2', - bidId: 'bidid2', - bidder: 'sovrn', - bidderRequestId: '10340af0c7dc72', - transactionId: '99dca3ee-a80a-46d7-a4a0-cbcba463d97e', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '9999e27a5752fb', - mediaType: 'banner', - source: 'client', - cpm: 0.12, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60000, - timeToRespond: 50, - size: '300x250', - status: 'rendered', - isAuctionWinner: true - }; - let expectedAdServerTargeting = { - hb_bidder: 'sovrn', - hb_adid: '3870e27a5752fb', - hb_pb: '0.85' - }; - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should send auction data ', function () { - let auctionId = '678.678.678.678'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_RESPONSE', bidResponse, auctionId); - emitEvent('BID_RESPONSE', bidResponse2, auctionId) - emitEvent('AUCTION_END', {}, auctionId); - let requestBody = JSON.parse(server.requests[0].requestBody); - let requestsFromRequestBody = requestBody.requests[0]; - let bidsFromRequests = requestsFromRequestBody.bids[0]; - expect(requestBody).to.deep.include(expectedPostBody); - expect(requestBody.timeouts).to.deep.equal({buffer: 400, bidder: 3000}); - expect(requestsFromRequestBody).to.deep.include(expectedRequests); - expect(bidsFromRequests).to.deep.include(expectedBids); - let bidsFromRequests2 = requestsFromRequestBody.bids[1]; - expect(bidsFromRequests2).to.deep.include(SecondAdUnitExpectedBids); - expect(bidsFromRequests.adserverTargeting).to.deep.include(expectedAdServerTargeting); - }); - }); - describe('bid won data send ', function() { - let auctionId = '789.789.789.789'; - let creativeId = 'cridprebidrtb'; - let requestId = 'requestId69'; - let bidWonEvent = { - ad: 'html', - adId: 'adId', - adUnitCode: adUnitCode, - auctionId: auctionId, - bidder: bidderCode, - bidderCode: bidderCode, - cpm: 1.01, - creativeId: creativeId, - currency: 'USD', - height: 250, - mediaType: 'banner', - requestId: requestId, - size: '300x250', - source: 'client', - status: 'rendered', - statusMessage: 'Bid available', - timeToRespond: 421, - ttl: 60, - width: 300 - }; - let expectedBidWonBody = { - sovrnId: 123, - payload: 'winner' - }; - let expectedWinningBid = { - bidderCode: bidderCode, - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: 'adId', - mediaType: 'banner', - source: 'client', - requestId: requestId, - cpm: 1.01, - creativeId: creativeId, - currency: 'USD', - ttl: 60, - auctionId: auctionId, - bidder: bidderCode, - adUnitCode: adUnitCode, - timeToRespond: 421, - size: '300x250', - }; - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should send bid won data ', function () { - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_WON', bidWonEvent, auctionId); - let requestBody = JSON.parse(server.requests[0].requestBody); - expect(requestBody).to.deep.include(expectedBidWonBody); - expect(requestBody.winningBid).to.deep.include(expectedWinningBid); - }); - }); - describe('Error Tracking', function() { - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics() - sovrnAnalyticsAdapter.track.restore() - }); - it('should send an error message when a bid is received for a closed auction', function() { - let auctionId = '678.678.678.678'; - emitEvent('AUCTION_INIT', auctionInit, auctionId) - emitEvent('BID_REQUESTED', bidRequested, auctionId) - emitEvent('AUCTION_END', {}, auctionId) - server.requests[0].respond(200) - emitEvent('BID_RESPONSE', bidResponse, auctionId) - let requestBody = JSON.parse(server.requests[1].requestBody) - expect(requestBody.payload).to.equal('error') - expect(requestBody.message).to.include('Event Received after Auction Close Auction Id') - }) - }) -}) diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js index 10f5ab8e89d..2d6af1f964f 100644 --- a/test/spec/modules/sovrnBidAdapter_spec.js +++ b/test/spec/modules/sovrnBidAdapter_spec.js @@ -243,7 +243,7 @@ describe('sovrnBidAdapter', function() { it('when FLEDGE is enabled, should send ortb2imp.ext.ae', function () { const bidderRequest = { ...baseBidderRequest, - fledgeEnabled: true + paapi: {enabled: true} } const bidRequest = { ...baseBidRequest, @@ -273,7 +273,9 @@ describe('sovrnBidAdapter', function() { it('when FLEDGE is enabled, but env is malformed, should not send ortb2imp.ext.ae', function () { const bidderRequest = { ...baseBidderRequest, - fledgeEnabled: true + paapi: { + enabled: true + } } const bidRequest = { ...baseBidRequest, @@ -968,9 +970,9 @@ describe('sovrnBidAdapter', function() { it('should return valid fledge auction configs alongside bids', function () { const result = spec.interpretResponse(fledgeResponse) expect(result).to.have.property('bids') - expect(result).to.have.property('fledgeAuctionConfigs') - expect(result.fledgeAuctionConfigs.length).to.equal(2) - expect(result.fledgeAuctionConfigs).to.deep.equal(expectedFledgeResponse) + expect(result).to.have.property('paapi') + expect(result.paapi.length).to.equal(2) + expect(result.paapi).to.deep.equal(expectedFledgeResponse) }) it('should ignore empty fledge auction configs array', function () { const result = spec.interpretResponse(emptyFledgeResponse) diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js deleted file mode 100644 index ec99d0f7142..00000000000 --- a/test/spec/modules/spotxBidAdapter_spec.js +++ /dev/null @@ -1,711 +0,0 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {loadExternalScript} from '../../../src/adloader'; -import {isRendererRequired} from '../../../src/Renderer'; -import {spec, GOOGLE_CONSENT} from 'modules/spotxBidAdapter.js'; - -describe('the spotx adapter', function () { - function getValidBidObject() { - return { - bidId: 123, - mediaTypes: { - video: { - playerSize: [['300', '200']] - } - }, - params: { - channel_id: 12345, - } - }; - }; - - describe('isBidRequestValid', function() { - let bid; - - beforeEach(function() { - bid = getValidBidObject(); - }); - - it('should fail validation if the bid isn\'t defined or not an object', function() { - let result = spec.isBidRequestValid(); - - expect(result).to.equal(false); - - result = spec.isBidRequestValid('not an object'); - - expect(result).to.equal(false); - }); - - it('should succeed validation with all the right parameters', function() { - expect(spec.isBidRequestValid(getValidBidObject())).to.equal(true); - }); - - it('should succeed validation with mediaType and outstream_function or outstream_options', function() { - bid.mediaType = 'video'; - bid.params.outstream_function = 'outstream_func'; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - - delete bid.params.outstream_function; - bid.params.outstream_options = { - slot: 'elemID' - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should succeed with ad_unit outstream and outstream function set', function() { - bid.params.ad_unit = 'outstream'; - bid.params.outstream_function = function() {}; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should succeed with ad_unit outstream, options set for outstream and slot provided', function() { - bid.params.ad_unit = 'outstream'; - bid.params.outstream_options = {slot: 'ad_container_id'}; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should fail without a channel_id', function() { - delete bid.params.channel_id; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail without playerSize', function() { - delete bid.mediaTypes.video.playerSize; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail without video', function() { - delete bid.mediaTypes.video; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail with ad_unit outstream but no options set for outstream', function() { - bid.params.ad_unit = 'outstream'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail with ad_unit outstream, options set for outstream but no slot provided', function() { - bid.params.ad_unit = 'outstream'; - bid.params.outstream_options = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function() { - let bid, bidRequestObj; - - beforeEach(function() { - bid = getValidBidObject(); - bidRequestObj = { - refererInfo: { - page: 'prebid.js' - } - }; - }); - - it('should build a very basic request', function() { - let request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.method).to.equal('POST'); - expect(request.url).to.equal('https://search.spotxchange.com/openrtb/2.3/dados/12345?src_sys=prebid'); - expect(request.bidRequest).to.equal(bidRequestObj); - expect(request.data.id).to.equal(12345); - expect(request.data.ext.wrap_response).to.equal(1); - expect(request.data.imp.id).to.match(/\d+/); - expect(request.data.imp.secure).to.equal(0); - expect(request.data.imp.video).to.deep.equal({ - ext: { - sdk_name: 'Prebid 1+', - versionOrtb: '2.3' - }, - h: '200', - mimes: [ - 'application/javascript', - 'video/mp4', - 'video/webm' - ], - w: '300' - }); - expect(request.data.site).to.deep.equal({ - content: 'content', - id: '', - page: 'prebid.js' - }); - }); - - it('should change request parameters based on options sent', function() { - let request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.imp.video.ext).to.deep.equal({ - sdk_name: 'Prebid 1+', - versionOrtb: '2.3' - }); - - bid.params = { - channel_id: 54321, - ad_mute: 1, - hide_skin: 1, - ad_volume: 1, - ad_unit: 'incontent', - outstream_options: {foo: 'bar'}, - outstream_function: '987', - custom: {bar: 'foo'}, - start_delay: true, - number_of_ads: 2, - spotx_all_google_consent: 1, - min_duration: 5, - max_duration: 10, - placement_type: 1, - position: 1 - }; - - bid.userIdAsEids = [{ - source: 'adserver.org', - uids: [{id: 'tdid_1', atype: 1, ext: {rtiPartner: 'TDID'}}] - }, - { - source: 'id5-sync.com', - uids: [{id: 'id5id_1', ext: {}}] - }, - { - source: 'uidapi.com', - uids: [{ - id: 'uid_1', - atype: 3 - }] - } - ]; - - bid.crumbs = { - pubcid: 'pubcid_1' - }; - - bid.schain = { - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - } - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.id).to.equal(54321); - expect(request.data.imp.video).to.contain({ - minduration: 5, - maxduration: 10 - }) - expect(request.data.imp.video.ext).to.deep.equal({ - ad_volume: 1, - hide_skin: 1, - ad_unit: 'incontent', - outstream_options: {foo: 'bar'}, - outstream_function: '987', - custom: {bar: 'foo'}, - sdk_name: 'Prebid 1+', - versionOrtb: '2.3', - placement: 1, - pos: 1 - }); - - expect(request.data.imp.video.startdelay).to.equal(1); - expect(request.data.ext).to.deep.equal({ - number_of_ads: 2, - wrap_response: 1 - }); - expect(request.data.user.ext).to.deep.equal({ - consented_providers_settings: GOOGLE_CONSENT, - eids: [{ - source: 'adserver.org', - uids: [{ - id: 'tdid_1', - atype: 1, - ext: { - rtiPartner: 'TDID' - } - }] - }, { - source: 'id5-sync.com', - uids: [{ - id: 'id5id_1', - ext: {} - }] - }, - { - source: 'uidapi.com', - uids: [{ - id: 'uid_1', - atype: 3, - ext: { - rtiPartner: 'UID2' - } - }] - }], - fpc: 'pubcid_1' - }); - - expect(request.data.source).to.deep.equal({ - ext: { - schain: { - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - } - } - }) - }); - - it('should process premarket bids', function() { - let request; - sinon.stub(Date, 'now').returns(1000); - - bid.params.pre_market_bids = [{ - vast_url: 'prebid.js', - deal_id: '123abc', - price: 12, - currency: 'USD' - }]; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.imp.video.ext.pre_market_bids).to.deep.equal([ - { - 'cur': 'USD', - 'ext': { - 'event_log': [ - {} - ] - }, - 'id': '123abc', - 'seatbid': [ - { - 'bid': [ - { - 'adm': 'prebid.js', - 'dealid': '123abc', - 'impid': 1000, - 'price': 12, - } - ] - } - ] - } - ]); - Date.now.restore(); - }); - - it('should pass GDPR params', function() { - let request; - - bidRequestObj.gdprConsent = { - consentString: 'consent123', - gdprApplies: true - }; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.regs.ext.gdpr).to.equal(1); - expect(request.data.user.ext.consent).to.equal('consent123'); - }); - - it('should pass CCPA us_privacy string', function() { - let request; - - bidRequestObj.uspConsent = '1YYY' - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); - }); - - it('should pass both GDPR params and CCPA us_privacy', function() { - let request; - - bidRequestObj.gdprConsent = { - consentString: 'consent123', - gdprApplies: true - }; - bidRequestObj.uspConsent = '1YYY' - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.regs.ext.gdpr).to.equal(1); - expect(request.data.user.ext.consent).to.equal('consent123'); - expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); - }); - - it('should pass min and max duration params', function() { - let request; - - bid.params.min_duration = 3 - bid.params.max_duration = 15 - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.imp.video.minduration).to.equal(3); - expect(request.data.imp.video.maxduration).to.equal(15); - }); - - it('should pass placement_type and position params', function() { - let request; - - bid.params.placement_type = 2 - bid.params.position = 5 - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.imp.video.ext.placement).to.equal(2); - expect(request.data.imp.video.ext.pos).to.equal(5); - }); - - it('should pass page param and override refererInfo.referer', function() { - let request; - - bid.params.page = 'https://example.com'; - - let origGetConfig = config.getConfig; - sinon.stub(config, 'getConfig').callsFake(function (key) { - if (key === 'pageUrl') { - return 'https://www.spotx.tv'; - } - return origGetConfig.apply(config, arguments); - }); - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.site.page).to.equal('https://example.com'); - config.getConfig.restore(); - }); - - it('should use refererInfo.referer if no page is passed', function() { - let request; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.site.page).to.equal('prebid.js'); - }); - - it('should set ext.wrap_response to 0 when cache url is set and ignoreBidderCacheKey is true', function() { - let request; - - let origGetConfig = config.getConfig; - sinon.stub(config, 'getConfig').callsFake(function (key) { - if (key === 'cache') { - return { - url: 'prebidCacheLocation', - ignoreBidderCacheKey: true - }; - } - if (key === 'cache.url') { - return 'prebidCacheLocation'; - } - if (key === 'cache.ignoreBidderCacheKey') { - return true; - } - return origGetConfig.apply(config, arguments); - }); - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.ext.wrap_response).to.equal(0); - config.getConfig.restore(); - }); - - it('should pass price floor in USD from the floors module if available', function () { - let request; - - bid.getFloor = function () { - return { currency: 'USD', floor: 3 }; - } - - bid.params.price_floor = 2; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.imp.bidfloor).to.equal(3); - }); - - it('should not pass price floor if price floors module gives a non-USD currency', function () { - let request; - - bid.getFloor = function () { - return { currency: 'EUR', floor: 3 }; - } - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.imp.bidfloor).to.be.undefined; - }); - - it('if floors module is not available, should pass price floor from price_floor param if available', function () { - let request; - - bid.params.price_floor = 2; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.imp.bidfloor).to.equal(2); - }); - }); - - describe('interpretResponse', function() { - let serverResponse, bidderRequestObj; - - beforeEach(function() { - bidderRequestObj = { - bidRequest: { - bids: [{ - mediaTypes: { - video: { - playerSize: [['400', '300']] - } - }, - bidId: 123, - params: { - ad_unit: 'outstream', - player_width: 400, - player_height: 300, - content_page_url: 'prebid.js', - ad_mute: 1, - outstream_options: {foo: 'bar'}, - outstream_function: 'function' - } - }, { - mediaTypes: { - video: { - playerSize: [['200', '100']] - } - }, - bidId: 124, - params: { - player_width: 200, - player_height: 100, - content_page_url: 'prebid.js', - ad_mute: 1, - outstream_options: {foo: 'bar'}, - outstream_function: 'function' - } - }] - } - }; - - serverResponse = { - body: { - id: 12345, - seatbid: [{ - bid: [{ - impid: 123, - cur: 'USD', - price: 12, - adomain: ['abc.com'], - crid: 321, - w: 400, - h: 300, - ext: { - cache_key: 'cache123', - slot: 'slot123' - } - }, { - impid: 124, - cur: 'USD', - price: 13, - adomain: ['def.com'], - w: 200, - h: 100, - ext: { - cache_key: 'cache124', - slot: 'slot124' - } - }] - }] - } - }; - }); - - it('should return an array of bid responses', function() { - let responses = spec.interpretResponse(serverResponse, bidderRequestObj); - expect(responses).to.be.an('array').with.length(2); - expect(responses[0].cache_key).to.equal('cache123'); - expect(responses[0].channel_id).to.equal(12345); - expect(responses[0].meta.advertiserDomains[0]).to.equal('abc.com'); - expect(responses[0].cpm).to.equal(12); - expect(responses[0].creativeId).to.equal(321); - expect(responses[0].currency).to.equal('USD'); - expect(responses[0].height).to.equal(300); - expect(responses[0].mediaType).to.equal('video'); - expect(responses[0].netRevenue).to.equal(true); - expect(responses[0].requestId).to.equal(123); - expect(responses[0].ttl).to.equal(360); - expect(responses[0].vastUrl).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); - expect(responses[0].videoCacheKey).to.equal('cache123'); - expect(responses[0].width).to.equal(400); - expect(responses[1].cache_key).to.equal('cache124'); - expect(responses[1].channel_id).to.equal(12345); - expect(responses[1].cpm).to.equal(13); - expect(responses[1].meta.advertiserDomains[0]).to.equal('def.com'); - expect(responses[1].creativeId).to.equal(''); - expect(responses[1].currency).to.equal('USD'); - expect(responses[1].height).to.equal(100); - expect(responses[1].mediaType).to.equal('video'); - expect(responses[1].netRevenue).to.equal(true); - expect(responses[1].requestId).to.equal(124); - expect(responses[1].ttl).to.equal(360); - expect(responses[1].vastUrl).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache124'); - expect(responses[1].videoCacheKey).to.equal('cache124'); - expect(responses[1].width).to.equal(200); - }); - - it('should set the renderer attached to the bid to render immediately', function () { - var renderer = spec.interpretResponse(serverResponse, bidderRequestObj)[0].renderer, - hasRun = false; - expect(renderer._render).to.be.a('function'); - renderer._render = () => { - hasRun = true; - } - renderer.render(); - expect(hasRun).to.equal(true); - }); - - it('should include the url property on the renderer for Prebid Core checks', function () { - var renderer = spec.interpretResponse(serverResponse, bidderRequestObj)[0].renderer; - expect(isRendererRequired(renderer)).to.be.true; - }); - }); - - describe('outstreamRender', function() { - let serverResponse, bidderRequestObj; - - beforeEach(function() { - sinon.stub(window.document, 'getElementById').returns({ - clientWidth: 200, - appendChild: sinon.stub().callsFake(function(script) {}) - }); - sinon.stub(window.document, 'createElement').returns({ - setAttribute: function () {} - }); - bidderRequestObj = { - bidRequest: { - bids: [{ - mediaTypes: { - video: { - playerSize: [['400', '300']] - } - }, - bidId: 123, - params: { - ad_unit: 'outstream', - player_width: 400, - player_height: 300, - content_page_url: 'prebid.js', - outstream_options: { - ad_mute: 1, - foo: 'bar', - slot: 'slot123', - playersize_auto_adapt: true, - custom_override: { - digitrust_opt_out: 1, - vast_url: 'bad_vast' - } - }, - } - }] - } - }; - - serverResponse = { - body: { - id: 12345, - seatbid: [{ - bid: [{ - impid: 123, - cur: 'USD', - price: 12, - crid: 321, - w: 400, - h: 300, - ext: { - cache_key: 'cache123', - slot: 'slot123' - } - }] - }] - } - }; - }); - afterEach(function () { - window.document.getElementById.restore(); - window.document.createElement.restore(); - }); - - it('should attempt to insert the EASI script', function() { - window.document.getElementById.restore(); - sinon.stub(window.document, 'getElementById').returns({ - appendChild: sinon.stub().callsFake(function(script) {}), - }); - let responses = spec.interpretResponse(serverResponse, bidderRequestObj); - let attrs; - - responses[0].renderer.render(responses[0]); - expect(loadExternalScript.called).to.be.true; - attrs = valuesToString(loadExternalScript.args[0][4]); - - expect(attrs['data-spotx_channel_id']).to.equal('12345'); - expect(attrs['data-spotx_vast_url']).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); - expect(attrs['data-spotx_ad_unit']).to.equal('incontent'); - expect(attrs['data-spotx_collapse']).to.equal('0'); - expect(attrs['data-spotx_autoplay']).to.equal('1'); - expect(attrs['data-spotx_blocked_autoplay_override_mode']).to.equal('1'); - expect(attrs['data-spotx_video_slot_can_autoplay']).to.equal('1'); - expect(attrs['data-spotx_digitrust_opt_out']).to.equal('1'); - expect(attrs['data-spotx_content_width']).to.equal('400'); - expect(attrs['data-spotx_content_height']).to.equal('300'); - expect(attrs['data-spotx_ad_mute']).to.equal('1'); - }); - - it('should append into an iframe', function() { - bidderRequestObj.bidRequest.bids[0].params.outstream_options.in_iframe = 'iframeId'; - window.document.getElementById.restore(); - sinon.stub(window.document, 'getElementById').returns({ - nodeName: 'IFRAME', - clientWidth: 200, - appendChild: sinon.stub().callsFake(function(script) {}), - contentDocument: {nodeName: 'IFRAME'} - }); - - let responses = spec.interpretResponse(serverResponse, bidderRequestObj); - responses[0].renderer.render(responses[0]); - expect(loadExternalScript.called).to.be.true; - expect(loadExternalScript.args[0][3].nodeName).to.equal('IFRAME'); - }); - - it('should adjust width and height to match slot clientWidth if playersize_auto_adapt is used', function() { - let responses = spec.interpretResponse(serverResponse, bidderRequestObj); - - responses[0].renderer.render(responses[0]); - expect(loadExternalScript.args[0][4]['data-spotx_content_width']).to.equal('200'); - expect(loadExternalScript.args[0][4]['data-spotx_content_height']).to.equal('150'); - }); - - it('should use a default 4/3 ratio if playersize_auto_adapt is used and response does not contain width or height', function() { - delete serverResponse.body.seatbid[0].bid[0].w; - delete serverResponse.body.seatbid[0].bid[0].h; - let responses = spec.interpretResponse(serverResponse, bidderRequestObj); - - responses[0].renderer.render(responses[0]); - expect(loadExternalScript.args[0][4]['data-spotx_content_width']).to.equal('200'); - expect(loadExternalScript.args[0][4]['data-spotx_content_height']).to.equal('150'); - }); - }); -}); - -function valuesToString(obj) { - let newObj = {}; - for (let prop in obj) { - newObj[prop] = '' + obj[prop]; - } - return newObj; -} diff --git a/test/spec/modules/staqAnalyticsAdapter_spec.js b/test/spec/modules/staqAnalyticsAdapter_spec.js deleted file mode 100644 index 3f28098e1d1..00000000000 --- a/test/spec/modules/staqAnalyticsAdapter_spec.js +++ /dev/null @@ -1,302 +0,0 @@ -import analyticsAdapter, { ExpiringQueue, getUmtSource, storage } from 'modules/staqAnalyticsAdapter.js'; -import { expect } from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import { EVENTS } from 'src/constants.js'; - -const events = require('../../../src/events'); - -const DIRECT = { - source: '(direct)', - medium: '(direct)', - campaign: '(direct)' -}; -const REFERRER = { - source: 'lander.com', - medium: '(referral)', - campaign: '(referral)', - content: '/lander.html' -}; -const GOOGLE_ORGANIC = { - source: 'google', - medium: '(organic)', - campaign: '(organic)' -}; -const CAMPAIGN = { - source: 'adkernel', - medium: 'email', - campaign: 'new_campaign', - c1: '1', - c2: '2', - c3: '3', - c4: '4', - c5: '5' - -}; -describe('', function() { - let sandbox; - - before(function() { - sandbox = sinon.sandbox.create(); - }); - - after(function() { - sandbox.restore(); - analyticsAdapter.disableAnalytics(); - }); - - describe('UTM source parser', function() { - let stubSetItem; - let stubGetItem; - - before(function() { - stubSetItem = sandbox.stub(storage, 'setItem'); - stubGetItem = sandbox.stub(storage, 'getItem'); - }); - - afterEach(function() { - sandbox.reset(); - }); - - it('should parse first direct visit as (direct)', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://example.com'); - expect(source).to.be.eql(DIRECT); - }); - - it('should parse visit from google as organic', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://example.com', 'https://www.google.com/search?q=pikachu'); - expect(source).to.be.eql(GOOGLE_ORGANIC); - }); - - it('should parse referral visit', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://example.com', 'https://lander.com/lander.html'); - expect(source).to.be.eql(REFERRER); - }); - - it('should parse referral visit from same domain as direct', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://lander.com/news.html', 'https://lander.com/lander.html'); - expect(source).to.be.eql(DIRECT); - }); - - it('should parse campaign visit', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://lander.com/index.html?utm_campaign=new_campaign&utm_source=adkernel&utm_medium=email&utm_c1=1&utm_c2=2&utm_c3=3&utm_c4=4&utm_c5=5'); - expect(source).to.be.eql(CAMPAIGN); - }); - }); - - describe('ExpiringQueue', function() { - let timer; - before(function() { - timer = sandbox.useFakeTimers(0); - }); - after(function() { - timer.restore(); - }); - - it('should notify after timeout period', (done) => { - let queue = new ExpiringQueue(() => { - let elements = queue.popAll(); - expect(elements).to.be.eql([1, 2, 3, 4]); - elements = queue.popAll(); - expect(elements).to.have.lengthOf(0); - expect(Date.now()).to.be.equal(200); - done(); - }, 100); - - queue.push(1); - setTimeout(() => { - queue.push([2, 3]); - timer.tick(50); - }, 50); - setTimeout(() => { - queue.push([4]); - timer.tick(100); - }, 100); - timer.tick(50); - }); - }); - - const REQUEST = { - bidderCode: 'AppNexus', - bidderName: 'AppNexus', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - bidderRequestId: '1a6fc81528d0f6', - bids: [{ - bidder: 'AppNexus', - params: {}, - adUnitCode: 'container-1', - transactionId: 'de90df62-7fd0-4fbc-8787-92d133a7dc06', - sizes: [ - [300, 250] - ], - bidId: '208750227436c1', - bidderRequestId: '1a6fc81528d0f6', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f' - }], - auctionStart: 1509369418387, - timeout: 3000, - start: 1509369418389 - }; - - const RESPONSE = { - bidderCode: 'AppNexus', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '208750227436c1', - mediaType: 'banner', - cpm: 0.015, - ad: '', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - responseTimestamp: 1509369418832, - requestTimestamp: 1509369418389, - bidder: 'AppNexus', - adUnitCode: 'container-1', - timeToRespond: 443, - size: '300x250' - }; - - const bidTimeoutArgsV1 = [{ - bidId: '2baa51527bd015', - bidderCode: 'AppNexus', - adUnitCode: 'container-1', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - }, - { - bidId: '6fe3b4c2c23092', - bidderCode: 'AppNexus', - adUnitCode: 'container-2', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - }]; - - describe('Analytics adapter', function() { - let ajaxStub; - let timer; - - before(function() { - ajaxStub = sandbox.stub(analyticsAdapter, 'ajaxCall'); - timer = sandbox.useFakeTimers(0); - }); - - beforeEach(function() { - sandbox.stub(events, 'getEvents').callsFake(() => { - return [] - }); - }); - - afterEach(function() { - events.getEvents.restore(); - }); - - it('should be configurable', function() { - adapterManager.registerAnalyticsAdapter({ - code: 'staq', - adapter: analyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'staq', - options: { - connId: 777, - queueTimeout: 1000, - url: 'https://localhost/prebid' - } - }); - - expect(analyticsAdapter.context).to.have.property('connectionId', 777); - }); - - it('should handle auction init event', function() { - events.emit(EVENTS.AUCTION_INIT, { config: {}, timeout: 3000 }); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(1); - expect(ev[0]).to.be.eql({ event: 'auctionInit', auctionId: undefined }); - }); - - it('should handle bid request event', function() { - events.emit(EVENTS.BID_REQUESTED, REQUEST); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(2); - expect(ev[1]).to.be.eql({ - adUnitCode: 'container-1', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - event: 'bidRequested', - adapter: 'AppNexus', - bidderName: 'AppNexus' - }); - }); - - it('should handle bid response event', function() { - events.emit(EVENTS.BID_RESPONSE, RESPONSE); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(3); - expect(ev[2]).to.be.eql({ - adId: '208750227436c1', - event: 'bidResponse', - adapter: 'AppNexus', - bidderName: 'AppNexus', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - adUnitCode: 'container-1', - cpm: 0.015, - timeToRespond: 0.443, - height: 250, - width: 300, - bidWon: false, - }); - }); - - it('should handle timeouts properly', function() { - events.emit(EVENTS.BID_TIMEOUT, bidTimeoutArgsV1); - - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(5); // remember, we added 2 timeout events - expect(ev[3]).to.be.eql({ - adapter: 'AppNexus', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f', - bidderName: 'AppNexus', - event: 'adapterTimedOut' - }) - }); - - it('should handle winning bid', function() { - events.emit(EVENTS.BID_WON, RESPONSE); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(6); - expect(ev[5]).to.be.eql({ - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - adId: '208750227436c1', - event: 'bidWon', - adapter: 'AppNexus', - bidderName: 'AppNexus', - adUnitCode: 'container-1', - cpm: 0.015, - height: 250, - width: 300, - bidWon: true, - }); - }); - - it('should handle auction end event', function() { - timer.tick(447); - events.emit(EVENTS.AUCTION_END, RESPONSE); - let ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(0); - expect(ajaxStub.calledOnce).to.be.equal(true); - let firstCallArgs0 = ajaxStub.firstCall.args[0]; - ev = JSON.parse(firstCallArgs0); - const ev6 = ev['events'][6]; - expect(ev['connId']).to.be.eql(777); - expect(ev6.auctionId).to.be.eql('5018eb39-f900-4370-b71e-3bb5b48d324f'); - expect(ev6.event).to.be.eql('auctionEnd'); - }); - }); -}); diff --git a/test/spec/modules/stroeerCoreBidAdapter_spec.js b/test/spec/modules/stroeerCoreBidAdapter_spec.js index a8295c197ef..66e2b575b8b 100644 --- a/test/spec/modules/stroeerCoreBidAdapter_spec.js +++ b/test/spec/modules/stroeerCoreBidAdapter_spec.js @@ -169,16 +169,17 @@ describe('stroeerCore bid adapter', function () { } function setupSingleWindow(sandBox, placementElements = [createElement('div-1', 17), createElement('div-2', 54)]) { - const win = createWindow('http://www.xyz.com/', { - parent: win, top: win, frameElement: createElement(undefined, 304), placementElements: placementElements + let singleWin = null + singleWin = createWindow('http://www.xyz.com/', { + parent: singleWin, top: singleWin, frameElement: createElement(undefined, 304), placementElements: placementElements }); - win.innerHeight = 200; + singleWin.innerHeight = 200; - sandBox.stub(utils, 'getWindowSelf').returns(win); - sandBox.stub(utils, 'getWindowTop').returns(win); + sandBox.stub(utils, 'getWindowSelf').returns(singleWin); + sandBox.stub(utils, 'getWindowTop').returns(singleWin); - return win; + return singleWin; } function setupNestedWindows(sandBox, placementElements = [createElement('div-1', 17), createElement('div-2', 54)]) { diff --git a/test/spec/modules/stvBidAdapter_spec.js b/test/spec/modules/stvBidAdapter_spec.js index 3ef865ed2f1..099d8d33b02 100644 --- a/test/spec/modules/stvBidAdapter_spec.js +++ b/test/spec/modules/stvBidAdapter_spec.js @@ -30,12 +30,12 @@ describe('stvAdapter', function() { }); it('should return false when required params are not passed', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'someIncorrectParam': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/symitriDapRtdProvider_spec.js b/test/spec/modules/symitriDapRtdProvider_spec.js new file mode 100644 index 00000000000..79ebfd707c7 --- /dev/null +++ b/test/spec/modules/symitriDapRtdProvider_spec.js @@ -0,0 +1,600 @@ +import {config} from 'src/config.js'; +import { + dapUtils, + generateRealTimeData, + symitriDapRtdSubmodule, + storage, DAP_MAX_RETRY_TOKENIZE, DAP_SS_ID, DAP_TOKEN, DAP_MEMBERSHIP, DAP_ENCRYPTED_MEMBERSHIP +} from 'modules/symitriDapRtdProvider.js'; +import {server} from 'test/mocks/xhr.js'; +import {hook} from '../../../src/hook.js'; +const responseHeader = {'Content-Type': 'application/json'}; + +describe('symitriDapRtdProvider', function() { + const testReqBidsConfigObj = { + adUnits: [ + { + bids: ['bid1', 'bid2'] + } + ] + }; + + const onDone = function() { return true }; + + const sampleGdprConsentConfig = { + 'gdpr': { + 'consentString': null, + 'vendorData': {}, + 'gdprApplies': true + } + }; + + const sampleUspConsentConfig = { + 'usp': '1YYY' + }; + + const sampleIdentity = { + type: 'dap-signature:1.0.0' + }; + + const cmoduleConfig = { + 'name': 'dap', + 'waitForIt': true, + 'params': { + 'apiHostname': 'prebid.dap.akadns.net', + 'apiVersion': 'x1', + 'domain': 'prebid.org', + 'identityType': 'dap-signature:1.0.0', + 'segtax': 503 + } + } + + const emoduleConfig = { + 'name': 'dap', + 'waitForIt': true, + 'params': { + 'apiHostname': 'prebid.dap.akadns.net', + 'apiVersion': 'x1', + 'domain': 'prebid.org', + 'identityType': 'dap-signature:1.0.0', + 'segtax': 504 + } + } + + const sampleConfig = { + 'api_hostname': 'prebid.dap.akadns.net', + 'api_version': 'x1', + 'domain': 'prebid.org', + 'segtax': 503, + 'identity': sampleIdentity + } + + const esampleConfig = { + 'api_hostname': 'prebid.dap.akadns.net', + 'api_version': 'x1', + 'domain': 'prebid.org', + 'segtax': 504, + 'identity': sampleIdentity + } + let cacheExpiry = Math.round(Date.now() / 1000.0) + 300; // in seconds + const sampleCachedToken = {'expires_at': cacheExpiry, 'token': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..6buzBd2BjtgoyaNbHN8YnQ.l38avCfm3sYNy798-ETYOugz0cOx1cCkjACkAhYszxzrZ0sUJ0AiF-NdDXVTiTyp2Ih3vCWKzS0rKJ8lbS1zhyEVWVu91QwtwseM2fBbwA5ggAgBEo5wV-IXqDLPxVnxsPF0D3hP6cNCiH9Q2c-vULfsLhMhG5zvvZDPBbn4hUY5fKB8LoCBTF9rbuuWGYK1nramnb4AlS5UK82wBsHQea1Ou_Kp5wWCMNZ6TZk5qKIuRBfPIAhQblWvHECaHXkg1wyoM9VASs_yNhne7RR-qkwzbFiPFiMJibNOt9hF3_vPDJO5-06ZBjRTP1BllYGWxI-uQX6InzN18Wtun2WHqg.63sH0SNlIRcsK57v0pMujfB_nhU8Y5CuQbsHqH5MGoM'}; + const cachedEncryptedMembership = {'expires_at': cacheExpiry, 'encryptedSegments': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoic29tZXNlY3JldGludmF1bHQifQ..IvnIUQDqWBVYIS0gbcE9bw.Z4NZGvtogWaWlGH4e-GdYKe_PUc15M2x3Bj85rMWsN1A17mIxQIMOfg2hsQ2tgieLu5LggWPmsFu1Wbph6P0k3kOu1dVReoIhOHzxw50rP0DLHKaEZ5mLMJ7Lcosvwh4miIfFuCHlsX7J0sFgOTAp0zGo1S_UsHLtev1JflhjoSB0AoX95ALbAnyctirPuLJM8gZ1vXTiZ01jpvucGyR1lM4cWjPOeD8jPtgwaPGgSRZXE-3X2Cqy7z4Giam5Uqu74LPWTBuKtUQTGyAXA5QJoP7xwTbsU4O1f69lu3fWNqC92GijeTH1A4Zd_C-WXxWuQlDEURjlkWQoaqTHka2OqlnwukEQIf_v0r5KQQX64CTLhEUH91jeD0-E9ClcIP7pwOLxxqiKoaBmx8Mrnm_6Agj5DtTA1rusy3AL63sI_rsUxrmLrVt0Wft4aCfRkW8QpQxu8clFdOmce0NNCGeBCyCPVw9d9izrILlXJ6rItU2cpFrcbz8uw2otamF5eOFCOY3IzHedWVNNuKHFIUVC_xYSlsYvQ8f2QIP1eiMbmukcuPzmTzjw1h1_7IKaj-jJkXrnrY-TdDgX_4-_Z3rmbpXK2yTR7dBrsg-ubqFbgbKic1b4zlQEO_LbBlgPl3DYdWEuJ8CY2NUt1GfpATQGsufS2FTY1YGw_gkPe3q04l_cgLafDoxHvHh_t_0ZgPjciW82gThB_kN4RP7Mc3krVcXl_P6N1VbV07xyx0hCyVsrrxbLslI8q9wYDiLGci7mNmByM5j7SXV9jPwwPkHtn0HfMJlw2PFbIDPjgG3h7sOyLcBIJTTvuUIgpHPIkRWLIl_4FlIucXbJ7orW2nt5BWleBVHgumzGcnl9ZNcZb3W-dsdYPSOmuj0CY28MRTP2oJ1rzLInbDDpIRffJBtR7SS4nYyy7Vi09PtBigod5YNz1Q0WDSJxr8zeH_aKFaXInw7Bfo_U0IAcLiRgcT0ogsMLeQRjRFy27mr4XNJv3NtHhbdjDAwF2aClCktXyXbQaVdsPH2W71v6m2Q9rB5GQWOktw2s5f-4N1-_EBPGq6TgjF-aJZP22MJVwp1pimT50DfOzoeEqDwi862NNwNNoHmcObH0ZfwAXlhRxsgupNBe20-MNNABj2Phlfv4DUrtQbMdfCnNiypzNCmoTb7G7c_o5_JUwoV_GVkwUtvmi_IUm05P4GeMASSUw8zDKVRAj9h31C2cabM8RjMHGhkbCWpUP2pcz9zlJ7Y76Dh3RLnctfTw7DG9U4w4UlaxNZOgLUiSrGwfyapuSiuGUpuOJkBBLiHmEqAGI5C8oJpcVRccNlHxJAYowgXyFopD5Fr-FkXmv8KMkS0h5C9F6KihmDt5sqDD0qnjM0hHJgq01l7wjVnhEmPpyD-6auFQ-xDnbh1uBOJ_0gCVbRad--FSa5p-dXenggegRxOvZXJ0iAtM6Fal5Og-RCjexIHa9WhVbXhQBJpkSTWwAajZJ64eQ.yih49XB51wE-Xob7COT9OYqBrzBmIMVCQbLFx2UdzkI'}; + const cachedMembership = {'expires_at': cacheExpiry, 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..QwvU5h0NVJYaJbs5EqWCKA.XNaJHSlnsH8P-yBIr3gIEqavLONWDIFyj7QCHFwJVkwXH_EYkxrk0_26b0uMPzfJp5URnqxKZusMH9DzEJsmj8EMrKQv1y3IYYMsW5_0BdP5bcAWfG6fzOqtMOwLiYRkYiQOqn1ZVGzhovheHWEmNr2_oCY0LvAr3iN1eG_K-l-bBKvBWnwvuuGKquUfCqO8NMMq6wtkecEXM9blqFRZ7oNYmW2aIG7qcHUsrUW7HMr9Ev2Ik0sIeEUsOYrgf_X_VA64RgKSTRugS9FupMv1p54JkHokwduF9pOFmW8QLQi8itFogKGbbgvOTNnmahxQUX5FcrjjYLqHwKqC8htLdlHnO5LWU9l4A7vLXrRurvoSnh0cAJy0GsdoyEwTqR9bwVFHoPquxlJjQ4buEd7PIxpBj9Qg9oOPH3b2upbMTu5CQ9oj526eXPhP5G54nwGklm2AZ3Vggd7jCQJn45Jjiq0iIfsXAtpqS2BssCLBN8WhmUTnStK8m5sux6WUBdrpDESQjPj-EEHVS-DB5rA7icRUh6EzRxzen2rndvHvnwVhSG_l6cwPYuJ0HE0KBmYHOoqNpKwzoGiKFHrf4ReA06iWB3V2TEGJucGujhtQ9_18WwHCeJ1XtQiiO1eqa3tp5MwAbFXawVFl3FFOBgadrPyvGmkmUJ6FCLU2MSwHiYZmANMnJsokFX_6DwoAgO3U_QnvEHIVSvefc7ReeJ8fBDdmrH3LtuLrUpXsvLvEIMQdWQ_SXhjKIi7tOODR8CfrhUcdIjsp3PZs1DpuOcDB6YJKbGnKZTluLUJi3TyHgyi-DHXdTm-jSE5i_DYJGW-t2Gf23FoQhexv4q7gdrfsKfcRJNrZLp6Gd6jl4zHhUtY.nprKBsy9taQBk6dCPbA7BFF0CiGhQOEF_MazZ2bedqk', 'cohorts': ['9', '11', '13']}; + const rtdUserObj = { + name: 'www.dataprovider3.com', + ext: { + taxonomyname: 'iab_audience_taxonomy' + }, + segment: [ + { + id: '1918' + }, + { + id: '1939' + } + ] + }; + + const encRtdUserObj = { + name: 'www.dataprovider3.com', + ext: { + segtax: 504, + taxonomyname: 'iab_audience_taxonomy' + }, + segment: [] + }; + + const cachedRtd = { + rtd: { + ortb2: { + user: { + data: [rtdUserObj] + } + } + } + }; + + let membership = { + said: cachedMembership.said, + cohorts: cachedMembership.cohorts, + attributes: null + }; + let encMembership = { + encryptedSegments: cachedEncryptedMembership.encryptedSegments + }; + encRtdUserObj.segment.push({ id: encMembership.encryptedSegments }); + const cachedEncRtd = { + rtd: { + ortb2: { + user: { + data: [encRtdUserObj] + } + } + } + }; + + before(() => { + hook.ready(); + }); + + let ortb2, bidConfig; + + beforeEach(function() { + bidConfig = {ortb2Fragments: {}}; + ortb2 = bidConfig.ortb2Fragments.global = {}; + config.resetConfig(); + storage.removeDataFromLocalStorage(DAP_TOKEN); + storage.removeDataFromLocalStorage(DAP_MEMBERSHIP); + storage.removeDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP); + storage.removeDataFromLocalStorage(DAP_SS_ID); + }); + + afterEach(function () { + }); + + describe('symitriDapRtdSubmodule', function() { + it('successfully instantiates', function () { + expect(symitriDapRtdSubmodule.init()).to.equal(true); + }); + }); + + describe('Get Real-Time Data', function() { + it('gets rtd from local storage cache', function() { + let dapGetMembershipFromLocalStorageStub = sinon.stub(dapUtils, 'dapGetMembershipFromLocalStorage').returns(membership) + let dapGetRtdObjStub = sinon.stub(dapUtils, 'dapGetRtdObj').returns(cachedRtd) + let dapGetEncryptedMembershipFromLocalStorageStub = sinon.stub(dapUtils, 'dapGetEncryptedMembershipFromLocalStorage').returns(encMembership) + let dapGetEncryptedRtdObjStub = sinon.stub(dapUtils, 'dapGetEncryptedRtdObj').returns(cachedEncRtd) + let callDapApisStub = sinon.stub(dapUtils, 'callDapAPIs') + try { + storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(sampleCachedToken)); + expect(ortb2).to.eql({}); + generateRealTimeData(bidConfig, () => {}, emoduleConfig, {}); + + expect(ortb2.user.data).to.deep.include.members([encRtdUserObj]); + generateRealTimeData(bidConfig, () => {}, cmoduleConfig, {}); + expect(ortb2.user.data).to.deep.include.members([rtdUserObj]); + } finally { + dapGetRtdObjStub.restore() + dapGetMembershipFromLocalStorageStub.restore() + dapGetEncryptedRtdObjStub.restore() + dapGetEncryptedMembershipFromLocalStorageStub.restore() + callDapApisStub.restore() + } + }); + }); + + describe('calling DAP APIs', function() { + it('Calls callDapAPIs for unencrypted segments flow', function() { + storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(sampleCachedToken)); + let dapExtractExpiryFromTokenStub = sinon.stub(dapUtils, 'dapExtractExpiryFromToken').returns(cacheExpiry) + try { + expect(ortb2).to.eql({}); + dapUtils.callDapAPIs(bidConfig, () => {}, cmoduleConfig, {}); + let membership = {'cohorts': ['9', '11', '13'], 'said': 'sample-said'} + let membershipRequest = server.requests[0]; + membershipRequest.respond(200, responseHeader, JSON.stringify(membership)); + let tokenWithExpiry = 'Sample-token-with-exp' + let tokenizeRequest = server.requests[1]; + responseHeader['Symitri-DAP-Token'] = tokenWithExpiry; + tokenizeRequest.respond(200, responseHeader, JSON.stringify(tokenWithExpiry)); + let data = dapUtils.dapGetRtdObj(membership, cmoduleConfig.params.segtax); + expect(ortb2.user.data).to.deep.include.members(data.rtd.ortb2.user.data); + } finally { + dapExtractExpiryFromTokenStub.restore(); + } + }); + + it('Calls callDapAPIs for encrypted segments flow', function() { + storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(sampleCachedToken)); + let dapExtractExpiryFromTokenStub = sinon.stub(dapUtils, 'dapExtractExpiryFromToken').returns(cacheExpiry) + try { + expect(ortb2).to.eql({}); + dapUtils.callDapAPIs(bidConfig, () => {}, emoduleConfig, {}); + let encMembership = 'Sample-enc-token'; + let membershipRequest = server.requests[0]; + responseHeader['Symitri-DAP-Token'] = encMembership; + membershipRequest.respond(200, responseHeader, JSON.stringify(encMembership)); + let tokenWithExpiry = 'Sample-token-with-exp' + let tokenizeRequest = server.requests[1]; + responseHeader['Symitri-DAP-Token'] = tokenWithExpiry; + tokenizeRequest.respond(200, responseHeader, JSON.stringify(tokenWithExpiry)); + let data = dapUtils.dapGetEncryptedRtdObj({'encryptedSegments': encMembership}, emoduleConfig.params.segtax); + expect(ortb2.user.data).to.deep.include.members(data.rtd.ortb2.user.data); + } finally { + dapExtractExpiryFromTokenStub.restore(); + } + }); + }); + + describe('dapTokenize', function () { + it('dapTokenize error callback', function () { + let configAsync = JSON.parse(JSON.stringify(sampleConfig)); + let submoduleCallback = dapUtils.dapTokenize(configAsync, sampleIdentity, onDone, + function(token, status, xhr, onDone) { + }, + function(xhr, status, error, onDone) { + } + ); + let request = server.requests[0]; + request.respond(400, responseHeader, JSON.stringify('error')); + expect(submoduleCallback).to.equal(undefined); + }); + + it('dapTokenize success callback', function () { + let configAsync = JSON.parse(JSON.stringify(sampleConfig)); + let submoduleCallback = dapUtils.dapTokenize(configAsync, sampleIdentity, onDone, + function(token, status, xhr, onDone) { + }, + function(xhr, status, error, onDone) { + } + ); + let request = server.requests[0]; + request.respond(200, responseHeader, JSON.stringify('success')); + expect(submoduleCallback).to.equal(undefined); + }); + }); + + describe('dapTokenize and dapMembership incorrect params', function () { + it('Onerror and config are null', function () { + expect(dapUtils.dapTokenize(null, 'identity', onDone, null, null)).to.be.equal(undefined); + expect(dapUtils.dapMembership(null, 'identity', onDone, null, null)).to.be.equal(undefined); + expect(dapUtils.dapEncryptedMembership(null, 'identity', onDone, null, null)).to.be.equal(undefined); + const config = { + 'api_hostname': 'prebid.dap.akadns.net', + 'api_version': 1, + 'domain': '', + 'segtax': 503 + }; + const encConfig = { + 'api_hostname': 'prebid.dap.akadns.net', + 'api_version': 1, + 'domain': '', + 'segtax': 504 + }; + let identity = { + type: 'dap-signature:1.0.0' + }; + expect(dapUtils.dapTokenize(config, identity, onDone, null, null)).to.be.equal(undefined); + expect(dapUtils.dapMembership(config, 'token', onDone, null, null)).to.be.equal(undefined); + expect(dapUtils.dapEncryptedMembership(encConfig, 'token', onDone, null, null)).to.be.equal(undefined); + }); + }); + + describe('Getting dapTokenize, dapMembership and dapEncryptedMembership from localstorage', function () { + it('dapGetTokenFromLocalStorage success', function () { + storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(sampleCachedToken)); + expect(dapUtils.dapGetTokenFromLocalStorage(60)).to.be.equal(sampleCachedToken.token); + }); + + it('dapGetMembershipFromLocalStorage success', function () { + storage.setDataInLocalStorage(DAP_MEMBERSHIP, JSON.stringify(cachedMembership)); + expect(JSON.stringify(dapUtils.dapGetMembershipFromLocalStorage())).to.be.equal(JSON.stringify(membership)); + }); + + it('dapGetEncryptedMembershipFromLocalStorage success', function () { + storage.setDataInLocalStorage(DAP_ENCRYPTED_MEMBERSHIP, JSON.stringify(cachedEncryptedMembership)); + expect(JSON.stringify(dapUtils.dapGetEncryptedMembershipFromLocalStorage())).to.be.equal(JSON.stringify(encMembership)); + }); + }); + + describe('dapMembership', function () { + it('dapMembership success callback', function () { + let configAsync = JSON.parse(JSON.stringify(sampleConfig)); + let submoduleCallback = dapUtils.dapMembership(configAsync, 'token', onDone, + function(token, status, xhr, onDone) { + }, + function(xhr, status, error, onDone) { + } + ); + let request = server.requests[0]; + request.respond(200, responseHeader, JSON.stringify('success')); + expect(submoduleCallback).to.equal(undefined); + }); + + it('dapMembership error callback', function () { + let configAsync = JSON.parse(JSON.stringify(sampleConfig)); + let submoduleCallback = dapUtils.dapMembership(configAsync, 'token', onDone, + function(token, status, xhr, onDone) { + }, + function(xhr, status, error, onDone) { + } + ); + let request = server.requests[0]; + request.respond(400, responseHeader, JSON.stringify('error')); + expect(submoduleCallback).to.equal(undefined); + }); + }); + + describe('dapEncMembership', function () { + it('dapEncMembership success callback', function () { + let configAsync = JSON.parse(JSON.stringify(esampleConfig)); + let submoduleCallback = dapUtils.dapEncryptedMembership(configAsync, 'token', onDone, + function(token, status, xhr, onDone) { + }, + function(xhr, status, error, onDone) { + } + ); + let request = server.requests[0]; + request.respond(200, responseHeader, JSON.stringify('success')); + expect(submoduleCallback).to.equal(undefined); + }); + + it('dapEncMembership error callback', function () { + let configAsync = JSON.parse(JSON.stringify(esampleConfig)); + let submoduleCallback = dapUtils.dapEncryptedMembership(configAsync, 'token', onDone, + function(token, status, xhr, onDone) { + }, + function(xhr, status, error, onDone) { + } + ); + let request = server.requests[0]; + request.respond(400, responseHeader, JSON.stringify('error')); + expect(submoduleCallback).to.equal(undefined); + }); + }); + + describe('dapMembership', function () { + it('should invoke the getDapToken and getDapMembership', function () { + let membership = { + said: 'item.said1', + cohorts: 'item.cohorts', + attributes: null + }; + + let getDapMembershipStub = sinon.stub(dapUtils, 'dapGetMembershipFromLocalStorage').returns(membership); + let callDapApisStub = sinon.stub(dapUtils, 'callDapAPIs'); + try { + generateRealTimeData(testReqBidsConfigObj, onDone, cmoduleConfig); + expect(getDapMembershipStub.calledOnce).to.be.equal(true); + } finally { + getDapMembershipStub.restore(); + callDapApisStub.restore(); + } + }); + }); + + describe('dapEncMembership test', function () { + it('should invoke the getDapToken and getEncDapMembership', function () { + let encMembership = { + encryptedSegments: 'enc.seg', + }; + + let getDapEncMembershipStub = sinon.stub(dapUtils, 'dapGetEncryptedMembershipFromLocalStorage').returns(encMembership); + let callDapApisStub = sinon.stub(dapUtils, 'callDapAPIs'); + try { + generateRealTimeData(testReqBidsConfigObj, onDone, emoduleConfig); + expect(getDapEncMembershipStub.calledOnce).to.be.equal(true); + } finally { + getDapEncMembershipStub.restore(); + callDapApisStub.restore(); + } + }); + }); + + describe('dapGetRtdObj test', function () { + it('dapGetRtdObj', function () { + const config = { + apiHostname: 'prebid.dap.akadns.net', + apiVersion: 'x1', + domain: 'prebid.org', + segtax: 503 + }; + expect(dapUtils.dapRefreshMembership(ortb2, config, 'token', onDone)).to.equal(undefined) + const membership = {cohorts: ['1', '5', '7']} + expect(dapUtils.dapGetRtdObj(membership, config.segtax)).to.not.equal(undefined); + }); + }); + + describe('checkAndAddRealtimeData test', function () { + it('add realtime data for segtax 503 and 504', function () { + dapUtils.checkAndAddRealtimeData(ortb2, cachedEncRtd, 504); + dapUtils.checkAndAddRealtimeData(ortb2, cachedEncRtd, 504); + expect(ortb2.user.data).to.deep.include.members([encRtdUserObj]); + dapUtils.checkAndAddRealtimeData(ortb2, cachedRtd, 503); + expect(ortb2.user.data).to.deep.include.members([rtdUserObj]); + }); + }); + + describe('dapExtractExpiryFromToken test', function () { + it('test dapExtractExpiryFromToken function', function () { + let tokenWithoutExpiry = 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..6buzBd2BjtgoyaNbHN8YnQ.l38avCfm3sYNy798-ETYOugz0cOx1cCkjACkAhYszxzrZ0sUJ0AiF-NdDXVTiTyp2Ih3vCWKzS0rKJ8lbS1zhyEVWVu91QwtwseM2fBbwA5ggAgBEo5wV-IXqDLPxVnxsPF0D3hP6cNCiH9Q2c-vULfsLhMhG5zvvZDPBbn4hUY5fKB8LoCBTF9rbuuWGYK1nramnb4AlS5UK82wBsHQea1Ou_Kp5wWCMNZ6TZk5qKIuRBfPIAhQblWvHECaHXkg1wyoM9VASs_yNhne7RR-qkwzbFiPFiMJibNOt9hF3_vPDJO5-06ZBjRTP1BllYGWxI-uQX6InzN18Wtun2WHqg.63sH0SNlIRcsK57v0pMujfB_nhU8Y5CuQbsHqH5MGoM' + expect(dapUtils.dapExtractExpiryFromToken(tokenWithoutExpiry)).to.equal(undefined); + let tokenWithExpiry = 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIiwiZXhwIjoxNjQzODMwMzY5fQ..hTbcSQgmmO0HUJJrQ5fRHw.7zjrQXNNVkb-GD0ZhIVhEPcWbyaDBilHTWv-bp1lFZ9mdkSC0QbcAvUbYteiTD7ya23GUwcL2WOW8WgRSHaWHOJe0B5NDqfdUGTzElWfu7fFodRxRgGmwG8Rq5xxteFKLLGHLf1mFYRJKDtjtgajGNUKIDfn9AEt-c5Qz4KU8VolG_KzrLROx-f6Z7MnoPTcwRCj0WjXD6j2D6RAZ80-mKTNIsMIELdj6xiabHcjDJ1WzwtwCZSE2y2nMs451pSYp8W-bFPfZmDDwrkjN4s9ASLlIXcXgxK-H0GsiEbckQOZ49zsIKyFtasBvZW8339rrXi1js-aBh99M7aS5w9DmXPpUDmppSPpwkeTfKiqF0cQiAUq8tpeEQrGDJuw3Qt2.XI8h9Xw-VZj_NOmKtV19wLM63S4snos7rzkoHf9FXCw' + expect(dapUtils.dapExtractExpiryFromToken(tokenWithExpiry)).to.equal(1643830369); + }); + }); + + describe('dapRefreshToken test', function () { + it('test dapRefreshToken success response', function () { + dapUtils.dapRefreshToken(ortb2, sampleConfig, true, onDone) + let request = server.requests[0]; + responseHeader['Symitri-DAP-Token'] = sampleCachedToken.token; + request.respond(200, responseHeader, JSON.stringify(sampleCachedToken.token)); + expect(JSON.parse(storage.getDataFromLocalStorage(DAP_TOKEN)).token).to.be.equal(sampleCachedToken.token); + }); + + it('test dapRefreshToken success response with deviceid 100', function () { + dapUtils.dapRefreshToken(ortb2, esampleConfig, true, onDone) + let request = server.requests[0]; + responseHeader['Symitri-DAP-100'] = sampleCachedToken.token; + request.respond(200, responseHeader, ''); + expect(storage.getDataFromLocalStorage('dap_deviceId100')).to.be.equal(sampleCachedToken.token); + }); + + it('test dapRefreshToken success response with exp claim', function () { + dapUtils.dapRefreshToken(ortb2, sampleConfig, true, onDone) + let request = server.requests[0]; + let tokenWithExpiry = 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIiwiZXhwIjoxNjQzODMwMzY5fQ..hTbcSQgmmO0HUJJrQ5fRHw.7zjrQXNNVkb-GD0ZhIVhEPcWbyaDBilHTWv-bp1lFZ9mdkSC0QbcAvUbYteiTD7ya23GUwcL2WOW8WgRSHaWHOJe0B5NDqfdUGTzElWfu7fFodRxRgGmwG8Rq5xxteFKLLGHLf1mFYRJKDtjtgajGNUKIDfn9AEt-c5Qz4KU8VolG_KzrLROx-f6Z7MnoPTcwRCj0WjXD6j2D6RAZ80-mKTNIsMIELdj6xiabHcjDJ1WzwtwCZSE2y2nMs451pSYp8W-bFPfZmDDwrkjN4s9ASLlIXcXgxK-H0GsiEbckQOZ49zsIKyFtasBvZW8339rrXi1js-aBh99M7aS5w9DmXPpUDmppSPpwkeTfKiqF0cQiAUq8tpeEQrGDJuw3Qt2.XI8h9Xw-VZj_NOmKtV19wLM63S4snos7rzkoHf9FXCw' + responseHeader['Symitri-DAP-Token'] = tokenWithExpiry; + request.respond(200, responseHeader, JSON.stringify(tokenWithExpiry)); + expect(JSON.parse(storage.getDataFromLocalStorage(DAP_TOKEN)).expires_at).to.be.equal(1643830359); + }); + + it('test dapRefreshToken error response', function () { + storage.setDataInLocalStorage(DAP_TOKEN, JSON.stringify(sampleCachedToken)); + dapUtils.dapRefreshToken(ortb2, sampleConfig, false, onDone) + let request = server.requests[0]; + request.respond(400, responseHeader, 'error'); + expect(JSON.parse(storage.getDataFromLocalStorage(DAP_TOKEN)).expires_at).to.be.equal(cacheExpiry);// Since the expiry is same, the token is not updated in the cache + }); + }); + + describe('dapRefreshEncryptedMembership test', function () { + it('test dapRefreshEncryptedMembership success response', function () { + let expiry = Math.round(Date.now() / 1000.0) + 3600; // in seconds + let encMembership = 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoic29tZXNlY3JldGludmF1bHQifQ..f8_At4OqeQXyQcSwThOJ_w.69ImVQ3bEZ6QP7ROCRpAJjNcKY49SEPYR6qTp_8l7L8kQdPbpi4wmuOzt78j7iBrX64k2wltzmQFjDmVKSxDhrEguxpgx6t-L1tT8ZA0UosMWpVsgmKEZxOn2e9ES3jw8RNCS4WSWocSPQX33xSb51evXjm9E1s0tGoLnwXl0GsUvzRsSU86wQG6RZnAQTi7s-r-M2TKibdDjUqgIt62vJ-aBZ7RWw91MINgOdmDNs1bFfbBX5Cy1kd4-kjvRDz_aJ6zHX4sK_7EmQhGEY3tW-A3_l2I88mw-RSJaPkb_IWg0QpVwXDaE2F2g8NpY1PzCRvG_NIE8r28eK5q44OMVitykHmKmBXGDj7z2JVgoXkfo5u0I-dypZARn4GP_7niK932avB-9JD7Mz3TrlU4GZ7IpYfJ91PMsRhrs5xNPQwLZbpuhF76A7Dp7iss71UjkGCiPTU6udfRb4foyf_7xEF66m1eQVcVaMdxEbMuu9GBfdr-d04TbtJhPfUV8JfxTenvRYoi13n0j5kH0M5OgaSQD9kQ3Mrd9u-Cms-BGtT0vf-N8AaFZY_wn0Y4rkpv5HEaH7z3iT4RCHINWrXb_D0WtjLTKQi2YmF8zMlzUOewNJGwZRwbRwxc7JoDIKEc5RZkJYevfJXOEEOPGXZ7AGZxOEsJawPqFqd_nOUosCZS4akHhcDPcVowoecVAV0hhhoS6JEY66PhPp1snbt6yqA-fQhch7z8Y-DZT3Scibvffww3Scg_KFANWp0KeEvHG0vyv9R2F4o66viSS8y21MDnM7Yjk8C-j7aNMldUQbjN_7Yq1nkfe0jiBX_hsINBRPgJHUY4zCaXuyXs-JZZfU92nwG0RT3A_3RP2rpY8-fXp9d3C2QJjEpnmHvTMsuAZCQSBe5DVrJwN_UKedxcJEoOt0wLz6MaCMyYZPd8tnQeqYK1cd3RgQDXtzKC0HDw1En489DqJXEst4eSSkaaW1lImLeaF8XCOaIqPqoyGk4_6KVLw5Q7OnpczuXqYKMd9UTMovGeuTuo1k0ddfEqTq9QwxkwZL51AiDRnwTCAeYBU1krV8FCJQx-mH_WPB5ftZj-o_3pbvANeRk27QBVmjcS-tgDllJkWBxX-4axRXzLw8pUUUZUT_NOL0OiqUCWVm0qMBEpgRQ57Se42-hkLMTzLhhGJOnVcaXU1j4ep-N7faNvbgREBjf_LgzvaWS90a2NJ9bB_J9FyXelhCN_AMLfdOS3fHkeWlZ0u0PMbn5DxXRMe0l9jB-2VJZhcPQRlWoYyoCO3l4F5ZmuQP5Xh9CU4tvSWih6jlwMDgdVWuTpdfPD5bx8ccog3JDq87enx-QtPzLU3gMgouNARJGgNwKS_GJSE1uPrt2oiqgZ3Z0u_I5MKvPdQPV3o-4rsaE730eB4OwAOF-mkGWpzy8Pbl-Qe5PR9mHBhuyJgZ-WDSCHl5yvet2kfO9mPXZlqBQ26fzTcUYH94MULAZn36og6w.3iKGv-Le-AvRmi26W1v6ibRLGbwKbCR92vs-a9t55hw'; + dapUtils.dapRefreshEncryptedMembership(ortb2, esampleConfig, sampleCachedToken.token, onDone) + let request = server.requests[0]; + responseHeader['Symitri-DAP-Token'] = encMembership; + request.respond(200, responseHeader, encMembership); + let rtdObj = dapUtils.dapGetEncryptedRtdObj({'encryptedSegments': encMembership}, 504) + expect(ortb2.user.data).to.deep.include.members(rtdObj.rtd.ortb2.user.data); + expect(JSON.parse(storage.getDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP)).expires_at).to.equal(expiry); + }); + + it('test dapRefreshEncryptedMembership success response with exp claim', function () { + let encMembership = 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoic29tZXNlY3JldGludmF1bHQiLCJleHAiOjE2NDM4MzA2NDB9..inYoxwht_aqTIWqGhEm_Gw.wDcCUOCwtqgnNUouaD723gKfm7X7bgkHgtiX4mr07P3tWk25PUQunmwTLhWBB5CYzzGIfIvveG_u4glNRLi_eRSQV4ihKKk1AN-BSSJ3d0CLAdY9I1WG5vX1VmopXyKnV90bl9SLNqnhg4Vxe6YU4ogTYxsKHuIN1EeIH4hpl-HbCQWQ1DQt4mB-MQF8V9AWTfU0D7sFMSK8f9qj6NGmf1__oHdHUlws0t5V2UAn_dhJexsuREK_gh65pczCuly5eEcziZ82LeP-nOhKWSRHB_tS_mKXrRU6_At_EVDgtfA3PSBJ6eQylCii6bTL42vZzz4jZhJv_3eLfRdKqpVT5CWNBzcDoQ2VcQgKgIBtPJ45KFfAYTQ6kdl21QMSjqtu8GTsv1lEZtrqHY6zRiG8_Mu28-PmjEw4LDdZmBDOeroue_MJD6wuE_jlE7J2iVdo8CkVnoRgzFwNbKBo7CK4z0WahV9rhuOm0LKAN5H0jF_gj696U-3fVTDTIb8ndNKNI2_xAhvWs00BFGtUtWgr8QGDGRTDCNGsDgnb_Vva9xCqVOyAE9O3Fq1QYl-tMA-KkBt3zzvmFFpOxpOyH-lUubKLKlsrxKc3GSyVEQ9DDLhrXXJgR5H5BSE4tjlK7p3ODF5qz0FHtIj7oDcgLazFO7z2MuFy2LjJmd3hKl6ujcfYEDiQ4D3pMIo7oiU33aFBD1YpzI4-WzNfJlUt1FoK0-DAXpbbV95s8p08GOD4q81rPw5hRADKJEr0QzrbDwplTWCzT2fKXMg_dIIc5AGqGKnVRUS6UyF1DnHpudNIJWxyWZjWIEw_QNjU0cDFmyPSyKxNrnfq9w8WE2bfbS5KTicxei5QHnC-cnL7Nh7IXp7WOW6R1YHbNPT7Ad4OhnlV-jjrXwkSv4wMAbfwAWoSCchGh7uvENNAeJymuponlJbOgw_GcYM73hMs8Z8W9qxRfbyF4WX5fDKXg61mMlaieHkc0EnoC5q7uKyXuZUehHZ76JLDFmewslLkQq5SkVCttzJePBnY1ouPEHw5ZTzUnG5f01QQOVcjIN-AqXNDbG5IOwq0heyS6vVfq7lZKJdLDVQ21qRjazGPaqYwLzugkWkzCOzPTgyFdbXzgjfmJwylHSOM5Jpnul84GzxEQF-1mHP2A8wtIT-M7_iX24It2wwWvc8qLA6GEqruWCtNyoug8CXo44mKdSSCGeEZHtfMbzXdLIBHCy2jSHz5i8S7DU_R7rE_5Ssrb81CqIYbgsAQBHtOYoyvzduTOruWcci4De0QcULloqImIEHUuIe2lnYO889_LIx5p7nE3UlSvLBo0sPexavFUtHqI6jdG6ye9tdseUEoNBDXW0aWD4D-KXX1JLtAgToPVUtEaXCJI7QavwO9ZG6UZM6jbfuJ5co0fvUXp6qYrFxPQo2dYHkar0nT6s1Zg5l2g8yWlLUJrHdHAzAw_NScUp71OpM4TmNsLnYaPVPcOxMvtJXTanbNWr0VKc8gy9q3k_1XxAnQwiduNs7f5bA-6qCVpayHv5dE7mUhFEwyh1_w95jEaURsQF_hnnd2OqRkADfiok4ZiPU2b38kFW1LXjpI39XXES3JU0e08Rq2uuelyLbCLWuJWq_axuKSZbZvpYeqWtIAde8FjCiO7RPlEc0nyzWBst8RBxQ-Bekg9UXPhxBRcm0HwA.Q2cBSFOQAC-QKDwmjrQXnVQd3jNOppMl9oZfd2yuKeY'; + dapUtils.dapRefreshEncryptedMembership(ortb2, esampleConfig, sampleCachedToken.token, onDone) + let request = server.requests[0]; + responseHeader['Symitri-DAP-Token'] = encMembership; + request.respond(200, responseHeader, encMembership); + let rtdObj = dapUtils.dapGetEncryptedRtdObj({'encryptedSegments': encMembership}, 504) + expect(ortb2.user.data).to.deep.include.members(rtdObj.rtd.ortb2.user.data); + expect(JSON.parse(storage.getDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP)).expires_at).to.equal(1643830630); + }); + + it('test dapRefreshEncryptedMembership error response', function () { + dapUtils.dapRefreshEncryptedMembership(ortb2, esampleConfig, sampleCachedToken.token, onDone) + let request = server.requests[0]; + request.respond(400, responseHeader, 'error'); + expect(ortb2).to.eql({}); + }); + + it('test dapRefreshEncryptedMembership 403 error response', function () { + dapUtils.dapRefreshEncryptedMembership(ortb2, esampleConfig, sampleCachedToken.token, onDone) + let request = server.requests[0]; + request.respond(403, responseHeader, 'error'); + let requestTokenize = server.requests[1]; + responseHeader['Symitri-DAP-Token'] = sampleCachedToken.token; + requestTokenize.respond(200, responseHeader, ''); + let requestMembership = server.requests[2]; + requestMembership.respond(403, responseHeader, 'error'); + expect(server.requests.length).to.be.equal(DAP_MAX_RETRY_TOKENIZE + 2); + }); + }); + + describe('dapRefreshMembership test', function () { + it('test dapRefreshMembership success response', function () { + let membership = {'cohorts': ['9', '11', '13'], 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..17wnrhz6FbWx0Cf6LXpm1A.m9PKVCradk3CZokNKzVHzE06TOqiXYeijgxTQUiQy5Syx-yicnO8DyYX6zQ6rgPcNgUNRt4R4XE5MXuK0laUVQJr9yc9g3vUfQfw69OMYGW_vRlLMPzoNOhF2c4gSyfkRrLr7C0qgALmZO1D11sPflaCTNmO7pmZtRaCOB5buHoWcQhp1bUSJ09DNDb31dX3llimPwjNGSrUhyq_EZl4HopnnjxbM4qVNMY2G_43C_idlVOvbFoTxcDRATd-6MplJoIOIHQLDZEetpIOVcbEYN9gQ_ndBISITwuu5YEgs5C_WPHA25nm6e4BT5R-tawSA8yPyQAupqE8gk4ZWq_2-T0cqyTstIHrMQnZ_vysYN7h6bkzE-KeZRk7GMtySN87_fiu904hLD9QentGegamX6UAbVqQh7Htj7SnMHXkEenjxXAM5mRqQvNCTlw8k-9-VPXs-vTcKLYP8VFf8gMOmuYykgWac1gX-svyAg-24mo8cUbqcsj9relx4Qj5HiXUVyDMBZxK-mHZi-Xz6uv9GlggcsjE13DSszar-j2OetigpdibnJIxRZ-4ew3-vlvZ0Dul3j0LjeWURVBWYWfMjuZ193G7lwR3ohh_NzlNfwOPBK_SYurdAnLh7jJgTW-lVLjH2Dipmi9JwX9s03IQq9opexAn7hlM9oBI6x5asByH8JF8WwZ5GhzDjpDwpSmHPQNGFRSyrx_Sh2CPWNK6C1NJmLkyqAtJ5iw0_al7vPDQyZrKXaLTjBCUnbpJhUZ8dUKtWLzGPjzFXp10muoDIutd1NfyKxk1aWGhx5aerYuLdywv6cT_M8RZTi8924NGj5VA30V5OvEwLLyX93eDhntXZSCbkPHpAfiRZNGXrPY.GhCbWGQz11mIRD4uPKmoAuFXDH7hGnils54zg7N7-TU'} + dapUtils.dapRefreshMembership(ortb2, sampleConfig, sampleCachedToken.token, onDone); + let request = server.requests[0]; + request.respond(200, responseHeader, JSON.stringify(membership)); + let rtdObj = dapUtils.dapGetRtdObj(membership, 503); + expect(ortb2.user.data).to.deep.include.members(rtdObj.rtd.ortb2.user.data); + }); + + it('test dapRefreshMembership success response with exp claim', function () { + let membership = {'cohorts': ['9', '11', '13'], 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIiwiZXhwIjoxNjQ3OTcxNTU4fQ..ptdM5WO-62ypXlKxFXD4FQ.waEo9MHS2NYQCi-zh_p6HgT9BdqGyQbBq4GfGLfsay4nRBgICsTS-VkV6e7xx5U1T8BgpKkRJIZBwTOY5Pkxk9FpK5nnffDSEljRrp1LXLCkNP4qwrlqHInFbZsonNWW4_mW-7aUPlTwIsTbfjTuyHdXHeQa1ALrwFFFWE7QUmPNd2RsHjDwUsxlJPEb5TnHn5W0Mgo_PQZaxvhJInMbxPgtJLoqnJvOqCBEoQY7au7ALZL_nWK8XIwPMF19J7Z3cBg9vQInhr_E3rMdQcAFHEzYfgoNcIYCCR0t1UOqUE3HNtX-E64kZAYKWdlsBb9eW5Gj9hHYyPNL_4Hntjg5eLXGpsocMg0An-qQKGC6hkrxKzeM-GrjpvSaQLNs4iqDpHUtzA02LW_vkLkMNRUiyXVJ3FUZwfyq6uHSRKWZ6UFdAfL0rfJ8q8x8Ll-qJO2Jfyvidlsi9FIs7x1WJrvDCKepfAQM1UXRTonrQljFBAk83PcL2bmWuJDgJZ0lWS4VnZbIf6A7fDourmkDxdVRptvQq5nSjtzCA6whRw0-wGz8ehNJsaJw9H_nG9k4lRKs7A5Lqsyy7TVFrAPjnA_Q1a2H6xF2ULxrtIqoNqdX7k9RjowEZSQlZgZUOAmI4wzjckdcSyC_pUlYBMcBwmlld34mmOJe9EBHAxjdci7Q_9lvj1HTcwGDcQITXnkW9Ux5Jkt9Naw-IGGrnEIADaT2guUAto8W_Gb05TmwHSd6DCmh4zepQCbqeVe6AvPILtVkTgsTTo27Q-NvS7h-XtthJy8425j5kqwxxpZFJ0l0ytc6DUyNCLJXuxi0JFU6-LoSXcROEMVrHa_Achufr9vHIELwacSAIHuwseEvg_OOu1c1WYEwZH8ynBLSjqzy8AnDj24hYgA0YanPAvDqacrYrTUFqURbHmvcQqLBTcYa_gs7uDx4a1EjtP_NvHRlvCgGAaASrjGMhTX8oJxlTqahhQ.pXm-7KqnNK8sbyyczwkVYhcjgiwkpO8LjBBVw4lcyZE'}; + dapUtils.dapRefreshMembership(ortb2, sampleConfig, sampleCachedToken.token, onDone); + let request = server.requests[0]; + request.respond(200, responseHeader, JSON.stringify(membership)); + let rtdObj = dapUtils.dapGetRtdObj(membership, 503) + expect(ortb2.user.data).to.deep.include.members(rtdObj.rtd.ortb2.user.data); + expect(JSON.parse(storage.getDataFromLocalStorage(DAP_MEMBERSHIP)).expires_at).to.be.equal(1647971548); + }); + + it('test dapRefreshMembership 400 error response', function () { + dapUtils.dapRefreshMembership(ortb2, sampleConfig, sampleCachedToken.token, onDone) + let request = server.requests[0]; + request.respond(400, responseHeader, 'error'); + expect(ortb2).to.eql({}); + }); + + it('test dapRefreshMembership 403 error response', function () { + dapUtils.dapRefreshMembership(ortb2, sampleConfig, sampleCachedToken.token, onDone) + let request = server.requests[0]; + request.respond(403, responseHeader, 'error'); + expect(server.requests.length).to.be.equal(DAP_MAX_RETRY_TOKENIZE); + }); + }); + + describe('dapGetEncryptedMembershipFromLocalStorage test', function () { + it('test dapGetEncryptedMembershipFromLocalStorage function with valid cache', function () { + storage.setDataInLocalStorage(DAP_ENCRYPTED_MEMBERSHIP, JSON.stringify(cachedEncryptedMembership)) + expect(JSON.stringify(dapUtils.dapGetEncryptedMembershipFromLocalStorage())).to.equal(JSON.stringify(encMembership)); + }); + + it('test dapGetEncryptedMembershipFromLocalStorage function with invalid cache', function () { + let expiry = Math.round(Date.now() / 1000.0) - 100; // in seconds + let encMembership = {'expiry': expiry, 'encryptedSegments': cachedEncryptedMembership.encryptedSegments} + storage.setDataInLocalStorage(DAP_ENCRYPTED_MEMBERSHIP, JSON.stringify(encMembership)) + expect(dapUtils.dapGetEncryptedMembershipFromLocalStorage()).to.equal(null); + }); + }); + + describe('Symitri-DAP-SS-ID test', function () { + it('Symitri-DAP-SS-ID present in response header', function () { + let expiry = Math.round(Date.now() / 1000.0) + 300; // in seconds + dapUtils.dapRefreshToken(ortb2, sampleConfig, false, onDone) + let request = server.requests[0]; + let sampleSSID = 'Test_SSID_Spec'; + responseHeader['Symitri-DAP-Token'] = sampleCachedToken.token; + responseHeader['Symitri-DAP-SS-ID'] = sampleSSID; + request.respond(200, responseHeader, ''); + expect(storage.getDataFromLocalStorage(DAP_SS_ID)).to.be.equal(JSON.stringify(sampleSSID)); + }); + + it('Test if Symitri-DAP-SS-ID is present in request header', function () { + let expiry = Math.round(Date.now() / 1000.0) + 100; // in seconds + storage.setDataInLocalStorage(DAP_SS_ID, JSON.stringify('Test_SSID_Spec')) + dapUtils.dapRefreshToken(ortb2, sampleConfig, false, onDone) + let request = server.requests[0]; + let ssidHeader = request.requestHeaders['Symitri-DAP-SS-ID']; + responseHeader['Symitri-DAP-Token'] = sampleCachedToken.token; + request.respond(200, responseHeader, ''); + expect(ssidHeader).to.be.equal('Test_SSID_Spec'); + }); + }); + + describe('Test gdpr and usp consent handling', function () { + it('Gdpr applies and gdpr consent string not present', function () { + expect(symitriDapRtdSubmodule.init(null, sampleGdprConsentConfig)).to.equal(false); + }); + + it('Gdpr applies and gdpr consent string is present', function () { + sampleGdprConsentConfig.gdpr.consentString = 'BOJ/P2HOJ/P2HABABMAAAAAZ+A=='; + expect(symitriDapRtdSubmodule.init(null, sampleGdprConsentConfig)).to.equal(true); + }); + + it('USP consent present and user have opted out', function () { + expect(symitriDapRtdSubmodule.init(null, sampleUspConsentConfig)).to.equal(false); + }); + + it('USP consent present and user have not been provided with option to opt out', function () { + expect(symitriDapRtdSubmodule.init(null, {'usp': '1NYY'})).to.equal(false); + }); + + it('USP consent present and user have not opted out', function () { + expect(symitriDapRtdSubmodule.init(null, {'usp': '1YNY'})).to.equal(true); + }); + }); +}); diff --git a/test/spec/modules/taboolaBidAdapter_spec.js b/test/spec/modules/taboolaBidAdapter_spec.js index 55d0731ec21..bcf388a67e2 100644 --- a/test/spec/modules/taboolaBidAdapter_spec.js +++ b/test/spec/modules/taboolaBidAdapter_spec.js @@ -1149,7 +1149,7 @@ describe('Taboola Adapter', function () { }, } ], - 'fledgeAuctionConfigs': [ + 'paapi': [ { 'impId': request.bids[0].bidId, 'config': { @@ -1222,7 +1222,7 @@ describe('Taboola Adapter', function () { }, } ], - 'fledgeAuctionConfigs': [ + 'paapi': [ { 'impId': request.bids[0].bidId, 'config': { diff --git a/test/spec/modules/tagorasBidAdapter_spec.js b/test/spec/modules/tagorasBidAdapter_spec.js index 7559567dcff..d68088affa1 100644 --- a/test/spec/modules/tagorasBidAdapter_spec.js +++ b/test/spec/modules/tagorasBidAdapter_spec.js @@ -2,6 +2,14 @@ import {expect} from 'chai'; import { spec as adapter, createDomain, + storage +} from 'modules/tagorasBidAdapter'; +import * as utils from 'src/utils.js'; +import {version} from 'package.json'; +import {useFakeTimers} from 'sinon'; +import {BANNER, VIDEO} from '../../../src/mediaTypes'; +import {config} from '../../../src/config'; +import { hashCode, extractPID, extractCID, @@ -10,12 +18,7 @@ import { setStorageItem, tryParseJSON, getUniqueDealId, -} from 'modules/tagorasBidAdapter'; -import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes'; -import {config} from '../../../src/config'; +} from '../../../libraries/vidazooUtils/bidderUtils.js'; export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -324,7 +327,12 @@ describe('TagorasBidAdapter', function () { startdelay: 0 } }, - gpid: '' + gpid: '', + cat: [], + contentData: [], + isStorageAllowed: true, + pagecat: [], + userData: [] } }); }); @@ -385,6 +393,11 @@ describe('TagorasBidAdapter', function () { uqs: getTopWindowQueryParams(), 'ext.param1': 'loremipsum', 'ext.param2': 'dolorsitamet', + cat: [], + contentData: [], + isStorageAllowed: true, + pagecat: [], + userData: [] } }); }); @@ -527,8 +540,6 @@ describe('TagorasBidAdapter', function () { switch (idSystemProvider) { case 'lipb': return {lipbid: id}; - case 'parrableId': - return {eid: id}; case 'id5id': return {uid: id}; default: @@ -581,13 +592,13 @@ describe('TagorasBidAdapter', function () { const key = 'myKey'; let uniqueDealId; beforeEach(() => { - uniqueDealId = getUniqueDealId(key, 0); + uniqueDealId = getUniqueDealId(storage, key, 0); }) it('should get current unique deal id', function (done) { // waiting some time so `now` will become past setTimeout(() => { - const current = getUniqueDealId(key); + const current = getUniqueDealId(storage, key); expect(current).to.be.equal(uniqueDealId); done(); }, 200); @@ -595,7 +606,7 @@ describe('TagorasBidAdapter', function () { it('should get new unique deal id on expiration', function (done) { setTimeout(() => { - const current = getUniqueDealId(key, 100); + const current = getUniqueDealId(storage, key, 100); expect(current).to.not.be.equal(uniqueDealId); done(); }, 200) @@ -619,8 +630,8 @@ describe('TagorasBidAdapter', function () { shouldAdvanceTime: true, now }); - setStorageItem('myKey', 2020); - const {value, created} = getStorageItem('myKey'); + setStorageItem(storage, 'myKey', 2020); + const {value, created} = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -631,7 +642,7 @@ describe('TagorasBidAdapter', function () { it('should get external stored value', function () { const value = 'superman' window.localStorage.setItem('myExternalKey', value); - const item = getStorageItem('myExternalKey'); + const item = getStorageItem(storage, 'myExternalKey'); expect(item).to.be.equal(value); }); diff --git a/test/spec/modules/targetVideoBidAdapter_spec.js b/test/spec/modules/targetVideoBidAdapter_spec.js index 8180183e6d7..442d7e7ef0b 100644 --- a/test/spec/modules/targetVideoBidAdapter_spec.js +++ b/test/spec/modules/targetVideoBidAdapter_spec.js @@ -1,27 +1,42 @@ import { spec } from '../../../modules/targetVideoBidAdapter.js' describe('TargetVideo Bid Adapter', function() { + const bidder = 'targetVideo'; + const params = { + placementId: 12345, + }; + const bannerRequest = [{ - bidder: 'targetVideo', + bidder, + params, mediaTypes: { banner: { sizes: [[300, 250]], } }, - params: { - placementId: 12345, + }]; + + const videoRequest = [{ + bidder, + params, + mediaTypes: { + video: { + playerSize: [[640, 360]], + context: 'instream', + playbackmethod: [1, 2, 3, 4] + } } }]; it('Test the bid validation function', function() { - const validBid = spec.isBidRequestValid(bannerRequest[0]); + const validBid = spec.isBidRequestValid(bannerRequest[0]) && spec.isBidRequestValid(videoRequest[0]); const invalidBid = spec.isBidRequestValid(null); expect(validBid).to.be.true; expect(invalidBid).to.be.false; }); - it('Test the request processing function', function () { + it('Test the BANNER request processing function', function() { const request = spec.buildRequests(bannerRequest, bannerRequest[0]); expect(request).to.not.be.empty; @@ -36,7 +51,20 @@ describe('TargetVideo Bid Adapter', function() { expect(payload.tags[0].ad_types[0]).to.equal('video'); }); - it('Handle nobid responses', function () { + it('Test the VIDEO request processing function', function() { + const request = spec.buildRequests(videoRequest, videoRequest[0]); + expect(request).to.not.be.empty; + + const payload = JSON.parse(request[0].data); + expect(payload).to.not.be.empty; + expect(payload.sdk).to.deep.equal({ + source: 'pbjs', + version: '$prebid.version$' + }); + expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(12345); + }) + + it('Handle BANNER nobid responses', function() { const responseBody = { 'version': '0.0.1', 'tags': [{ @@ -48,11 +76,24 @@ describe('TargetVideo Bid Adapter', function() { }; const bidderRequest = null; - const bidResponse = spec.interpretResponse({ body: responseBody }, {bidderRequest}); + const bidResponse = spec.interpretResponse({ body: responseBody }, { bidderRequest }); expect(bidResponse.length).to.equal(0); }); - it('Test the response parsing function', function () { + it('Handle VIDEO nobid responses', function() { + const responseBody = { + 'id': 'test-id', + 'cur': 'USD', + 'seatbid': [], + 'nbr': 0 + }; + const bidderRequest = null; + + const bidResponse = spec.interpretResponse({ body: responseBody }, { bidderRequest }); + expect(bidResponse.length).to.equal(0); + }) + + it('Test the BANNER response parsing function', function() { const responseBody = { 'tags': [{ 'uuid': '84ab500420319d', @@ -82,7 +123,7 @@ describe('TargetVideo Bid Adapter', function() { }] }; - const bidResponse = spec.interpretResponse({ body: responseBody }, {bidderRequest}); + const bidResponse = spec.interpretResponse({ body: responseBody }, { bidderRequest }); expect(bidResponse).to.not.be.empty; const bid = bidResponse[0]; @@ -94,7 +135,43 @@ describe('TargetVideo Bid Adapter', function() { expect(bid.ad).to.include('initPlayer') }); - it('Test GDPR consent information is present in the request', function () { + it('Test the VIDEO response parsing function', function() { + const responseBody = { + 'id': 'test-id', + 'cur': 'USD', + 'seatbid': [{ + 'bid': [{ + 'id': '5044997188309660254', + 'price': 10, + 'adm': 'test ad', + 'adid': '97517771', + 'crid': '97517771', + 'adomain': ['domain.com'], + 'w': 640, + 'h': 480 + }], + 'seat': 'bidder' + }] + }; + const bidderRequest = { + bidderCode: 'brid', + bidderRequestId: '22edbae2733bf6', + bids: videoRequest + }; + + const bidResponse = spec.interpretResponse({ body: responseBody }, { bidderRequest }); + expect(bidResponse).to.not.be.empty; + + const bid = bidResponse[0]; + expect(bid).to.not.be.empty; + expect(bid.ad).to.equal('test ad'); + expect(bid.cpm).to.equal(10); + expect(bid.width).to.equal(640); + expect(bid.height).to.equal(480); + expect(bid.currency).to.equal('USD'); + }) + + it('Test BANNER GDPR consent information is present in the request', function() { let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; let bidderRequest = { 'bidderCode': 'targetVideo', @@ -119,7 +196,7 @@ describe('TargetVideo Bid Adapter', function() { expect(payload.gdpr_consent.addtl_consent).to.exist.and.to.deep.equal([7, 12, 35, 62, 66, 70, 89, 93, 108]); }); - it('Test US Privacy string is present in the request', function() { + it('Test BANNER US Privacy string is present in the request', function() { let consentString = '1YA-'; let bidderRequest = { 'bidderCode': 'targetVideo', @@ -136,4 +213,28 @@ describe('TargetVideo Bid Adapter', function() { expect(payload.us_privacy).to.exist; expect(payload.us_privacy).to.exist.and.to.equal(consentString); }); + + it('Test VIDEO GDPR and USP consents are present in the request', function() { + let gdprConsentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; + let uspConsentString = '1YA-'; + let bidderRequest = { + 'bidderCode': 'targetVideo', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + 'uspConsent': uspConsentString, + 'gdprConsent': { + consentString: gdprConsentString, + gdprApplies: true, + addtlConsent: '1~7.12.35.62.66.70.89.93.108' + } + }; + bidderRequest.bids = videoRequest; + + const request = spec.buildRequests(videoRequest, bidderRequest); + const payload = JSON.parse(request[0].data); + + expect(payload.user.ext.consent).to.equal(gdprConsentString); + expect(payload.regs.ext.us_privacy).to.equal(uspConsentString); + expect(payload.regs.ext.gdpr).to.equal(1); + }); }); diff --git a/test/spec/modules/gdprEnforcement_spec.js b/test/spec/modules/tcfControl_spec.js similarity index 95% rename from test/spec/modules/gdprEnforcement_spec.js rename to test/spec/modules/tcfControl_spec.js index 4caf0276874..bdb14f6e44e 100644 --- a/test/spec/modules/gdprEnforcement_spec.js +++ b/test/spec/modules/tcfControl_spec.js @@ -1,18 +1,19 @@ import { accessDeviceRule, + ACTIVE_RULES, enrichEidsRule, fetchBidsRule, - transmitEidsRule, - transmitPreciseGeoRule, getGvlid, getGvlidFromAnalyticsAdapter, - ACTIVE_RULES, reportAnalyticsRule, setEnforcementConfig, STRICT_STORAGE_ENFORCEMENT, - syncUserRule, ufpdRule, + syncUserRule, + transmitEidsRule, + transmitPreciseGeoRule, + ufpdRule, validateRules -} from 'modules/gdprEnforcement.js'; +} from 'modules/tcfControl.js'; import {config} from 'src/config.js'; import adapterManager, {gdprDataHandler} from 'src/adapterManager.js'; import * as utils from 'src/utils.js'; @@ -26,8 +27,7 @@ import * as events from 'src/events.js'; import 'modules/appnexusBidAdapter.js'; // some tests expect this to be in the adapter registry import 'src/prebid.js'; import {hook} from '../../../src/hook.js'; -import {GDPR_GVLIDS, VENDORLESS_GVLID, FIRST_PARTY_GVLID} from '../../../src/consentHandler.js'; -import {validateStorageEnforcement} from '../../../src/storageManager.js'; +import {GDPR_GVLIDS, VENDORLESS_GVLID} from '../../../src/consentHandler.js'; import {activityParams} from '../../../src/activities/activityParams.js'; describe('gdpr enforcement', function () { @@ -762,47 +762,52 @@ describe('gdpr enforcement', function () { }) }) - describe('when module does not need vendor consent', () => { + describe('first party modules', () => { Object.entries({ - 'storage': 1, - 'basicAds': 2, - 'measurement': 7, - 'personalizedAds': 4, - }).forEach(([purpose, purposeNo]) => { - describe(`for purpose ${purpose}`, () => { + 'storage': { + purposeNo: 1, + allowsLI: false + }, + 'basicAds': { + purposeNo: 2, + allowsLI: true + }, + 'measurement': { + purposeNo: 7, + allowsLI: true + }, + 'personalizedAds': { + purposeNo: 4, + allowsLI: false + }, + }).forEach(([purpose, {purposeNo, allowsLI}]) => { + describe(`purpose ${purpose}`, () => { + let consent; + beforeEach(() => { + consent = utils.deepClone(consentData); + }) const rule = createGdprRule(purpose); Object.entries({ 'allowed': true, 'not allowed': false }).forEach(([t, consentGiven]) => { - it(`should be ${t} when purpose is ${t}`, () => { - const consent = utils.deepClone(consentData); - consent.vendorData.purpose.consents[purposeNo] = consentGiven; - // take legitimate interest out of the picture for this test - consent.vendorData.purpose.legitimateInterests = {}; + it(`should be ${t} when publisher is ${t}`, () => { + consent.vendorData.publisher.consents[purposeNo] = consentGiven; + consent.vendorData.publisher.legitimateInterests[purposeNo] = false; const actual = validateRules(rule, consent, 'mockModule', VENDORLESS_GVLID); expect(actual).to.equal(consentGiven); - }) + }); + }) + it(`should ${allowsLI ? '' : 'NOT '}be allowed when publisher consent is not given, but LI is`, () => { + consent.vendorData.publisher.consents[purposeNo] = false; + consent.vendorData.publisher.legitimateInterests[purposeNo] = true; + const actual = validateRules(rule, consent, 'mockModule', VENDORLESS_GVLID); + expect(actual).to.equal(allowsLI); }) }) }) }) - it('if validateRules is passed FIRST_PARTY_GVLID, it will use publisher.consents', () => { - const rule = createGdprRule(); - const consentData = { - 'vendorData': { - 'publisher': { - 'consents': { - '1': true - } - }, - }, - }; - const result = validateRules(rule, consentData, 'cdep', FIRST_PARTY_GVLID); - expect(result).to.equal(true); - }); - describe('validateRules', function () { Object.entries({ '1 (which does not consider LI)': [1, 'storage', false], diff --git a/test/spec/modules/teadsBidAdapter_spec.js b/test/spec/modules/teadsBidAdapter_spec.js index 40011367ac0..8ccfdd44649 100644 --- a/test/spec/modules/teadsBidAdapter_spec.js +++ b/test/spec/modules/teadsBidAdapter_spec.js @@ -44,47 +44,47 @@ describe('teadsBidAdapter', () => { }); it('should return false when pageId is not valid (letters)', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': 1234, 'pageId': 'ABCD' }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when placementId is not valid (letters)', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': 'FCP', 'pageId': 1234 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when placementId < 0 or pageId < 0', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': -1, 'pageId': -1 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when required params are not passed', function() { - let bid = Object.assign({}, bid); - delete bid.params; + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; - bid.params = { + invalidBid.params = { 'placementId': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/theAdxBidAdapter_spec.js b/test/spec/modules/theAdxBidAdapter_spec.js index eb00834421a..53a65c1b044 100644 --- a/test/spec/modules/theAdxBidAdapter_spec.js +++ b/test/spec/modules/theAdxBidAdapter_spec.js @@ -81,7 +81,21 @@ describe('TheAdxAdapter', function () { [300, 600] ] } - } + }, + userId: { + uid2: { id: 'sample-uid2' }, + id5id: { + 'uid': 'sample-id5id', + 'ext': { + 'linkType': 'abc' + } + }, + netId: 'sample-netid', + sharedid: { + 'id': 'sample-sharedid', + }, + + }, }; const sampleBidderRequest = { @@ -357,6 +371,30 @@ describe('TheAdxAdapter', function () { expect(mediaTypes.video).to.not.be.null; expect(mediaTypes.video).to.not.be.undefined; }); + + it('add eids to request', function () { + let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); + + let results = spec.buildRequests([localBidRequest], sampleBidderRequest); + let result = results.pop(); + let payload = JSON.parse(result.data); + expect(payload).to.not.be.null; + expect(payload.ext).to.not.be.null; + + expect(payload.ext.uid2).to.not.be.null; + expect(payload.ext.uid2.length).to.greaterThan(0); + + expect(payload.ext.id5id).to.not.be.null; + expect(payload.ext.id5id.length).to.greaterThan(0); + expect(payload.ext.id5_linktype).to.not.be.null; + expect(payload.ext.id5_linktype.length).to.greaterThan(0); + + expect(payload.ext.netid).to.not.be.null; + expect(payload.ext.netid.length).to.greaterThan(0); + + expect(payload.ext.sharedid).to.not.be.null; + expect(payload.ext.sharedid.length).to.greaterThan(0); + }); }); describe('response interpreter', function () { @@ -495,7 +533,7 @@ describe('TheAdxAdapter', function () { banner: {} }, requestId: incomingRequestId, - deals: [{id: dealId}] + deals: [{ id: dealId }] }; let serverResponse = { body: sampleResponse diff --git a/test/spec/modules/topicsFpdModule_spec.js b/test/spec/modules/topicsFpdModule_spec.js index 4a79e7f77fd..0f8e379e95f 100644 --- a/test/spec/modules/topicsFpdModule_spec.js +++ b/test/spec/modules/topicsFpdModule_spec.js @@ -308,33 +308,6 @@ describe('topics', () => { }], name: 'ads.pubmatic.com' }]; - const consentString = 'CPi8wgAPi8wgAADABBENCrCsAP_AAH_AAAAAISNB7D=='; - const consentConfig = { - consentString: consentString, - gdprApplies: true, - vendorData: { - metadata: consentString, - gdprApplies: true, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true - } - } - } - }; - const mockData = [ - { - name: 'domain', - segment: [{id: 123}] - }, - { - name: 'domain', - segment: [{id: 321}], - } - ]; const evt = { data: '{"segment":{"domain":"ads.pubmatic.com","topics":[{"configVersion":"chrome.1","modelVersion":"2206021246","taxonomyVersion":"1","topic":165,"version":"chrome.1:1:2206021246"}],"bidder":"pubmatic"},"date":1669743901858}', @@ -345,37 +318,60 @@ describe('topics', () => { storage.removeDataFromLocalStorage(topicStorageName); }); - describe('when cached data is available and not expired', () => { + describe('caching', () => { let sandbox; beforeEach(() => { sandbox = sinon.sandbox.create(); - const storedSegments = JSON.stringify( - [['pubmatic', { - '2206021246': { - 'ext': {'segtax': 600, 'segclass': '2206021246'}, - 'segment': [{'id': '243'}, {'id': '265'}], - 'name': 'ads.pubmatic.com' - }, - 'lastUpdated': new Date().getTime() - }]] - ); - storage.setDataInLocalStorage(topicStorageName, storedSegments); - }); + }) + afterEach(() => { sandbox.restore(); + config.resetConfig(); }); - it('should return segments for bidder if transmitUfpd is allowed', () => { - assert.deepEqual(getCachedTopics(), expected); - }); + it('should return no segments when not configured', () => { + config.setConfig({userSync: {}}); + expect(getCachedTopics()).to.eql([]); + }) + + describe('when cached data is available and not expired', () => { + beforeEach(() => { + const storedSegments = JSON.stringify( + [['pubmatic', { + '2206021246': { + 'ext': {'segtax': 600, 'segclass': '2206021246'}, + 'segment': [{'id': '243'}, {'id': '265'}], + 'name': 'ads.pubmatic.com' + }, + 'lastUpdated': new Date().getTime() + }]] + ); + storage.setDataInLocalStorage(topicStorageName, storedSegments); + config.setConfig({ + userSync: { + topics: { + maxTopicCaller: 4, + bidders: [{ + bidder: 'pubmatic', + iframeURL: 'https://ads.pubmatic.com/AdServer/js/topics/topics_frame.html' + }] + } + } + }) + }); - it('should NOT return segments for bidder if enrichUfpd is NOT allowed', () => { - sandbox.stub(activities, 'isActivityAllowed').callsFake((activity, params) => { - return !(activity === ACTIVITY_ENRICH_UFPD && params.component === 'bidder.pubmatic'); + it('should return segments for bidder if transmitUfpd is allowed', () => { + assert.deepEqual(getCachedTopics(), expected); + }); + + it('should NOT return segments for bidder if enrichUfpd is NOT allowed', () => { + sandbox.stub(activities, 'isActivityAllowed').callsFake((activity, params) => { + return !(activity === ACTIVITY_ENRICH_UFPD && params.component === 'bidder.pubmatic'); + }); + expect(getCachedTopics()).to.eql([]); }); - expect(getCachedTopics()).to.eql([]); }); - }) + }); it('should return empty segments for bidder if there is cached segments stored which is expired', () => { let storedSegments = '[["pubmatic",{"2206021246":{"ext":{"segtax":600,"segclass":"2206021246"},"segment":[{"id":"243"},{"id":"265"}],"name":"ads.pubmatic.com"},"lastUpdated":10}]]'; diff --git a/test/spec/modules/tpmnBidAdapter_spec.js b/test/spec/modules/tpmnBidAdapter_spec.js index 505bc9d878f..48295e6fdff 100644 --- a/test/spec/modules/tpmnBidAdapter_spec.js +++ b/test/spec/modules/tpmnBidAdapter_spec.js @@ -4,7 +4,7 @@ import { generateUUID } from '../../../src/utils.js'; import { expect } from 'chai'; import * as utils from 'src/utils'; import * as sinon from 'sinon'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import {syncAddFPDToBidderRequest} from '../../helpers/fpd.js'; import {mockGdprConsent} from '../../helpers/consentData.js'; diff --git a/test/spec/modules/trafficgateBidAdapter_spec.js b/test/spec/modules/trafficgateBidAdapter_spec.js index 11ff547cc78..9c564606186 100644 --- a/test/spec/modules/trafficgateBidAdapter_spec.js +++ b/test/spec/modules/trafficgateBidAdapter_spec.js @@ -9,9 +9,11 @@ import 'modules/currency.js'; import 'modules/userId/index.js'; import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/schain.js'; +import 'modules/paapi.js'; + import {deepClone} from 'src/utils.js'; import {syncAddFPDToBidderRequest} from '../../helpers/fpd.js'; import {hook} from '../../../src/hook.js'; @@ -193,9 +195,9 @@ describe('TrafficgateOpenxRtbAdapter', function () { }); it('should return false when required params are not passed', function () { - let videoBidWithMediaTypes = Object.assign({}, videoBidWithMediaTypes); - videoBidWithMediaTypes.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false); + let invalidVideoBidWithMediaTypes = Object.assign({}, videoBidWithMediaTypes); + invalidVideoBidWithMediaTypes.params = {}; + expect(spec.isBidRequestValid(invalidVideoBidWithMediaTypes)).to.equal(false); }); }); describe('and request config uses both host and platform', () => { @@ -250,10 +252,10 @@ describe('TrafficgateOpenxRtbAdapter', function () { }); it('should return false when required params are not passed', function () { - let videoBidWithMediaType = Object.assign({}, videoBidWithMediaType); - delete videoBidWithMediaType.params; - videoBidWithMediaType.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(false); + let invalidVideoBidWithMediaTypes = Object.assign({}, videoBidWithMediaType); + delete invalidVideoBidWithMediaTypes.params; + invalidVideoBidWithMediaTypes.params = {}; + expect(spec.isBidRequestValid(invalidVideoBidWithMediaTypes)).to.equal(false); }); }); }); @@ -1017,7 +1019,9 @@ describe('TrafficgateOpenxRtbAdapter', function () { it('when FLEDGE is enabled, should send whatever is set in ortb2imp.ext.ae in all bid requests', function () { const request = spec.buildRequests(bidRequestsWithMediaTypes, { ...mockBidderRequest, - fledgeEnabled: true + paapi: { + enabled: true + } }); expect(request[0].data.imp[0].ext.ae).to.equal(2); }); diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index 09e57e29a12..216142ab02e 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -874,7 +874,7 @@ describe('triplelift adapter', function () { expect(url).to.match(/(\?|&)us_privacy=1YYY/); }); it('should pass fledge signal when Triplelift is eligible for fledge', function() { - bidderRequest.fledgeEnabled = true; + bidderRequest.paapi = {enabled: true}; const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); const url = request.url; expect(url).to.match(/(\?|&)fledge=true/); @@ -1411,11 +1411,11 @@ describe('triplelift adapter', function () { let result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); expect(result).to.have.property('bids'); - expect(result).to.have.property('fledgeAuctionConfigs'); - expect(result.fledgeAuctionConfigs.length).to.equal(2); - expect(result.fledgeAuctionConfigs[0].bidId).to.equal('30b31c1838de1e'); - expect(result.fledgeAuctionConfigs[1].bidId).to.equal('73edc0ba8de203'); - expect(result.fledgeAuctionConfigs[0].config).to.deep.equal( + expect(result).to.have.property('paapi'); + expect(result.paapi.length).to.equal(2); + expect(result.paapi[0].bidId).to.equal('30b31c1838de1e'); + expect(result.paapi[1].bidId).to.equal('73edc0ba8de203'); + expect(result.paapi[0].config).to.deep.equal( { 'seller': 'https://3lift.com', 'decisionLogicUrl': 'https://3lift.com/decision_logic.js', @@ -1423,7 +1423,7 @@ describe('triplelift adapter', function () { 'perBuyerSignals': { 'https://some_buyer.com': { 'a': 1 } } } ); - expect(result.fledgeAuctionConfigs[1].config).to.deep.equal( + expect(result.paapi[1].config).to.deep.equal( { 'seller': 'https://3lift.com', 'decisionLogicUrl': 'https://3lift.com/decision_logic.js', diff --git a/test/spec/modules/truereachBidAdapter_spec.js b/test/spec/modules/truereachBidAdapter_spec.js index cd7d0873569..78e6828147b 100644 --- a/test/spec/modules/truereachBidAdapter_spec.js +++ b/test/spec/modules/truereachBidAdapter_spec.js @@ -12,7 +12,6 @@ describe('truereachBidAdapterTests', function () { bidder: 'truereach', params: { site_id: '0142010a-8400-1b01-72cb-a553b9000009', - bidfloor: 0.1 } })).to.equal(true); }); @@ -27,8 +26,7 @@ describe('truereachBidAdapterTests', function () { }, bidder: 'truereach', params: { - site_id: '0142010a-8400-1b01-72cb-a553b9000009', - bidfloor: 0.1 + site_id: '0142010a-8400-1b01-72cb-a553b9000009' }, sizes: [[300, 250]] }]; @@ -40,7 +38,6 @@ describe('truereachBidAdapterTests', function () { expect(req_data.imp[0].id).to.equal('34ce3f3b15190a'); expect(req_data.imp[0].banner.w).to.equal(300); expect(req_data.imp[0].banner.h).to.equal(250); - expect(req_data.imp[0].bidfloor).to.equal(0); }); it('validate_response_params', function () { diff --git a/test/spec/modules/twistDigitalBidAdapter_spec.js b/test/spec/modules/twistDigitalBidAdapter_spec.js index 7d263f6d4f0..674414bb526 100644 --- a/test/spec/modules/twistDigitalBidAdapter_spec.js +++ b/test/spec/modules/twistDigitalBidAdapter_spec.js @@ -2,15 +2,7 @@ import {expect} from 'chai'; import { spec as adapter, createDomain, - hashCode, - extractPID, - extractCID, - extractSubDomain, - getStorageItem, - setStorageItem, - tryParseJSON, - getUniqueDealId, - webSessionId + storage } from 'modules/twistDigitalBidAdapter.js'; import * as utils from 'src/utils.js'; import {version} from 'package.json'; @@ -18,6 +10,16 @@ import {useFakeTimers} from 'sinon'; import {BANNER, VIDEO} from '../../../src/mediaTypes'; import {config} from '../../../src/config'; import {deepSetValue} from 'src/utils.js'; +import { + extractPID, + extractCID, + extractSubDomain, + hashCode, + getStorageItem, + setStorageItem, + tryParseJSON, + getUniqueDealId +} from '../../../libraries/vidazooUtils/bidderUtils.js'; export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -355,7 +357,6 @@ describe('TwistDigitalBidAdapter', function () { uniqueDealId: `${hashUrl}_${Date.now().toString()}`, uqs: getTopWindowQueryParams(), isStorageAllowed: true, - webSessionId: webSessionId, mediaTypes: { video: { api: [2], @@ -453,8 +454,7 @@ describe('TwistDigitalBidAdapter', function () { name: 'example.com', segment: [{id: '243'}], }, - ], - webSessionId: webSessionId + ] } }); }); @@ -540,8 +540,7 @@ describe('TwistDigitalBidAdapter', function () { name: 'example.com', segment: [{id: '243'}], }, - ], - webSessionId: webSessionId + ] }; const REQUEST_DATA2 = utils.deepClone(REQUEST_DATA); @@ -588,7 +587,7 @@ describe('TwistDigitalBidAdapter', function () { it('should set fledge correctly if enabled', function () { config.resetConfig(); const bidderRequest = utils.deepClone(BIDDER_REQUEST); - bidderRequest.fledgeEnabled = true; + bidderRequest.paapi = {enabled: true}; deepSetValue(bidderRequest, 'ortb2Imp.ext.ae', 1); const requests = adapter.buildRequests([BID], bidderRequest); expect(requests[0].data.fledge).to.equal(1); @@ -738,8 +737,6 @@ describe('TwistDigitalBidAdapter', function () { switch (idSystemProvider) { case 'lipb': return {lipbid: id}; - case 'parrableId': - return {eid: id}; case 'id5id': return {uid: id}; default: @@ -805,13 +802,13 @@ describe('TwistDigitalBidAdapter', function () { const key = 'myKey'; let uniqueDealId; beforeEach(() => { - uniqueDealId = getUniqueDealId(key, 0); + uniqueDealId = getUniqueDealId(storage, key, 0); }) it('should get current unique deal id', function (done) { // waiting some time so `now` will become past setTimeout(() => { - const current = getUniqueDealId(key); + const current = getUniqueDealId(storage, key); expect(current).to.be.equal(uniqueDealId); done(); }, 200); @@ -819,7 +816,7 @@ describe('TwistDigitalBidAdapter', function () { it('should get new unique deal id on expiration', function (done) { setTimeout(() => { - const current = getUniqueDealId(key, 100); + const current = getUniqueDealId(storage, key, 100); expect(current).to.not.be.equal(uniqueDealId); done(); }, 200) @@ -843,8 +840,8 @@ describe('TwistDigitalBidAdapter', function () { shouldAdvanceTime: true, now }); - setStorageItem('myKey', 2020); - const {value, created} = getStorageItem('myKey'); + setStorageItem(storage, 'myKey', 2020); + const {value, created} = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -855,7 +852,7 @@ describe('TwistDigitalBidAdapter', function () { it('should get external stored value', function () { const value = 'superman' window.localStorage.setItem('myExternalKey', value); - const item = getStorageItem('myExternalKey'); + const item = getStorageItem(storage, 'myExternalKey'); expect(item).to.be.equal(value); }); diff --git a/test/spec/modules/uid2IdSystem_helpers.js b/test/spec/modules/uid2IdSystem_helpers.js index e0bef047acb..cf60b123c66 100644 --- a/test/spec/modules/uid2IdSystem_helpers.js +++ b/test/spec/modules/uid2IdSystem_helpers.js @@ -1,4 +1,4 @@ -import {setConsentConfig} from 'modules/consentManagement.js'; +import {setConsentConfig} from 'modules/consentManagementTcf.js'; import {server} from 'test/mocks/xhr.js'; import {coreStorage, requestBidsHook} from 'modules/userId/index.js'; diff --git a/test/spec/modules/uid2IdSystem_spec.js b/test/spec/modules/uid2IdSystem_spec.js index 357dfdd9bea..434bca17416 100644 --- a/test/spec/modules/uid2IdSystem_spec.js +++ b/test/spec/modules/uid2IdSystem_spec.js @@ -3,12 +3,12 @@ import {config} from 'src/config.js'; import * as utils from 'src/utils.js'; import { uid2IdSubmodule } from 'modules/uid2IdSystem.js'; import 'src/prebid.js'; -import 'modules/consentManagement.js'; +import 'modules/consentManagementTcf.js'; import { getGlobal } from 'src/prebidGlobal.js'; import { configureTimerInterceptors } from 'test/mocks/timers.js'; import { cookieHelpers, runAuction, apiHelpers, setGdprApplies } from './uid2IdSystem_helpers.js'; import {hook} from 'src/hook.js'; -import {uninstall as uninstallGdprEnforcement} from 'modules/gdprEnforcement.js'; +import {uninstall as uninstallTcfControl} from 'modules/tcfControl.js'; import {server} from 'test/mocks/xhr'; import {createEidsArray} from '../../../modules/userId/eids.js'; @@ -93,7 +93,7 @@ describe(`UID2 module`, function () { before(function () { timerSpy = configureTimerInterceptors(debugOutput); hook.ready(); - uninstallGdprEnforcement(); + uninstallTcfControl(); attachIdSystem(uid2IdSubmodule); suiteSandbox = sinon.sandbox.create(); diff --git a/test/spec/modules/unrulyBidAdapter_spec.js b/test/spec/modules/unrulyBidAdapter_spec.js index abf1a54787d..662e5c0e03d 100644 --- a/test/spec/modules/unrulyBidAdapter_spec.js +++ b/test/spec/modules/unrulyBidAdapter_spec.js @@ -696,7 +696,9 @@ describe('UnrulyAdapter', function () { it('should return an array with 2 items and enabled protected audience', function () { mockBidRequests = { 'bidderCode': 'unruly', - 'fledgeEnabled': true, + 'paapi': { + enabled: true + }, 'bids': [ { 'bidder': 'unruly', @@ -782,7 +784,9 @@ describe('UnrulyAdapter', function () { it('should return an array with 2 items and enabled protected audience on only one unit', function () { mockBidRequests = { 'bidderCode': 'unruly', - 'fledgeEnabled': true, + 'paapi': { + enabled: true + }, 'bids': [ { 'bidder': 'unruly', @@ -1043,7 +1047,7 @@ describe('UnrulyAdapter', function () { mediaType: 'video' } ], - 'fledgeAuctionConfigs': [{ + 'paapi': [{ 'bidId': bidId, 'config': { 'seller': 'https://nexxen.tech', @@ -1107,7 +1111,7 @@ describe('UnrulyAdapter', function () { expect(adapter.interpretResponse(mockServerResponse, originalRequest)).to.deep.equal({ 'bids': [], - 'fledgeAuctionConfigs': [{ + 'paapi': [{ 'bidId': bidId, 'config': { 'seller': 'https://nexxen.tech', diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index a5684fa5c8f..2f28df47667 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -4,7 +4,7 @@ import { coreStorage, dep, findRootDomain, - getConsentHash, + getConsentHash, getValidSubmoduleConfigs, init, PBJS_USER_ID_OPTOUT_NAME, requestBidsHook, @@ -21,7 +21,7 @@ import {getPrebidInternal} from 'src/utils.js'; import * as events from 'src/events.js'; import {EVENTS} from 'src/constants.js'; import {getGlobal} from 'src/prebidGlobal.js'; -import {resetConsentData} from 'modules/consentManagement.js'; +import {resetConsentData, } from 'modules/consentManagementTcf.js'; import {setEventFiredFlag as liveIntentIdSubmoduleDoNotFireEvent} from 'modules/liveIntentIdSystem.js'; import {sharedIdSystemSubmodule} from 'modules/sharedIdSystem.js'; import {pubProvidedIdSubmodule} from 'modules/pubProvidedIdSystem.js'; @@ -30,7 +30,7 @@ import 'src/prebid.js'; import {hook} from '../../../src/hook.js'; import {mockGdprConsent} from '../../helpers/consentData.js'; import {getPPID} from '../../../src/adserver.js'; -import {uninstall as uninstallGdprEnforcement} from 'modules/gdprEnforcement.js'; +import {uninstall as uninstallTcfControl} from 'modules/tcfControl.js'; import {allConsent, GDPR_GVLIDS, gdprDataHandler} from '../../../src/consentHandler.js'; import {MODULE_TYPE_UID} from '../../../src/activities/modules.js'; import {ACTIVITY_ENRICH_EIDS} from '../../../src/activities/activities.js'; @@ -154,7 +154,7 @@ describe('User ID', function () { before(function () { hook.ready(); - uninstallGdprEnforcement(); + uninstallTcfControl(); localStorage.removeItem(PBJS_USER_ID_OPTOUT_NAME); liveIntentIdSubmoduleDoNotFireEvent(); }); @@ -173,6 +173,7 @@ describe('User ID', function () { afterEach(() => { sandbox.restore(); + config.resetConfig(); }); describe('GVL IDs', () => { @@ -189,6 +190,65 @@ describe('User ID', function () { }) }) + describe('userId config validation', () => { + beforeEach(() => { + sandbox.stub(utils, 'logWarn'); + }); + + function mockConfig(storageConfig = {}) { + return { + name: 'mockModule', + storage: { + name: 'mockStorage', + type: 'cookie', + ...storageConfig + } + } + } + + Object.entries({ + 'not an object': 'garbage', + 'missing name': {}, + 'empty name': {name: ''}, + 'empty storage config': {name: 'mockId', storage: {}}, + 'storage type, but no storage name': mockConfig({name: ''}), + 'storage name, but no storage type': mockConfig({type: undefined}), + }).forEach(([t, config]) => { + it(`should log a warning and reject configuration with ${t}`, () => { + expect(getValidSubmoduleConfigs([config]).length).to.equal(0); + sinon.assert.called(utils.logWarn); + }); + }); + + it('should reject non-array userId configuration', () => { + expect(getValidSubmoduleConfigs({})).to.eql([]); + sinon.assert.called(utils.logWarn); + }); + + it('should accept null configuration', () => { + expect(getValidSubmoduleConfigs()).to.eql([]); + sinon.assert.notCalled(utils.logWarn); + }); + + ['refreshInSeconds', 'expires'].forEach(param => { + describe(`${param} parameter`, () => { + it('should be made a number, when possible', () => { + expect(getValidSubmoduleConfigs([mockConfig({[param]: '123'})])[0].storage[param]).to.equal(123); + }); + + it('should log a warning when not a number', () => { + expect(getValidSubmoduleConfigs([mockConfig({[param]: 'garbage'})])[0].storage[param]).to.not.exist; + sinon.assert.called(utils.logWarn) + }); + + it('should be left untouched when not specified', () => { + expect(getValidSubmoduleConfigs([mockConfig()])[0].storage[param]).to.not.exist; + sinon.assert.notCalled(utils.logWarn); + }); + }) + }) + }) + describe('Decorate Ad Units', function () { beforeEach(function () { // reset mockGpt so nothing else interferes @@ -1310,7 +1370,6 @@ describe('User ID', function () { coreStorage.setCookie(PBJS_USER_ID_OPTOUT_NAME, '', EXPIRED_COOKIE_DATE); $$PREBID_GLOBAL$$.requestBids.removeAll(); utils.logInfo.restore(); - config.resetConfig(); }); it('does not fetch ids if opt out cookie exists', function () { @@ -1340,7 +1399,6 @@ describe('User ID', function () { afterEach(function () { $$PREBID_GLOBAL$$.requestBids.removeAll(); utils.logInfo.restore(); - config.resetConfig(); }); it('handles config with no usersync object', function () { @@ -1455,7 +1513,7 @@ describe('User ID', function () { expect(auctionDelay).to.equal(100); }); - it('config auctionDelay defaults to 0 if not a number', function () { + it('config auctionDelay defaults to 500 if not a number', function () { init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); config.setConfig({ @@ -1467,7 +1525,7 @@ describe('User ID', function () { }] } }); - expect(auctionDelay).to.equal(0); + expect(auctionDelay).to.equal(500); }); describe('auction and user sync delays', function () { @@ -1585,9 +1643,10 @@ describe('User ID', function () { }); }); - it('does not delay auction if not set, delays id fetch after auction ends with syncDelay', function () { + it('does not delay auction if set to 0, delays id fetch after auction ends with syncDelay', function () { config.setConfig({ userSync: { + auctionDelay: 0, syncDelay: 77, userIds: [{ name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} @@ -1595,10 +1654,6 @@ describe('User ID', function () { } }); - // check config has been set correctly - expect(auctionDelay).to.equal(0); - expect(syncDelay).to.equal(77); - return expectImmediateBidHook(auctionSpy, {adUnits}) .then(() => { // should not delay auction @@ -1624,6 +1679,7 @@ describe('User ID', function () { it('does not delay user id sync after auction ends if set to 0', function () { config.setConfig({ userSync: { + auctionDelay: 0, syncDelay: 0, userIds: [{ name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} @@ -1631,8 +1687,6 @@ describe('User ID', function () { } }); - expect(syncDelay).to.equal(0); - return expectImmediateBidHook(auctionSpy, {adUnits}) .then(() => { // auction should not be delayed @@ -2040,6 +2094,7 @@ describe('User ID', function () { done(); }, {adUnits}); }); + it('should add new id system ', function (done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); @@ -2137,6 +2192,12 @@ describe('User ID', function () { describe('callbacks at the end of auction', function () { beforeEach(function () { + config.setConfig({ + // callbacks run after auction end only when auctionDelay is 0 + userSync: { + auctionDelay: 0, + } + }) sinon.stub(events, 'getEvents').returns([]); sinon.stub(utils, 'triggerPixel'); coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -2156,17 +2217,13 @@ describe('User ID', function () { } it('pubcid callback with url', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; let customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url'}); init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); - config.setConfig(customCfg); - return runBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}).then(() => { + config.mergeConfig(customCfg); + return runBidsHook({}).then(() => { expect(utils.triggerPixel.called).to.be.false; return endAuction(); }).then(() => { @@ -2175,60 +2232,40 @@ describe('User ID', function () { }); }); - describe('Set cookie behavior', function () { - let cookie, cookieStub; - - beforeEach(function () { - setSubmoduleRegistry([sharedIdSystemSubmodule]); - init(config); - cookie = document.cookie; - cookieStub = sinon.stub(document, 'cookie'); - cookieStub.get(() => cookie); - cookieStub.set((val) => cookie = val); - }); - - afterEach(function () { - cookieStub.restore(); - }); - - it('should allow submodules to override the domain', function () { - const submodule = { - submodule: { - domainOverride: function () { - return 'foo.com' - } - }, + describe('Submodule ID storage', () => { + let submodule; + beforeEach(() => { + submodule = { + submodule: {}, config: { name: 'mockId', - storage: { - type: 'cookie' - } }, storageMgr: { - setCookie: sinon.stub() + setCookie: sinon.stub(), + setDataInLocalStorage: sinon.stub() }, - enabledStorageTypes: [ 'cookie' ] + enabledStorageTypes: ['cookie', 'html5'] } - setStoredValue(submodule, 'bar'); - expect(submodule.storageMgr.setCookie.getCall(0).args[4]).to.equal('foo.com'); }); - it('should pass no domain if submodule does not override the domain', function () { - const submodule = { - submodule: {}, - config: { - name: 'mockId', - storage: { - type: 'cookie' - } - }, - storageMgr: { - setCookie: sinon.stub() - }, - enabledStorageTypes: [ 'cookie' ] - } - setStoredValue(submodule, 'bar'); - expect(submodule.storageMgr.setCookie.getCall(0).args[4]).to.equal(null); + describe('Set cookie behavior', function () { + beforeEach(() => { + submodule.config.storage = { + type: 'cookie' + } + }); + it('should allow submodules to override the domain', function () { + submodule.submodule.domainOverride = function() { + return 'foo.com' + } + setStoredValue(submodule, 'bar'); + expect(submodule.storageMgr.setCookie.getCall(0).args[4]).to.equal('foo.com'); + }); + + it('should pass no domain if submodule does not override the domain', function () { + setStoredValue(submodule, 'bar'); + expect(submodule.storageMgr.setCookie.getCall(0).args[4]).to.equal(null); + }); }); }); diff --git a/test/spec/modules/utiqSystem_spec.js b/test/spec/modules/utiqIdSystem_spec.js similarity index 86% rename from test/spec/modules/utiqSystem_spec.js rename to test/spec/modules/utiqIdSystem_spec.js index afeeea7c3ea..62754d39fa3 100644 --- a/test/spec/modules/utiqSystem_spec.js +++ b/test/spec/modules/utiqIdSystem_spec.js @@ -1,8 +1,8 @@ import { expect } from 'chai'; -import { utiqSubmodule } from 'modules/utiqSystem.js'; -import { storage } from 'modules/utiqSystem.js'; +import { utiqIdSubmodule } from 'modules/utiqIdSystem.js'; +import { storage } from 'modules/utiqIdSystem.js'; -describe('utiqSystem', () => { +describe('utiqIdSystem', () => { const utiqPassKey = 'utiqPass'; const getStorageData = (idGraph) => { @@ -17,7 +17,7 @@ describe('utiqSystem', () => { }; it('should have the correct module name declared', () => { - expect(utiqSubmodule.name).to.equal('utiq'); + expect(utiqIdSubmodule.name).to.equal('utiqId'); }); describe('utiq getId()', () => { @@ -26,13 +26,13 @@ describe('utiqSystem', () => { }); it('it should return object with key callback', () => { - expect(utiqSubmodule.getId()).to.have.property('callback'); + expect(utiqIdSubmodule.getId()).to.have.property('callback'); }); it('should return object with key callback with value type - function', () => { storage.setDataInLocalStorage(utiqPassKey, JSON.stringify(getStorageData())); - expect(utiqSubmodule.getId()).to.have.property('callback'); - expect(typeof utiqSubmodule.getId().callback).to.be.equal('function'); + expect(utiqIdSubmodule.getId()).to.have.property('callback'); + expect(typeof utiqIdSubmodule.getId().callback).to.be.equal('function'); }); it('tests if localstorage & JSON works properly ', () => { @@ -50,7 +50,7 @@ describe('utiqSystem', () => { 'atid': 'atidValue', }; storage.setDataInLocalStorage(utiqPassKey, JSON.stringify(getStorageData(idGraph))); - const response = utiqSubmodule.getId(); + const response = utiqIdSubmodule.getId(); expect(response).to.have.property('id'); expect(response.id).to.have.property('utiq'); expect(response.id.utiq).to.be.equal('atidValue'); @@ -61,7 +61,7 @@ describe('utiqSystem', () => { 'domain': 'test.domain', 'atid': 'atidValue', }; - const response = utiqSubmodule.getId(); + const response = utiqIdSubmodule.getId(); expect(response).to.have.property('callback'); expect(response.callback.toString()).contain('result(callback)'); @@ -82,7 +82,7 @@ describe('utiqSystem', () => { 'atid': 'atidValue', }; - const response = utiqSubmodule.getId(); + const response = utiqIdSubmodule.getId(); expect(response).to.have.property('callback'); expect(response.callback.toString()).contain('result(callback)'); @@ -105,7 +105,7 @@ describe('utiqSystem', () => { 'atid': 'atidValue', }; - const response = utiqSubmodule.getId({params: {maxDelayTime: 200}}); + const response = utiqIdSubmodule.getId({params: {maxDelayTime: 200}}); expect(response).to.have.property('callback'); expect(response.callback.toString()).contain('result(callback)'); @@ -138,7 +138,7 @@ describe('utiqSystem', () => { ]; VALID_API_RESPONSES.forEach(responseData => { it('should return a newly constructed object with the utiq for a payload with {utiq: value}', () => { - expect(utiqSubmodule.decode(responseData.payload)).to.deep.equal( + expect(utiqIdSubmodule.decode(responseData.payload)).to.deep.equal( {utiq: responseData.expected} ); }); @@ -146,7 +146,7 @@ describe('utiqSystem', () => { [{}, '', {foo: 'bar'}].forEach((response) => { it(`should return null for an invalid response "${JSON.stringify(response)}"`, () => { - expect(utiqSubmodule.decode(response)).to.be.null; + expect(utiqIdSubmodule.decode(response)).to.be.null; }); }); }); @@ -177,7 +177,7 @@ describe('utiqSystem', () => { window.dispatchEvent(new MessageEvent('message', eventData)); - const response = utiqSubmodule.getId(); + const response = utiqIdSubmodule.getId(); expect(response).to.have.property('id'); expect(response.id).to.have.property('utiq'); expect(response.id.utiq).to.be.equal('atidValue'); diff --git a/test/spec/modules/viantOrtbBidAdapter_spec.js b/test/spec/modules/viantOrtbBidAdapter_spec.js index 73fdb7f3dc8..a289faf3573 100644 --- a/test/spec/modules/viantOrtbBidAdapter_spec.js +++ b/test/spec/modules/viantOrtbBidAdapter_spec.js @@ -1,8 +1,9 @@ -import { spec, converter } from 'modules/viantOrtbBidAdapter.js'; +import {spec, converter} from 'modules/viantOrtbBidAdapter.js'; import {assert, expect} from 'chai'; -import { deepClone } from '../../../src/utils'; +import {deepClone} from '../../../src/utils'; import {buildWindowTree} from '../../helpers/refererDetectionHelper'; import {detectReferer} from '../../../src/refererDetection'; + describe('viantOrtbBidAdapter', function () { function testBuildRequests(bidRequests, bidderRequestBase) { let clonedBidderRequest = deepClone(bidderRequestBase); @@ -10,7 +11,8 @@ describe('viantOrtbBidAdapter', function () { let requests = spec.buildRequests(bidRequests, clonedBidderRequest); return requests } - describe('isBidRequestValid', function() { + + describe('isBidRequestValid', function () { function makeBid() { return { 'bidder': 'viant', @@ -46,9 +48,7 @@ describe('viantOrtbBidAdapter', function () { it('should return true if placementId is not passed ', function () { let bid = makeBid(); delete bid.params.placementId; - bid.ortb2Imp = { - - } + bid.ortb2Imp = {} expect(spec.isBidRequestValid(bid)).to.equal(true); }); @@ -98,6 +98,7 @@ describe('viantOrtbBidAdapter', function () { 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' } } + it('should return true when required params found', function () { expect(spec.isBidRequestValid(makeBid())).to.equal(true); }); @@ -141,6 +142,7 @@ describe('viantOrtbBidAdapter', function () { 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' } } + it('should return true when required params found', function () { expect(spec.isBidRequestValid(makeBid())).to.equal(true); }); @@ -180,6 +182,57 @@ describe('viantOrtbBidAdapter', function () { 'src': 'client', 'bidRequestsCount': 1 }]; + const basePMPDealsBidRequests = [{ + 'bidder': 'viant', + 'params': { + 'publisherId': '464', + 'placementId': '1' + }, + 'ortb2Imp': { + 'pmp': { + 'private_auction': 0, + 'deals': [ + { + 'id': '1234567', + 'at': 3, + 'bidfloor': 25, + 'bidfloorcur': 'USD', + 'ext': { + 'must_bid': 1, + 'private_auction': 1 + } + }, + { + 'id': '1234568', + 'at': 3, + 'bidfloor': 25, + 'bidfloorcur': 'USD', + 'ext': { + 'must_bid': 0 + } + } + ] + }, + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[728, 90]] + } + }, + 'gdprConsent': { + 'consentString': 'consentString', + 'gdprApplies': true, + }, + 'uspConsent': '1YYY', + 'sizes': [[728, 90]], + 'transactionId': '1111474f-58b1-4368-b812-84f8c937a099', + 'adUnitCode': 'div-gpt-ad-1460505748561-0', + 'bidId': '243310435309b5', + 'bidderRequestId': '18084284054531', + 'auctionId': 'e7b34fa3-8654-424e-8c49-03e509e53d8c', + 'src': 'client', + 'bidRequestsCount': 1 + }]; const testWindow = buildWindowTree(['https://www.example.com/test', 'https://www.example.com/other/page', 'https://www.example.com/third/page'], 'https://othersite.com/', 'https://example.com/canonical/page'); const baseBidderRequestReferer = detectReferer(testWindow)(); @@ -236,6 +289,34 @@ describe('viantOrtbBidAdapter', function () { const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest)[0].data; expect(requestBody.imp[0].banner.pos).to.equal(1); }); + it('includes the deals in the bid request', function () { + const requestBody = testBuildRequests(basePMPDealsBidRequests, baseBidderRequest)[0].data; + expect(requestBody.imp[0].pmp).to.be.not.null; + expect(requestBody.imp[0].pmp).to.deep.equal({ + 'private_auction': 0, + 'deals': [ + { + 'id': '1234567', + 'at': 3, + 'bidfloor': 25, + 'bidfloorcur': 'USD', + 'ext': { + 'must_bid': 1, + 'private_auction': 1 + } + }, + { + 'id': '1234568', + 'at': 3, + 'bidfloor': 25, + 'bidfloorcur': 'USD', + 'ext': { + 'must_bid': 0 + } + } + ] + }); + }); }); if (FEATURES.VIDEO) { @@ -259,6 +340,7 @@ describe('viantOrtbBidAdapter', function () { 'skip': 1, 'skipafter': 5, 'minduration': 10, + 'placement': 1, 'maxduration': 31 } }, diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index 5515002a054..c5da6eebdd9 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -1,7 +1,11 @@ import {expect} from 'chai'; import { spec as adapter, + storage, createDomain, + webSessionId +} from 'modules/vidazooBidAdapter.js'; +import { hashCode, extractPID, extractCID, @@ -11,9 +15,9 @@ import { tryParseJSON, getUniqueDealId, getNextDealId, - getVidazooSessionId, - webSessionId -} from 'modules/vidazooBidAdapter.js'; + getTopWindowQueryParams, + getVidazooSessionId +} from 'libraries/vidazooUtils/bidderUtils.js' import * as utils from 'src/utils.js'; import {version} from 'package.json'; import {useFakeTimers} from 'sinon'; @@ -21,7 +25,7 @@ import {BANNER, VIDEO} from '../../../src/mediaTypes'; import {config} from '../../../src/config'; import {deepSetValue} from 'src/utils.js'; -export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; +export const TEST_ID_SYSTEMS = ['criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'pubcid', 'tdid', 'pubProvidedId']; const SUB_DOMAIN = 'openrtb'; @@ -205,15 +209,6 @@ const REQUEST = { } }; -function getTopWindowQueryParams() { - try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); - return parsedUrl.search; - } catch (e) { - return ''; - } -} - describe('VidazooBidAdapter', function () { describe('validtae spec', function () { it('exists and is a function', function () { @@ -317,6 +312,7 @@ describe('VidazooBidAdapter', function () { gpid: '', prebidVersion: version, ptrace: '1000', + vdzhum: '1000', publisherId: '59ac17c192832d0011283fe3', url: 'https%3A%2F%2Fwww.greatsite.com', referrer: 'https://www.somereferrer.com', @@ -436,6 +432,7 @@ describe('VidazooBidAdapter', function () { prebidVersion: version, schain: BID.schain, ptrace: '1000', + vdzhum: '1000', res: `${window.top.screen.width}x${window.top.screen.height}`, mediaTypes: [BANNER], uqs: getTopWindowQueryParams(), @@ -526,6 +523,7 @@ describe('VidazooBidAdapter', function () { prebidVersion: version, schain: BID.schain, ptrace: '1000', + vdzhum: '1000', res: `${window.top.screen.width}x${window.top.screen.height}`, mediaTypes: [BANNER], uqs: getTopWindowQueryParams(), @@ -600,7 +598,7 @@ describe('VidazooBidAdapter', function () { it('should set fledge correctly if enabled', function () { config.resetConfig(); const bidderRequest = utils.deepClone(BIDDER_REQUEST); - bidderRequest.fledgeEnabled = true; + bidderRequest.paapi = {enabled: true}; deepSetValue(bidderRequest, 'ortb2Imp.ext.ae', 1); const requests = adapter.buildRequests([BID], bidderRequest); expect(requests[0].data.fledge).to.equal(1); @@ -750,8 +748,6 @@ describe('VidazooBidAdapter', function () { switch (idSystemProvider) { case 'lipb': return {lipbid: id}; - case 'parrableId': - return {eid: id}; case 'id5id': return {uid: id}; default: @@ -802,14 +798,14 @@ describe('VidazooBidAdapter', function () { $$PREBID_GLOBAL$$.bidderSettings = {}; }); it('should get undefined vidazoo session id', function () { - const sessionId = getVidazooSessionId(); + const sessionId = getVidazooSessionId(storage); expect(sessionId).to.be.empty; }); it('should get vidazoo session id from storage', function () { const vidSid = '1234-5678'; window.localStorage.setItem('vidSid', vidSid); - const sessionId = getVidazooSessionId(); + const sessionId = getVidazooSessionId(storage); expect(sessionId).to.be.equal(vidSid); }); }); @@ -828,15 +824,15 @@ describe('VidazooBidAdapter', function () { const key = 'myDealKey'; it('should get the next deal id', function () { - const dealId = getNextDealId(key); - const nextDealId = getNextDealId(key); + const dealId = getNextDealId(storage, key); + const nextDealId = getNextDealId(storage, key); expect(dealId).to.be.equal(1); expect(nextDealId).to.be.equal(2); }); it('should get the first deal id on expiration', function (done) { setTimeout(function () { - const dealId = getNextDealId(key, 100); + const dealId = getNextDealId(storage, key, 100); expect(dealId).to.be.equal(1); done(); }, 200); @@ -857,13 +853,13 @@ describe('VidazooBidAdapter', function () { const key = 'myKey'; let uniqueDealId; beforeEach(() => { - uniqueDealId = getUniqueDealId(key, 0); + uniqueDealId = getUniqueDealId(storage, key, 0); }) it('should get current unique deal id', function (done) { // waiting some time so `now` will become past setTimeout(() => { - const current = getUniqueDealId(key); + const current = getUniqueDealId(storage, key); expect(current).to.be.equal(uniqueDealId); done(); }, 200); @@ -871,7 +867,7 @@ describe('VidazooBidAdapter', function () { it('should get new unique deal id on expiration', function (done) { setTimeout(() => { - const current = getUniqueDealId(key, 100); + const current = getUniqueDealId(storage, key, 100); expect(current).to.not.be.equal(uniqueDealId); done(); }, 200) @@ -895,8 +891,8 @@ describe('VidazooBidAdapter', function () { shouldAdvanceTime: true, now }); - setStorageItem('myKey', 2020); - const {value, created} = getStorageItem('myKey'); + setStorageItem(storage, 'myKey', 2020); + const {value, created} = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -907,7 +903,7 @@ describe('VidazooBidAdapter', function () { it('should get external stored value', function () { const value = 'superman' window.localStorage.setItem('myExternalKey', value); - const item = getStorageItem('myExternalKey'); + const item = getStorageItem(storage, 'myExternalKey'); expect(item).to.be.equal(value); }); diff --git a/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js b/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js index a7379ccbab2..125f608f803 100644 --- a/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js +++ b/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js @@ -6,7 +6,7 @@ import { const {VideojsProvider, utils} = require('modules/videojsVideoProvider'); const { - PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLACEMENT, VPAID_MIME_TYPE, AD_POSITION + PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLCMT, VPAID_MIME_TYPE, AD_POSITION } = require('libraries/video/constants/ortb.js'); const videojs = require('video.js').default; @@ -139,7 +139,7 @@ describe('videojsProvider', function () { expect(video.playbackmethod).to.include(PLAYBACK_METHODS.CLICK_TO_PLAY); expect(video.playbackend).to.equal(1); expect(video.api).to.deep.equal([2]); - expect(video.placement).to.be.equal(PLACEMENT.INSTREAM); + expect(video.plcmt).to.be.equal(PLCMT.ACCOMPANYING_CONTENT); }); it('should populate oRTB Content', function () { diff --git a/test/spec/modules/videoreachBidAdapter_spec.js b/test/spec/modules/videoreachBidAdapter_spec.js index 67ad89eac3d..dc81ec74ff8 100644 --- a/test/spec/modules/videoreachBidAdapter_spec.js +++ b/test/spec/modules/videoreachBidAdapter_spec.js @@ -21,12 +21,12 @@ describe('videoreachBidAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'TagId': '' }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/vidoomyBidAdapter_spec.js b/test/spec/modules/vidoomyBidAdapter_spec.js index 38fa872e6b8..6fd779bdb0b 100644 --- a/test/spec/modules/vidoomyBidAdapter_spec.js +++ b/test/spec/modules/vidoomyBidAdapter_spec.js @@ -44,9 +44,9 @@ describe('vidoomyBidAdapter', function() { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when mediaType is video with INSTREAM context and lacks playerSize property', function () { diff --git a/test/spec/modules/visiblemeasuresBidAdapter_spec.js b/test/spec/modules/visiblemeasuresBidAdapter_spec.js index ad75e17699f..1e0fd6f64d2 100644 --- a/test/spec/modules/visiblemeasuresBidAdapter_spec.js +++ b/test/spec/modules/visiblemeasuresBidAdapter_spec.js @@ -3,11 +3,21 @@ import { spec } from '../../../modules/visiblemeasuresBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; -const bidder = 'visiblemeasures' +const bidder = 'visiblemeasures'; const adUrl = 'https://us-e.visiblemeasures.com/pbjs'; const syncUrl = 'https://cs.visiblemeasures.com'; describe('VisibleMeasuresBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -18,8 +28,9 @@ describe('VisibleMeasuresBidAdapter', function () { } }, params: { - placementId: 'testBanner', - } + placementId: 'testBanner' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -32,8 +43,9 @@ describe('VisibleMeasuresBidAdapter', function () { } }, params: { - placementId: 'testVideo', - } + placementId: 'testVideo' + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -55,8 +67,9 @@ describe('VisibleMeasuresBidAdapter', function () { } }, params: { - placementId: 'testNative', - } + placementId: 'testNative' + }, + userIdAsEids } ]; @@ -75,9 +88,20 @@ describe('VisibleMeasuresBidAdapter', function () { const bidderRequest = { uspConsent: '1---', - gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, refererInfo: { - referer: 'https://test.com' + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } }, timeout: 500 }; @@ -131,7 +155,7 @@ describe('VisibleMeasuresBidAdapter', function () { expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); expect(data.coppa).to.be.a('number'); - expect(data.gdpr).to.be.a('string'); + expect(data.gdpr).to.be.a('object'); expect(data.ccpa).to.be.a('string'); expect(data.tmax).to.be.a('number'); expect(data.placements).to.have.lengthOf(3); @@ -147,6 +171,56 @@ describe('VisibleMeasuresBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -172,8 +246,10 @@ describe('VisibleMeasuresBidAdapter', function () { serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); @@ -188,12 +264,38 @@ describe('VisibleMeasuresBidAdapter', function () { expect(data.ccpa).to.equal(bidderRequest.uspConsent); expect(data.gdpr).to.not.exist; }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([], bidderRequest); + let serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) }); describe('interpretResponse', function () { @@ -397,5 +499,17 @@ describe('VisibleMeasuresBidAdapter', function () { expect(syncData[0].url).to.be.a('string') expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&ccpa_consent=1---&coppa=0`) }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0`); + }); }); }); diff --git a/test/spec/modules/visxBidAdapter_spec.js b/test/spec/modules/visxBidAdapter_spec.js index f70f614b2c8..db928e4d802 100755 --- a/test/spec/modules/visxBidAdapter_spec.js +++ b/test/spec/modules/visxBidAdapter_spec.js @@ -4,6 +4,7 @@ import { config } from 'src/config.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; import { makeSlot } from '../integration/faker/googletag.js'; +import { mergeDeep } from '../../../src/utils.js'; describe('VisxAdapter', function () { const adapter = newBidder(spec); @@ -32,21 +33,21 @@ describe('VisxAdapter', function () { }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'uid': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when uid can not be parsed as number', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'uid': 'sdvsdv' }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('it should fail on invalid video bid', function () { @@ -2161,4 +2162,183 @@ describe('VisxAdapter', function () { expect(request.data.user.ext.vads).to.be.a('string'); }); }); + + describe('ortb2 data', function () { + const bidRequests = [ + { + 'bidder': 'visx', + 'params': { + 'uid': 903535 + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475' + } + ]; + const bidderRequest = { + timeout: 3000, + refererInfo: { + page: 'https://example.com' + }, + 'ortb2': { + 'device': { + 'w': 1259, + 'h': 934, + 'dnt': 0, + 'ua': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', + 'language': 'tr', + 'sua': { + 'source': 1, + 'platform': { + 'brand': 'macOS' + }, + 'browsers': [ + { + 'brand': 'Chromium', + 'version': [ '124' ] + }, + { + 'brand': 'Google Chrome', + 'version': [ '124' ] + }, + { + 'brand': 'Not-A.Brand', + 'version': [ '99' ] + } + ], + 'mobile': 0 + }, + 'ext': { + 'cdep': 'treatment_1.1' + } + }, + 'site': { + 'domain': 'localhost:9999', + 'publisher': { + 'domain': 'localhost:9999' + }, + 'page': 'http://localhost:9999/integrationExamples/gpt/hello_world.html' + }, + 'user': { + 'keywords': 'x,y', + 'data': [ + { + 'name': 'exampleprovider.de', + 'ext': { + 'segtax': 5 + }, + 'segment': [ + { + 'id': '1' + } + ] + }, + { + 'ext': { + 'segtax': 601, + 'segclass': '5' + }, + 'segment': [ + { + 'id': '140' + } + ], + 'name': 'pa.openx.net' + }, + { + 'ext': { + 'segtax': 601, + 'segclass': '5' + }, + 'segment': [ + { + 'id': '140' + } + ], + 'name': 'ads.pubmatic.com' + } + ], + 'ext': { + 'data': { + 'registered': true, + 'interests': [ + 'ads' + ] + } + } + } + } + }; + + it('should pass interests if ortb2 has interests in user data', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.user.ext.data.interests).not.to.be.undefined; + }); + + it('should pass device if ortb2 has device', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.device).not.to.be.undefined; + }); + + it('should pass site if ortb2 has site', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.site).not.to.be.undefined; + }); + + it('should merge if user object exists', function () { + const user = { + 'ext': { + 'vads': 'cXaIRA425BmynEN1ratEnc_5e', + 'data': { + 'registered': true, + 'interests': [ + 'ads' + ] + } + }, + 'keywords': 'x,y', + 'data': [ + { + 'name': 'exampleprovider.de', + 'ext': { + 'segtax': 5 + }, + 'segment': [ + { + 'id': '1' + } + ] + } + ] + }; + const userOrtb2 = { + 'keywords': 'x,y', + 'data': [ + { + 'name': 'exampleprovider.de', + 'ext': { + 'segtax': 5 + }, + 'segment': [ + { + 'id': '1' + } + ] + } + ], + 'ext': { + 'data': { + 'registered': true, + 'interests': [ + 'ads' + ] + } + } + } + const userReq = mergeDeep(user, userOrtb2); + expect(userReq.ext.vads).not.to.be.undefined; + }); + }); }); diff --git a/test/spec/modules/winrBidAdapter_spec.js b/test/spec/modules/winrBidAdapter_spec.js index 95d1473d1cb..b0d8d72f0a1 100644 --- a/test/spec/modules/winrBidAdapter_spec.js +++ b/test/spec/modules/winrBidAdapter_spec.js @@ -93,22 +93,22 @@ describe('WinrAdapter', function () { }); it('should return false when mediaType is not banner', function () { - let bid = Object.assign({}, bid); - delete bid.mediaTypes; - bid.mediaTypes = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.mediaTypes; + invalidBid.mediaTypes = { 'video': {} }; - expect(getMediaTypeFromBid(bid)).to.not.equal('banner'); - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(getMediaTypeFromBid(invalidBid)).to.not.equal('banner'); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { + let invalidBid = Object.assign({}, bid); + delete invalidBid.params; + invalidBid.params = { 'placementId': 0 }; - expect(spec.isBidRequestValid(bid)).to.equal(false); + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/wipesBidAdapter_spec.js b/test/spec/modules/wipesBidAdapter_spec.js index a458dcf69c8..a45e324f4fd 100644 --- a/test/spec/modules/wipesBidAdapter_spec.js +++ b/test/spec/modules/wipesBidAdapter_spec.js @@ -29,9 +29,9 @@ describe('wipesBidAdapter', function () { }); it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/yahoosspBidAdapter_spec.js b/test/spec/modules/yahooAdsBidAdapter_spec.js similarity index 99% rename from test/spec/modules/yahoosspBidAdapter_spec.js rename to test/spec/modules/yahooAdsBidAdapter_spec.js index 40dc2b3c63b..aaa7e2da8ee 100644 --- a/test/spec/modules/yahoosspBidAdapter_spec.js +++ b/test/spec/modules/yahooAdsBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { config } from 'src/config.js'; import { BANNER, VIDEO } from 'src/mediaTypes.js'; -import { spec } from 'modules/yahoosspBidAdapter.js'; +import { spec } from 'modules/yahooAdsBidAdapter.js'; import {createEidsArray} from '../../../modules/userId/eids'; const DEFAULT_BID_ID = '84ab500420319d'; @@ -193,7 +193,7 @@ describe('Yahoo Advertising Bid Adapter:', () => { }); it('should define the correct bidder aliases', () => { - expect(spec.aliases).to.deep.equal(['yahoossp', 'yahooAdvertising']); + expect(spec.aliases).to.deep.equal([{ 'code': 'yahoossp', 'gvlid': 25 }, { 'code': 'yahooAdvertising', 'gvlid': 25 }]); }); it('should define the correct vendor ID', () => { @@ -1169,7 +1169,8 @@ describe('Yahoo Advertising Bid Adapter:', () => { pos: undefined, playbackmethod: undefined, rewarded: undefined, - placement: undefined + placement: undefined, + plcmt: undefined }); }); @@ -1201,7 +1202,8 @@ describe('Yahoo Advertising Bid Adapter:', () => { pos: undefined, playbackmethod: undefined, rewarded: undefined, - placement: undefined + placement: undefined, + plcmt: undefined }); }); }); @@ -1298,7 +1300,8 @@ describe('Yahoo Advertising Bid Adapter:', () => { pos: undefined, playbackmethod: undefined, rewarded: undefined, - placement: undefined + placement: undefined, + plcmt: undefined }); }); }); @@ -1351,7 +1354,8 @@ describe('Yahoo Advertising Bid Adapter:', () => { pos: undefined, playbackmethod: undefined, rewarded: undefined, - placement: undefined + placement: undefined, + plcmt: undefined }); }); }); @@ -1381,7 +1385,8 @@ describe('Yahoo Advertising Bid Adapter:', () => { pos: 123456, playbackmethod: 1, rewarded: 1, - placement: 1 + placement: 1, + plcmt: 1 } } } @@ -1410,7 +1415,8 @@ describe('Yahoo Advertising Bid Adapter:', () => { delivery: 1, pos: 123456, playbackmethod: 1, - placement: 1 + placement: 1, + plcmt: 1 } const validBidRequests = [bidRequest]; bidderRequest.bids = validBidRequests; @@ -1430,6 +1436,7 @@ describe('Yahoo Advertising Bid Adapter:', () => { pos: 123456, playbackmethod: 1, placement: 1, + plcmt: 1, rewarded: undefined }); }); diff --git a/test/spec/modules/yandexIdSystem_spec.js b/test/spec/modules/yandexIdSystem_spec.js new file mode 100644 index 00000000000..8ae7a374bfa --- /dev/null +++ b/test/spec/modules/yandexIdSystem_spec.js @@ -0,0 +1,142 @@ +// @ts-check + +import { yandexIdSubmodule, PREBID_STORAGE, BIDDER_CODE, YANDEX_USER_ID_KEY, YANDEX_COOKIE_STORAGE_TYPE, YANDEX_MIN_EXPIRE_DAYS } from '../../../modules/yandexIdSystem.js'; +import {createSandbox} from 'sinon' +import * as utils from '../../../src/utils.js'; + +/** + * @typedef {import('sinon').SinonStub} SinonStub + * @typedef {import('sinon').SinonSpy} SinonSpy + * @typedef {import('sinon').SinonSandbox} SinonSandbox + */ + +const MIN_METRICA_ID_LEN = 17; + +/** @satisfies {import('../../../modules/userId/index.js').SubmoduleConfig} */ +const CORRECT_SUBMODULE_CONFIG = { + name: BIDDER_CODE, + storage: { + expires: YANDEX_MIN_EXPIRE_DAYS, + name: YANDEX_USER_ID_KEY, + type: YANDEX_COOKIE_STORAGE_TYPE, + refreshInSeconds: undefined, + }, + params: undefined, + value: undefined, +}; + +/** @type {import('../../../modules/userId/index.js').SubmoduleConfig[]} */ +const INCORRECT_SUBMODULE_CONFIGS = [ + { + ...CORRECT_SUBMODULE_CONFIG, + storage: { + ...CORRECT_SUBMODULE_CONFIG.storage, + expires: 0, + } + }, + { + ...CORRECT_SUBMODULE_CONFIG, + storage: { + ...CORRECT_SUBMODULE_CONFIG.storage, + type: 'html5' + } + }, + { + ...CORRECT_SUBMODULE_CONFIG, + storage: { + ...CORRECT_SUBMODULE_CONFIG.storage, + name: 'custom_key' + } + }, +]; + +describe('YandexId module', () => { + /** @type {SinonSandbox} */ + let sandbox; + /** @type {SinonStub} */ + let getCryptoRandomValuesStub; + /** @type {SinonStub} */ + let randomStub; + /** @type {SinonSpy} */ + let logErrorSpy; + + beforeEach(() => { + sandbox = createSandbox(); + logErrorSpy = sandbox.spy(utils, 'logError'); + + getCryptoRandomValuesStub = sandbox + .stub(window.crypto, 'getRandomValues') + .callsFake((bufferView) => { + if (bufferView != null) { + bufferView[0] = 10000; + } + + return null; + }); + randomStub = sandbox.stub(window.Math, 'random').returns(0.555); + }); + + afterEach(() => { + sandbox.restore(); + }); + + describe('getId()', () => { + it('user id matches Yandex Metrica format', () => { + const generatedId = yandexIdSubmodule.getId(CORRECT_SUBMODULE_CONFIG)?.id; + + expect(isNaN(Number(generatedId))).to.be.false; + expect(generatedId).to.have.length.greaterThanOrEqual( + MIN_METRICA_ID_LEN + ); + }); + + it('uses stored id', () => { + const storedId = '11111111111111111'; + const generatedId = yandexIdSubmodule.getId(CORRECT_SUBMODULE_CONFIG, undefined, storedId)?.id; + + expect(generatedId).to.be.equal(storedId); + }) + + describe('config validation', () => { + INCORRECT_SUBMODULE_CONFIGS.forEach((config, i) => { + it(`invalid config #${i} fails`, () => { + const generatedId = yandexIdSubmodule.getId(config)?.id; + + expect(generatedId).to.be.undefined; + expect(logErrorSpy.called).to.be.true; + }) + }) + }) + + describe('crypto', () => { + it('uses Math.random when crypto is not available', () => { + const cryptoTmp = window.crypto; + + // @ts-expect-error -- Crypto is always defined in modern JS. TS yells when trying to delete non-nullable property. + delete window.crypto; + + yandexIdSubmodule.getId(CORRECT_SUBMODULE_CONFIG); + + expect(randomStub.calledOnce).to.be.true; + expect(getCryptoRandomValuesStub.called).to.be.false; + + window.crypto = cryptoTmp; + }); + + it('uses crypto when it is available', () => { + yandexIdSubmodule.getId(CORRECT_SUBMODULE_CONFIG); + + expect(randomStub.called).to.be.false; + expect(getCryptoRandomValuesStub.calledOnce).to.be.true; + }); + }); + }); + + describe('decode()', () => { + it('should not transform value', () => { + const value = 'test value'; + + expect(yandexIdSubmodule.decode(value).yandexId).to.equal(value); + }); + }); +}); diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js index 06e94ed3919..b2a8d550e84 100644 --- a/test/spec/modules/yieldmoBidAdapter_spec.js +++ b/test/spec/modules/yieldmoBidAdapter_spec.js @@ -261,7 +261,11 @@ describe('YieldmoAdapter', function () { vendorData: {blerp: 1}, gdprApplies: true, }; - const data = buildAndGetData([mockBannerBid()], 0, mockBidderRequest({gdprConsent})); + const data = buildAndGetData( + [mockBannerBid()], + 0, + mockBidderRequest({ gdprConsent }) + ); expect(data.userConsent).equal( JSON.stringify({ gdprApplies: true, @@ -637,6 +641,45 @@ describe('YieldmoAdapter', function () { expect(buildAndGetData([mockVideoBid({ortb2Imp})]).imp[0].ext.gpid).to.be.equal(ortb2Imp.ext.data.pbadslot); }); + it('should pass consent in video bid along with eids', () => { + const params = { + userIdAsEids: [ + { + source: 'pubcid.org', + uids: [ + { + id: 'fake_pubcid', + atype: 1, + }, + ], + }, + ], + fakeUserIdAsEids: [ + { + source: 'pubcid.org', + uids: [ + { + id: 'fake_pubcid', + atype: 1, + }, + ], + }, + ], + }; + let videoBidder = mockBidderRequest( + { + gdprConsent: { + gdprApplies: 1, + consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', + }, + }, + [mockVideoBid()] + ); + let payload = buildAndGetData([mockVideoBid({...params})], 0, videoBidder); + expect(payload.user.ext.consent).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); + expect(payload.user.ext.eids).to.eql(params.fakeUserIdAsEids); + }); + it('should add eids to the video bid request', function () { const params = { userIdAsEids: [{ @@ -656,7 +699,7 @@ describe('YieldmoAdapter', function () { }] }] }; - expect(buildAndGetData([mockVideoBid({...params})]).user.eids).to.eql(params.fakeUserIdAsEids); + expect(buildAndGetData([mockVideoBid({...params})]).user.ext.eids).to.eql(params.fakeUserIdAsEids); }); it('should add topics to the bid request', function () { diff --git a/test/spec/modules/yieldoneBidAdapter_spec.js b/test/spec/modules/yieldoneBidAdapter_spec.js index a10247411db..4664f77216d 100644 --- a/test/spec/modules/yieldoneBidAdapter_spec.js +++ b/test/spec/modules/yieldoneBidAdapter_spec.js @@ -34,9 +34,9 @@ describe('yieldoneBidAdapter', function() { }); it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); + let invalidBid = Object.assign({}, bid); + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); diff --git a/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js b/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js index 4331060b1cd..7abfc7dcc10 100644 --- a/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +++ b/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js @@ -412,6 +412,7 @@ describe('Zeta Global SSP Analytics Adapter', function () { domain: 'test-zeta-ssp.net:63342', page: 'http://test-zeta-ssp.net:63342/zeta-ssp/ssp/_dev/examples/page_banner.html', bids: [{ + adUnitCode: '/19968336/header-bid-tag-0', bidId: '206be9a13236af', auctionId: '75e394d9', bidder: 'zeta_global_ssp', @@ -426,6 +427,7 @@ describe('Zeta Global SSP Analytics Adapter', function () { domain: 'test-zeta-ssp.net:63342', page: 'http://test-zeta-ssp.net:63342/zeta-ssp/ssp/_dev/examples/page_banner.html', bids: [{ + adUnitCode: '/19968336/header-bid-tag-0', bidId: '41badc0e164c758', auctionId: '75e394d9', bidder: 'appnexus', @@ -437,6 +439,7 @@ describe('Zeta Global SSP Analytics Adapter', function () { }] }], bidsReceived: [{ + adUnitCode: '/19968336/header-bid-tag-0', adId: '5759bb3ef7be1e8', requestId: '206be9a13236af', creativeId: '456456456', @@ -459,6 +462,7 @@ describe('Zeta Global SSP Analytics Adapter', function () { expect(auctionSucceeded.domain).to.eql('test-zeta-ssp.net'); expect(auctionSucceeded.page).to.eql('test-zeta-ssp.net/zeta-ssp/ssp/_dev/examples/page_banner.html'); expect(auctionSucceeded.bid).to.be.deep.equal({ + adUnitCode: '/19968336/header-bid-tag-0', adId: '5759bb3ef7be1e8', requestId: '206be9a13236af', auctionId: '75e394d9', diff --git a/test/spec/modules/zeta_global_sspBidAdapter_spec.js b/test/spec/modules/zeta_global_sspBidAdapter_spec.js index f6079f08460..a903c91ec18 100644 --- a/test/spec/modules/zeta_global_sspBidAdapter_spec.js +++ b/test/spec/modules/zeta_global_sspBidAdapter_spec.js @@ -132,6 +132,9 @@ describe('Zeta Ssp Bid Adapter', function () { userIdAsEids: eids, timeout: 500, ortb2: { + site: { + inventorypartnerdomain: 'disqus.com' + }, device: { sua: { mobile: 1, @@ -155,7 +158,17 @@ describe('Zeta Ssp Bid Adapter', function () { { id: '59' } ] } - ] + ], + geo: { + lat: 40.0, + lon: -80.0, + type: 2, + country: 'USA', + region: 'NY', + metro: '501', + city: 'New York', + zip: '10001', + } } } }]; @@ -658,12 +671,37 @@ describe('Zeta Ssp Bid Adapter', function () { expect(payload.device.sua.platform.brand).to.eql('Chrome'); expect(payload.device.sua.platform.version[0]).to.eql('102'); + // expecting the same values for user.geo and device.geo + expect(payload.device.geo.type).to.eql(2); + expect(payload.device.geo.lat).to.eql(40.0); + expect(payload.device.geo.lon).to.eql(-80.0); + expect(payload.device.geo.country).to.eql('USA'); + expect(payload.device.geo.region).to.eql('NY'); + expect(payload.device.geo.metro).to.eql('501'); + expect(payload.device.geo.city).to.eql('New York'); + expect(payload.device.geo.zip).to.eql('10001'); + expect(payload.device.ua).to.not.be.undefined; expect(payload.device.language).to.not.be.undefined; expect(payload.device.w).to.not.be.undefined; expect(payload.device.h).to.not.be.undefined; }); + it('Test provide user params', function () { + const request = spec.buildRequests(bannerRequest, bannerRequest[0]); + const payload = JSON.parse(request.data); + + // expecting the same values for user.geo and device.geo + expect(payload.user.geo.type).to.eql(2); + expect(payload.user.geo.lat).to.eql(40.0); + expect(payload.user.geo.lon).to.eql(-80.0); + expect(payload.user.geo.country).to.eql('USA'); + expect(payload.user.geo.region).to.eql('NY'); + expect(payload.user.geo.metro).to.eql('501'); + expect(payload.user.geo.city).to.eql('New York'); + expect(payload.user.geo.zip).to.eql('10001'); + }); + it('Test that all empties are removed', function () { const request = spec.buildRequests(bannerRequest, bannerRequest[0]); const payload = JSON.parse(request.data); @@ -674,4 +712,12 @@ describe('Zeta Ssp Bid Adapter', function () { expect(payload.ext.tags.nullTag).to.be.undefined; expect(payload.ext.tags.complexEmptyTag).to.be.undefined; }); + + it('Test that site payload param are merged from ortb2 and params', function () { + const request = spec.buildRequests(bannerRequest, bannerRequest[0]); + const payload = JSON.parse(request.data); + + expect(payload.site.page).to.eql('zetaglobal.com/page'); + expect(payload.site.inventorypartnerdomain).to.eql('disqus.com'); + }); }); diff --git a/test/spec/ortbConverter/converter_spec.js b/test/spec/ortbConverter/converter_spec.js index e00b46e66da..fd2dec6d6bb 100644 --- a/test/spec/ortbConverter/converter_spec.js +++ b/test/spec/ortbConverter/converter_spec.js @@ -80,6 +80,7 @@ describe('pbjs-ortb converter', () => { if (context.reqContext?.ctx) { bidResponse.reqCtx = context.reqContext?.ctx; } + bidResponse.seatbid = context.seatbid; } } }, @@ -116,13 +117,16 @@ describe('pbjs-ortb converter', () => { const response = cvt.fromORTB({request, response: MOCK_ORTB_RESPONSE}); expect(response.bids).to.eql([{ impid: 'imp0', - bidId: 111 + bidId: 111, + seatbid: MOCK_ORTB_RESPONSE.seatbid[0] }, { impid: 'imp1', - bidId: 112 + bidId: 112, + seatbid: MOCK_ORTB_RESPONSE.seatbid[0] }, { impid: 'imp1', - bidId: 112 + bidId: 112, + seatbid: MOCK_ORTB_RESPONSE.seatbid[1] }]); expect(response.marker).to.be.true; }); diff --git a/test/spec/ortbConverter/gdpr_spec.js b/test/spec/ortbConverter/gdpr_spec.js index 78fd1830438..65be8c5ebbe 100644 --- a/test/spec/ortbConverter/gdpr_spec.js +++ b/test/spec/ortbConverter/gdpr_spec.js @@ -1,4 +1,4 @@ -import {setOrtbAdditionalConsent} from '../../../modules/consentManagement.js'; +import {setOrtbAdditionalConsent} from '../../../modules/consentManagementTcf.js'; describe('pbjs -> ortb addtlConsent', () => { it('sets ConsentedProvidersSettings', () => { diff --git a/test/spec/ortbConverter/pbsExtensions/aliases_spec.js b/test/spec/ortbConverter/pbsExtensions/aliases_spec.js index 712ceaa397c..6b5bf0371cc 100644 --- a/test/spec/ortbConverter/pbsExtensions/aliases_spec.js +++ b/test/spec/ortbConverter/pbsExtensions/aliases_spec.js @@ -1,4 +1,5 @@ import {setRequestExtPrebidAliases} from '../../../../libraries/pbsExtensions/processors/aliases.js'; +import {config} from 'src/config.js'; describe('PBS - ortb ext.prebid.aliases', () => { let aliasRegistry, bidderRegistry; @@ -17,7 +18,11 @@ describe('PBS - ortb ext.prebid.aliases', () => { beforeEach(() => { aliasRegistry = {}; bidderRegistry = {}; - }) + config.resetConfig(); + }); + afterEach(() => { + config.resetConfig(); + }); describe('has no effect if', () => { it('bidder is not an alias', () => { @@ -37,13 +42,16 @@ describe('PBS - ortb ext.prebid.aliases', () => { }); }); - it('sets ext.prebid.aliases.BIDDER', () => { + function initAlias(spec = {}) { aliasRegistry['alias'] = 'bidder'; bidderRegistry['alias'] = { getSpec() { - return {} + return spec } }; + } + it('sets ext.prebid.aliases.BIDDER', () => { + initAlias(); expect(setAliases({bidderCode: 'alias'})).to.eql({ ext: { prebid: { @@ -54,4 +62,62 @@ describe('PBS - ortb ext.prebid.aliases', () => { } }) }); + + it('sets ext.prebid.aliasgvlids.BIDDER if set on spec', () => { + initAlias({ gvlid: 24 }); + expect(setAliases({ bidderCode: 'alias' })).to.eql({ + ext: { + prebid: { + aliases: { + alias: 'bidder' + }, + aliasgvlids: { + alias: 24 + } + } + } + }) + }); + + it('sets ext.prebid.aliasgvlids.BIDDER if set on config', () => { + config.setConfig({ + gvlMapping: { + alias: 24 + } + }); + initAlias(); + expect(setAliases({ bidderCode: 'alias' })).to.eql({ + ext: { + prebid: { + aliases: { + alias: 'bidder' + }, + aliasgvlids: { + alias: 24 + } + } + } + }) + }); + + it('prefers ext.prebid.aliasgvlids.BIDDER set on config over spec', () => { + config.setConfig({ + gvlMapping: { + alias: 888 + } + }); + initAlias({ gvlid: 24 }); + expect(setAliases({ bidderCode: 'alias' })).to.eql({ + ext: { + prebid: { + aliases: { + alias: 'bidder' + }, + aliasgvlids: { + alias: 888 + } + } + } + }) + }); }) diff --git a/test/spec/ortbConverter/pbsExtensions/params_spec.js b/test/spec/ortbConverter/pbsExtensions/params_spec.js index 73b92a0755d..d1b36c18b49 100644 --- a/test/spec/ortbConverter/pbsExtensions/params_spec.js +++ b/test/spec/ortbConverter/pbsExtensions/params_spec.js @@ -34,63 +34,5 @@ describe('pbjs -> ortb bid params to imp[].ext.prebid.BIDDER', () => { it('has no effect if bidRequest has no params', () => { expect(setParams({bidder: 'mockBidder'})).to.eql({}); - }) - - describe('when adapter provides transformBidParams', () => { - let transform, bidderRequest; - beforeEach(() => { - bidderRequest = {bidderCode: 'mockBidder'}; - transform = sinon.stub().callsFake((p) => Object.assign({transformed: true}, p)); - bidderRegistry.mockBidder = { - getSpec() { - return { - transformBidParams: transform - } - } - } - }) - - it('runs params through transform', () => { - expect(setParams({bidder: 'mockBidder', params: {a: 'param'}}, {bidderRequest})).to.eql({ - ext: { - prebid: { - bidder: { - mockBidder: { - a: 'param', - transformed: true - } - } - } - } - }); - }); - - it('runs through transform even if bid has no params', () => { - expect(setParams({bidder: 'mockBidder'}, {bidderRequest})).to.eql({ - ext: { - prebid: { - bidder: { - mockBidder: { - transformed: true - } - } - } - } - }) - }) - - it('by default, passes adUnit from index, bidderRequest from context', () => { - const params = {a: 'param'}; - setParams({bidder: 'mockBidder', params}, {bidderRequest}); - sinon.assert.calledWith(transform, params, true, adUnit, [bidderRequest]) - }); - - it('uses provided adUnit, bidderRequests', () => { - const adUnit = {code: 'other-ad-unit'}; - const bidderRequests = [{bidderCode: 'one'}, {bidderCode: 'two'}]; - const params = {a: 'param'}; - setParams({bidder: 'mockBidder', params}, {}, {adUnit, bidderRequests}); - sinon.assert.calledWith(transform, params, true, adUnit, bidderRequests); - }) }); }); diff --git a/test/spec/ortbConverter/video_spec.js b/test/spec/ortbConverter/video_spec.js index 8ac6d8b4d08..ab4034bb60a 100644 --- a/test/spec/ortbConverter/video_spec.js +++ b/test/spec/ortbConverter/video_spec.js @@ -30,7 +30,6 @@ describe('pbjs -> ortb video conversion', () => { h: 2, mimes: ['video/mp4'], skip: 1, - placement: 1, }, }, }, diff --git a/test/spec/schainSerializer/schainSerializer_spec.js b/test/spec/schainSerializer/schainSerializer_spec.js new file mode 100644 index 00000000000..d04e6de9847 --- /dev/null +++ b/test/spec/schainSerializer/schainSerializer_spec.js @@ -0,0 +1,138 @@ +import {serializeSupplyChain} from '../../../libraries/schainSerializer/schainSerializer.js' +describe('serializeSupplyChain', () => { + describe('Single Hop - Chain Complete', () => { + it('should serialize a single hop chain with complete information', () => { + const schain = { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234', + hp: 1, + rid: 'bid-request-1', + name: 'publisher', + domain: 'publisher.com' + } + ] + }; + const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; + const expectedResult = '1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com'; + expect(serializeSupplyChain(schain, nodesProperties)).to.equal(expectedResult); + }); + }); + + describe('Single Hop - Chain Complete, optional fields missing', () => { + it('should serialize a single hop chain with missing optional fields', () => { + const schain = { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234', + hp: 1 + } + ] + }; + const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; + const expectedResult = '1.0,1!exchange1.com,1234,1,,,'; + expect(serializeSupplyChain(schain, nodesProperties)).to.equal(expectedResult); + }); + }); + + describe('Multiple Hops - With all properties supplied', () => { + it('should serialize multiple hops with all properties supplied', () => { + const schain = { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234', + hp: 1, + rid: 'bid-request-1', + name: 'publisher', + domain: 'publisher.com' + }, + { + asi: 'exchange2.com', + sid: 'abcd', + hp: 1, + rid: 'bid-request-2', + name: 'intermediary', + domain: 'intermediary.com' + } + ] + }; + const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; + const expectedResult = '1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com!exchange2.com,abcd,1,bid-request-2,intermediary,intermediary.com'; + expect(serializeSupplyChain(schain, nodesProperties)).to.equal(expectedResult); + }); + }); + + describe('Multiple Hops - Chain Complete, optional fields missing', () => { + it('should serialize multiple hops with missing optional fields', () => { + const schain = { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234', + hp: 1 + }, + { + asi: 'exchange2.com', + sid: 'abcd', + hp: 1 + } + ] + }; + const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; + const expectedResult = '1.0,1!exchange1.com,1234,1,,,!exchange2.com,abcd,1,,,'; + expect(serializeSupplyChain(schain, nodesProperties)).to.equal(expectedResult); + }); + }); + + describe('Multiple Hops Expected - Chain Incomplete', () => { + it('should serialize multiple hops with chain incomplete', () => { + const schain = { + ver: '1.0', + complete: 0, + nodes: [ + { + asi: 'exchange2.com', + sid: 'abcd', + hp: 1 + } + ] + }; + const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; + const expectedResult = '1.0,0!exchange2.com,abcd,1,,,'; + expect(serializeSupplyChain(schain, nodesProperties)).to.equal(expectedResult); + }); + }); + + describe('Single Hop - Chain Complete, encoded values', () => { + it('should serialize a single hop chain with encoded values', () => { + const schain = { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234!abcd', + hp: 1, + rid: 'bid-request-1', + name: 'publisher, Inc.', + domain: 'publisher.com' + } + ] + }; + const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; + const expectedResult = '1.0,1!exchange1.com,1234%21abcd,1,bid-request-1,publisher%2C%20Inc.,publisher.com'; + expect(serializeSupplyChain(schain, nodesProperties)).to.equal(expectedResult); + }); + }); +}); diff --git a/test/spec/unit/core/ajax_spec.js b/test/spec/unit/core/ajax_spec.js index dd03ad1a761..8140123d9fc 100644 --- a/test/spec/unit/core/ajax_spec.js +++ b/test/spec/unit/core/ajax_spec.js @@ -405,24 +405,22 @@ describe('attachCallbacks', () => { }).forEach(([cbType, makeResponse]) => { it(`do not choke ${cbType} callbacks`, () => { const {response} = makeResponse(); - return new Promise((resolve) => { - const result = {success: false, error: false}; - attachCallbacks(Promise.resolve(response), { - success() { - result.success = true; - throw new Error(); - }, - error() { - result.error = true; - throw new Error(); - } + const result = {success: false, error: false}; + return attachCallbacks(Promise.resolve(response), { + success() { + result.success = true; + throw new Error(); + }, + error() { + result.error = true; + throw new Error(); + } + }).catch(() => null) + .then(() => { + Object.entries(result).forEach(([typ, ran]) => { + expect(ran).to.be[typ === cbType ? 'true' : 'false']; + }); }); - setTimeout(() => resolve(result), 20); - }).then(result => { - Object.entries(result).forEach(([typ, ran]) => { - expect(ran).to.be[typ === cbType ? 'true' : 'false'] - }) - }); }); }); }); diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index ef6d1de0b30..56668759db6 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -1510,39 +1510,29 @@ describe('bidderFactory', () => { paapiStub = sinon.stub(); }); - const PAAPI_PROPS = ['fledgeAuctionConfigs', 'paapi']; - - it(`should not accept both ${PAAPI_PROPS.join(' and ')}`, () => { - expect(() => { - runBidder(Object.fromEntries(PAAPI_PROPS.map(prop => [prop, [paapiConfig]]))) - }).to.throw(); - }) + describe(`when response has paapi`, () => { + it('should call paapi config hook with auction configs', function () { + runBidder({ + bids: bids, + paapi: [paapiConfig] + }); + expect(paapiStub.calledOnce).to.equal(true); + sinon.assert.calledWith(paapiStub, bidRequest.bids[0], paapiConfig); + sinon.assert.calledWith(addBidResponseStub, 'mock/placement', sinon.match(bids[0])); + }); - PAAPI_PROPS.forEach(paapiProp => { - describe(`using ${paapiProp}`, () => { - it('should call paapi config hook with auction configs', function() { + Object.entries({ + 'missing': undefined, + 'an empty array': [] + }).forEach(([t, bids]) => { + it(`should call paapi config hook with PAAPI configs even when bids is ${t}`, function () { runBidder({ - bids: bids, - [paapiProp]: [paapiConfig] - }) - expect(paapiStub.calledOnce).to.equal(true); - sinon.assert.calledWith(paapiStub, bidRequest.bids[0], paapiConfig); - sinon.assert.calledWith(addBidResponseStub, 'mock/placement', sinon.match(bids[0])); - }) - - Object.entries({ - 'missing': undefined, - 'an empty array': [] - }).forEach(([t, bids]) => { - it(`should call paapi config hook with PAAPI configs even when bids is ${t}`, function() { - runBidder({ - bids, - [paapiProp]: [paapiConfig] - }) - expect(paapiStub.calledOnce).to.be.true; - sinon.assert.calledWith(paapiStub, bidRequest.bids[0], paapiConfig); - expect(addBidResponseStub.calledOnce).to.equal(false); + bids, + paapi: [paapiConfig] }); + expect(paapiStub.calledOnce).to.be.true; + sinon.assert.calledWith(paapiStub, bidRequest.bids[0], paapiConfig); + expect(addBidResponseStub.calledOnce).to.equal(false); }); }); }); diff --git a/test/spec/unit/core/storageManager_spec.js b/test/spec/unit/core/storageManager_spec.js index edead126c2c..25471a80677 100644 --- a/test/spec/unit/core/storageManager_spec.js +++ b/test/spec/unit/core/storageManager_spec.js @@ -26,15 +26,15 @@ describe('storage manager', function() { hook.ready(); }); - beforeEach(function() { + beforeEach(function () { resetData(); }); - afterEach(function() { + afterEach(function () { config.resetConfig(); }) - it('should allow to set cookie for core modules without checking gdpr enforcements', function() { + it('should allow to set cookie for core modules without checking gdpr enforcements', function () { const coreStorage = getCoreStorageManager(); let date = new Date(); date.setTime(date.getTime() + (24 * 60 * 60 * 1000)); @@ -43,7 +43,7 @@ describe('storage manager', function() { expect(coreStorage.getCookie('hello')).to.equal('world'); }); - it('should add done callbacks to storageCallbacks array', function() { + it('should add done callbacks to storageCallbacks array', function () { let noop = sinon.spy(); const coreStorage = newStorageManager(); @@ -55,11 +55,15 @@ describe('storage manager', function() { coreStorage.getDataFromLocalStorage('foo', noop); coreStorage.removeDataFromLocalStorage('foo', noop); coreStorage.hasLocalStorage(noop); + coreStorage.setDataInSessionStorage('foo', 'bar', noop); + coreStorage.getDataFromSessionStorage('foo', noop); + coreStorage.removeDataFromSessionStorage('foo', noop); + coreStorage.hasSessionStorage(noop); - expect(storageCallbacks.length).to.equal(8); + expect(storageCallbacks.length).to.equal(12); }); - it('should allow bidder to access device if gdpr enforcement module is not included', function() { + it('should allow bidder to access device if gdpr enforcement module is not included', function () { let deviceAccessSpy = sinon.spy(utils, 'hasDeviceAccess'); const storage = newStorageManager(); storage.setCookie('foo1', 'baz1'); @@ -87,12 +91,16 @@ describe('storage manager', function() { })); }); - it('should deny access if activity is denied', () => { - isAllowed.returns(false); - const mgr = mkManager(MODULE_TYPE_PREBID, 'mockMod'); - mgr.setDataInLocalStorage('testKey', 'val'); - expect(mgr.getDataFromLocalStorage('testKey')).to.not.exist; - }); + ['Local', 'Session'].forEach(type => { + describe(`${type} storage`, () => { + it('should deny access if activity is denied', () => { + isAllowed.returns(false); + const mgr = mkManager(MODULE_TYPE_PREBID, 'mockMod'); + mgr[`setDataIn${type}Storage`]('testKey', 'val'); + expect(mgr[`getDataFrom${type}Storage`]('testKey')).to.not.exist; + }); + }) + }) it('should use bidder aliases when possible', () => { adapterManager.registerBidAdapter({callBids: sinon.stub(), getSpec: () => ({})}, 'mockBidder'); @@ -103,57 +111,66 @@ describe('storage manager', function() { [ACTIVITY_PARAM_COMPONENT_NAME]: 'mockAlias' })) }) - }) - - describe('localstorage forbidden access in 3rd-party context', function() { - let errorLogSpy; - let originalLocalStorage; - const localStorageMock = { get: () => { throw Error } }; + }); - beforeEach(function() { - originalLocalStorage = window.localStorage; - Object.defineProperty(window, 'localStorage', localStorageMock); - errorLogSpy = sinon.spy(utils, 'logError'); - }); + ['localStorage', 'sessionStorage'].forEach(storage => { + const Storage = storage.charAt(0).toUpperCase() + storage.substring(1); - afterEach(function() { - Object.defineProperty(window, 'localStorage', { get: () => originalLocalStorage }); - errorLogSpy.restore(); - }) + describe(`${storage} forbidden access in 3rd-party context`, function () { + let errorLogSpy; + let originalStorage; + const storageMock = { + get: () => { + throw Error + } + }; - it('should not throw if the localstorage is not accessible when setting/getting/removing from localstorage', function() { - const coreStorage = newStorageManager(); + beforeEach(function () { + originalStorage = window[storage]; + Object.defineProperty(window, storage, storageMock); + errorLogSpy = sinon.spy(utils, 'logError'); + }); - coreStorage.setDataInLocalStorage('key', 'value'); - const val = coreStorage.getDataFromLocalStorage('key'); - coreStorage.removeDataFromLocalStorage('key'); + afterEach(function () { + Object.defineProperty(window, storage, {get: () => originalStorage}); + errorLogSpy.restore(); + }) - expect(val).to.be.null; - sinon.assert.calledThrice(errorLogSpy); - }) - }) + it('should not throw if storage is not accessible when setting/getting/removing', function () { + const coreStorage = newStorageManager(); - describe('localstorage is enabled', function() { - let localStorage; + coreStorage[`setDataIn${Storage}`]('key', 'value'); + const val = coreStorage[`getDataFrom${Storage}`]('key'); + coreStorage[`removeDataFrom${Storage}`]('key'); - beforeEach(function() { - localStorage = window.localStorage; - localStorage.clear(); + expect(val).to.be.null; + sinon.assert.calledThrice(errorLogSpy); + }); }); + }); - afterEach(function() { - localStorage.clear(); - }) + ['localStorage', 'sessionStorage'].forEach(storage => { + describe(`${storage} is enabled`, function () { + let store; + beforeEach(function () { + store = window[storage]; + store.clear(); + }); - it('should remove side-effect after checking', function () { - const storage = newStorageManager(); + afterEach(function () { + store.clear(); + }) - localStorage.setItem('unrelated', 'dummy'); - const val = storage.localStorageIsEnabled(); + it('should remove side-effect after checking', function () { + const storageMgr = newStorageManager(); - expect(val).to.be.true; - expect(localStorage.length).to.be.eq(1); - expect(localStorage.getItem('unrelated')).to.be.eq('dummy'); + store.setItem('unrelated', 'dummy'); + const val = storageMgr[`${storage}IsEnabled`](); + + expect(val).to.be.true; + expect(store.length).to.be.eq(1); + expect(store.getItem('unrelated')).to.be.eq('dummy'); + }); }); }); diff --git a/test/spec/unit/core/targeting_spec.js b/test/spec/unit/core/targeting_spec.js index 54ea942e373..f6cfeededd3 100644 --- a/test/spec/unit/core/targeting_spec.js +++ b/test/spec/unit/core/targeting_spec.js @@ -1,5 +1,6 @@ import {expect} from 'chai'; import { + getGPTSlotsForAdUnits, filters, getHighestCpmBidsFromBidPool, sortByDealAndPriceBucketOrCpm, @@ -1310,6 +1311,17 @@ describe('targeting tests', function () { describe('setTargetingForAst', function () { let sandbox, apnTagStub; + + before(() => { + if (window.apntag?.setKeywords == null) { + const orig = window.apntag; + window.apntag = {setKeywords: () => {}} + after(() => { + window.apntag = orig; + }) + } + }); + beforeEach(function() { sandbox = sinon.createSandbox(); sandbox.stub(targetingInstance, 'resetPresetTargetingAST'); @@ -1346,4 +1358,62 @@ describe('targeting tests', function () { expect(apnTagStub.getCall(1).args[1]).to.deep.equal({HB_BIDDER: 'appnexus'}); }); }); + + describe('getGPTSlotsForAdUnits', () => { + function mockSlot(path, elId) { + return { + getAdUnitPath() { + return path; + }, + getSlotElementId() { + return elId; + } + } + } + + let slots; + + beforeEach(() => { + slots = [ + mockSlot('slot/1', 'div-1'), + mockSlot('slot/2', 'div-2'), + ] + }); + + Object.entries({ + 'ad unit path': ['slot/1', 'slot/2'], + 'element id': ['div-1', 'div-2'] + }).forEach(([t, adUnitCodes]) => { + it(`can find slots by ${t}`, () => { + expect(getGPTSlotsForAdUnits(adUnitCodes, null, () => slots)).to.eql(Object.fromEntries(adUnitCodes.map((au, i) => [au, [slots[i]]]))); + }) + }); + + it('returns empty list on no match', () => { + expect(getGPTSlotsForAdUnits(['missing', 'slot/2'], null, () => slots)).to.eql({ + missing: [], + 'slot/2': [slots[1]] + }); + }); + + it('can use customSlotMatching', () => { + const csm = (slot) => { + if (slot.getAdUnitPath() === 'slot/1') { + return (au) => { + return au === 'custom' + } + } + } + expect(getGPTSlotsForAdUnits(['div-2', 'custom'], csm, () => slots)).to.eql({ + 'custom': [slots[0]], + 'div-2': [slots[1]] + }) + }); + + it('can handle repeated adUnitCodes', () => { + expect(getGPTSlotsForAdUnits(['div-1', 'div-1'], null, () => slots)).to.eql({ + 'div-1': [slots[0]] + }) + }) + }) }); diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 94643f34a05..de267b793b2 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -1,33 +1,32 @@ import { + createBidReceived, getAdServerTargeting, + getAdUnits, getBidRequests, getBidResponses, getBidResponsesFromAPI, getTargetingKeys, - getTargetingKeysBidLandscape, - getAdUnits, - createBidReceived + getTargetingKeysBidLandscape } from 'test/fixtures/fixtures.js'; -import { auctionManager, newAuctionManager } from 'src/auctionManager.js'; -import { targeting, newTargeting, filters } from 'src/targeting.js'; -import { config as configObj } from 'src/config.js'; +import {auctionManager, newAuctionManager} from 'src/auctionManager.js'; +import {filters, newTargeting, targeting} from 'src/targeting.js'; +import {config as configObj} from 'src/config.js'; import * as ajaxLib from 'src/ajax.js'; import * as auctionModule from 'src/auction.js'; -import { registerBidder } from 'src/adapters/bidderFactory.js'; -import {resizeRemoteCreative} from 'src/secureCreatives.js'; +import {resetAuctionState} from 'src/auction.js'; +import {registerBidder} from 'src/adapters/bidderFactory.js'; import {find} from 'src/polyfill.js'; import * as pbjsModule from 'src/prebid.js'; +import $$PREBID_GLOBAL$$ from 'src/prebid.js'; import {hook} from '../../../src/hook.js'; import {reset as resetDebugging} from '../../../src/debugging.js'; -import $$PREBID_GLOBAL$$ from 'src/prebid.js'; -import {resetAuctionState} from 'src/auction.js'; import {stubAuctionIndex} from '../../helpers/indexStub.js'; import {createBid} from '../../../src/bidfactory.js'; import {enrichFPD} from '../../../src/fpd/enrichment.js'; import {mockFpdEnrichments} from '../../helpers/fpd.js'; import {generateUUID} from '../../../src/utils.js'; import {getCreativeRenderer} from '../../../src/creativeRenderers.js'; -import { BID_STATUS, EVENTS, GRANULARITY_OPTIONS, TARGETING_KEYS } from 'src/constants.js'; +import {BID_STATUS, EVENTS, GRANULARITY_OPTIONS, PB_LOCATOR, TARGETING_KEYS} from 'src/constants.js'; import {getBidToRender} from '../../../src/adRendering.js'; var assert = require('chai').assert; @@ -237,6 +236,11 @@ describe('Unit: Prebid Module', function () { getBidToRender.getHooks({hook: getBidToRenderHook}).remove(); }); + it('should insert a locator frame on the page', () => { + $$PREBID_GLOBAL$$.processQueue(); + expect(window.frames[PB_LOCATOR]).to.exist; + }) + describe('and global adUnits', () => { const startingAdUnits = [ { @@ -2503,6 +2507,52 @@ describe('Unit: Prebid Module', function () { } }); + if (FEATURES.NATIVE) { + Object.entries({ + missing: {}, + negative: {id: -1}, + 'not an integer': {id: 1.23}, + NaN: {id: 'garbage'} + }).forEach(([t, props]) => { + it(`should reject native ortb when asset ID is ${t}`, () => { + const adUnit = { + code: 'au', + mediaTypes: { + native: { + ortb: { + assets: [props] + } + } + }, + bids: [{bidder: 'appnexus'}] + }; + $$PREBID_GLOBAL$$.requestBids({ + adUnits: [adUnit] + }); + expect(auctionArgs.adUnits[0].bids.length).to.equal(0); + }); + }); + + ['sendTargetingKeys', 'types'].forEach(key => { + it(`should reject native that includes both ortb and ${key}`, () => { + const adUnit = { + code: 'au', + mediaTypes: { + native: { + ortb: {}, + [key]: {} + } + }, + bids: [{bidder: 'appnexus'}] + }; + $$PREBID_GLOBAL$$.requestBids({ + adUnits: [adUnit] + }); + expect(auctionArgs.adUnits[0].bids.length).to.equal(0); + }) + }); + } + it('should throw error message and remove adUnit if adUnit.bids is not defined correctly', function () { const adUnits = [{ code: 'ad-unit-1', @@ -3707,4 +3757,15 @@ describe('Unit: Prebid Module', function () { sinon.assert.calledOnce(adapterManager.callBidBillableBidder); }); }); + + describe('clearAllAuctions', () => { + after(() => { + resetAuction(); + }); + it('clears auction data', function () { + expect(auctionManager.getBidsReceived().length).to.not.equal(0); + $$PREBID_GLOBAL$$.clearAllAuctions(); + expect(auctionManager.getBidsReceived().length).to.equal(0); + }); + }); }); diff --git a/test/spec/unit/utils/focusTimeout_spec.js b/test/spec/unit/utils/focusTimeout_spec.js new file mode 100644 index 00000000000..ed7b1c0c2f3 --- /dev/null +++ b/test/spec/unit/utils/focusTimeout_spec.js @@ -0,0 +1,60 @@ +import setFocusTimeout from '../../../../src/utils/focusTimeout'; + +export const setDocumentHidden = (hidden) => { + Object.defineProperty(document, 'hidden', { + configurable: true, + get: () => hidden, + }); + document.dispatchEvent(new Event('visibilitychange')); +}; + +describe('focusTimeout', () => { + let clock; + + beforeEach(() => { + clock = sinon.useFakeTimers(); + }); + + afterEach(() => { + clock.restore(); + }) + + it('should invoke callback when page is visible', () => { + let callback = sinon.stub(); + setFocusTimeout(callback, 2000); + clock.tick(2000); + expect(callback.called).to.be.true; + }); + + it('should not invoke callback if page was hidden', () => { + let callback = sinon.stub(); + setFocusTimeout(callback, 2000); + setDocumentHidden(true); + clock.tick(3000); + expect(callback.called).to.be.false; + }); + + it('should defer callback execution when page is hidden', () => { + let callback = sinon.stub(); + setFocusTimeout(callback, 4000); + clock.tick(2000); + setDocumentHidden(true); + clock.tick(2000); + setDocumentHidden(false); + expect(callback.called).to.be.false; + clock.tick(2000); + expect(callback.called).to.be.true; + }); + + it('should return updated timerId after page was showed again', () => { + let callback = sinon.stub(); + const getCurrentTimerId = setFocusTimeout(callback, 4000); + const oldTimerId = getCurrentTimerId(); + clock.tick(2000); + setDocumentHidden(true); + clock.tick(2000); + setDocumentHidden(false); + const newTimerId = getCurrentTimerId(); + expect(oldTimerId).to.not.equal(newTimerId); + }); +}); diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js index d7d7007674a..a6df236ee46 100644 --- a/test/spec/utils_spec.js +++ b/test/spec/utils_spec.js @@ -1170,6 +1170,44 @@ describe('Utils', function () { }); }); + describe('getUnixTimestampFromNow', () => { + it('correctly obtains unix timestamp', () => { + const nowValue = new Date('2024-01-01').valueOf(); + sinon.stub(Date, 'now').returns(nowValue); + let val = utils.getUnixTimestampFromNow(); + expect(val).equal(nowValue); + + val = utils.getUnixTimestampFromNow(1); + expect(val).equal(nowValue + (1000 * 60 * 60 * 24)); + + val = utils.getUnixTimestampFromNow(1, 'd'); + expect(val).equal(nowValue + (1000 * 60 * 60 * 24)); + + val = utils.getUnixTimestampFromNow(1, 'm'); + expect(val).equal(nowValue + (1000 * 60 * 60 * 24 / 1440)); + + val = utils.getUnixTimestampFromNow(2, 'm'); + expect(val).equal(nowValue + (1000 * 60 * 60 * 24 * 2 / 1440)); + + // any value that isn't 'm' or 'd' gets treated as Date.now(); + val = utils.getUnixTimestampFromNow(10, 'o'); + expect(val).equal(nowValue); + }); + }); + + describe('convertObjectToArray', () => { + it('correctly converts object to array', () => { + const obj = {key: 1, anotherKey: 'fred', third: ['fred'], fourth: {sub: {obj: 'test'}}}; + const array = utils.convertObjectToArray(obj); + + expect(JSON.stringify(array[0])).equal(JSON.stringify({'key': 1})) + expect(JSON.stringify(array[1])).equal(JSON.stringify({'anotherKey': 'fred'})) + expect(JSON.stringify(array[2])).equal(JSON.stringify({'third': ['fred']})) + expect(JSON.stringify(array[3])).equal(JSON.stringify({'fourth': {sub: {obj: 'test'}}})); + expect(array.length).to.equal(4); + }); + }); + describe('setScriptAttributes', () => { it('correctly adds attributes from an object', () => { const script = document.createElement('script'), @@ -1185,6 +1223,25 @@ describe('Utils', function () { expect(script.id).to.equal('newId'); }); }); + + describe('safeJSONParse', () => { + it('correctly encodes valid input', () => { + const jsonObj = { + key1: 'val1', + key2: { + key3: 100, + key4: true + } + }; + const result = utils.safeJSONEncode(jsonObj); + expect(result).to.equal(`{"key1":"val1","key2":{"key3":100,"key4":true}}`); + }); + it('return empty string for stringify errors', () => { + const jsonObj = {k: 2n}; + const result = utils.safeJSONEncode(jsonObj); + expect(result).to.equal(''); + }); + }); }); describe('memoize', () => { diff --git a/test/spec/videoCache_spec.js b/test/spec/videoCache_spec.js index fc6e71779cb..7d07da9de90 100644 --- a/test/spec/videoCache_spec.js +++ b/test/spec/videoCache_spec.js @@ -1,39 +1,13 @@ import chai from 'chai'; -import {getCacheUrl, store} from 'src/videoCache.js'; +import {batchingCache, getCacheUrl, store, _internal, storeBatch} from 'src/videoCache.js'; import {config} from 'src/config.js'; import {server} from 'test/mocks/xhr.js'; import {auctionManager} from '../../src/auctionManager.js'; import {AuctionIndex} from '../../src/auctionIndex.js'; -import {batchingCache} from '../../src/auction.js'; +import * as utils from 'src/utils.js'; const should = chai.should(); -function getMockBid(bidder, auctionId, bidderRequestId) { - return { - 'bidder': bidder, - 'params': { - 'placementId': '10433394', - 'member': 123, - 'keywords': { - 'foo': ['bar', 'baz'], - 'fizz': ['buzz'] - } - }, - 'bid_id': '12345abc', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c', - 'sizes': [300, 250], - 'bidId': '123', - 'bidderRequestId': bidderRequestId, - 'auctionId': auctionId - }; -} - describe('The video cache', function () { function assertError(callbackSpy) { callbackSpy.calledOnce.should.equal(true); @@ -126,9 +100,7 @@ describe('The video cache', function () { prebid.org wrapper - - - + \n \n `; @@ -335,34 +307,36 @@ describe('The video cache', function () { JSON.parse(request.requestBody).should.deep.equal(payload); }); - it('should wait the duration of the batchTimeout and pass the correct batchSize if batched requests are enabled in the config', () => { - const mockAfterBidAdded = function() {}; - let callback = null; - let mockTimeout = sinon.stub().callsFake((cb) => { callback = cb }); + if (FEATURES.VIDEO) { + it('should wait the duration of the batchTimeout and pass the correct batchSize if batched requests are enabled in the config', () => { + const mockAfterBidAdded = function() {}; + let callback = null; + let mockTimeout = sinon.stub().callsFake((cb) => { callback = cb }); - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache', - batchSize: 3, - batchTimeout: 20 - } - }); + config.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache', + batchSize: 3, + batchTimeout: 20 + } + }); - let stubCache = sinon.stub(); - const batchAndStore = batchingCache(mockTimeout, stubCache); - for (let i = 0; i < 3; i++) { - batchAndStore({}, {}, mockAfterBidAdded); - } + let stubCache = sinon.stub(); + const batchAndStore = batchingCache(mockTimeout, stubCache); + for (let i = 0; i < 3; i++) { + batchAndStore({}, {}, mockAfterBidAdded); + } - sinon.assert.calledOnce(mockTimeout); - sinon.assert.calledWith(mockTimeout, sinon.match.any, 20); + sinon.assert.calledOnce(mockTimeout); + sinon.assert.calledWith(mockTimeout, sinon.match.any, 20); - const expectedBatch = [{ afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }, { afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }, { afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }]; + const expectedBatch = [{ afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }, { afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }, { afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }]; - callback(); + callback(); - sinon.assert.calledWith(stubCache, expectedBatch); - }); + sinon.assert.calledWith(stubCache, expectedBatch); + }); + } function assertRequestMade(bid, expectedValue) { store([bid], function () { }); @@ -393,6 +367,35 @@ describe('The video cache', function () { return callback; } }); + + describe('storeBatch', () => { + let sandbox; + let err, cacheIds + beforeEach(() => { + err = null; + cacheIds = []; + sandbox = sinon.createSandbox(); + sandbox.stub(utils, 'logError'); + sandbox.stub(_internal, 'store').callsFake((_, cb) => cb(err, cacheIds)); + }); + afterEach(() => { + sandbox.restore(); + }) + it('should log an error when store replies with an error', () => { + err = new Error('err'); + storeBatch([]); + sinon.assert.called(utils.logError); + }); + it('should not process returned uuids if they do not match the batch size', () => { + const el = {auctionInstance: {}, bidResponse: {}, afterBidAdded: sinon.stub()} + const batch = [el, el]; + cacheIds = [{uuid: 'mock-id'}] + storeBatch(batch); + expect(el.bidResponse.videoCacheKey).to.not.exist; + sinon.assert.notCalled(batch[0].afterBidAdded); + sinon.assert.called(utils.logError); + }) + }) }); describe('The getCache function', function () { diff --git a/test/test_deps.js b/test/test_deps.js index c8a3bcc9426..3f0f766b457 100644 --- a/test/test_deps.js +++ b/test/test_deps.js @@ -19,3 +19,4 @@ require('test/helpers/prebidGlobal.js'); require('test/mocks/adloaderStub.js'); require('test/mocks/xhr.js'); require('test/mocks/analyticsStub.js'); +require('test/mocks/ortbConverter.js') diff --git a/webpack.conf.js b/webpack.conf.js index 1035e985b22..5b0d864045e 100644 --- a/webpack.conf.js +++ b/webpack.conf.js @@ -126,7 +126,6 @@ module.exports = { }) ); const core = path.resolve('./src'); - const paapiMod = path.resolve('./modules/paapi.js'); return Object.assign(libraries, { core: { @@ -135,16 +134,6 @@ module.exports = { return module.resource && module.resource.startsWith(core); } }, - paapi: { - // fledgeForGpt imports paapi to keep backwards compat for NPM consumers - // this makes the paapi module its own chunk, pulled in by both paapi and fledgeForGpt entry points, - // to avoid duplication - // TODO: remove this in prebid 9 - name: 'chunk-paapi', - test: (module) => { - return module.resource === paapiMod; - } - } }, { default: false, defaultVendors: false