From 88666d6747a83ca112c102ba6fe1bc53a45aaecb Mon Sep 17 00:00:00 2001 From: John Hooks Date: Sun, 17 Dec 2023 05:12:44 -0800 Subject: [PATCH] fix: testing configuration (#11) * fix: project organization - Add Codeception for PHP testing - Add Docker testing environment - Add lint-staged - Add copy of WP_HTML_Tag_Processor, modify for use of indexing content. - Add stemmers from tntsearch - Add schema.md * ci: disable code-standards More work needs to be done before enabling this workflow. For now linting should be performed precommit, using lint-staged. --- .distignore | 43 + .env.example | 36 + .eslintignore | 3 + .eslintrc.json | 5 +- .github/actions/install/action.yml | 39 + .github/workflows/coding-standards.yml | 40 + .github/workflows/test-suite.yml | 56 + .gitignore | 9 + .husky/pre-commit | 4 + .php-cs-fixer.dist.php | 6 +- .prettierignore | 6 + .prettierrc.js => .prettierrc.cjs | 0 .stylelintignore | 13 + .wp-env.json | 4 - LICENSE.md | 2 +- README.md | 51 +- bin/dump-acceptance-db.sh | 3 + bin/init-pipeline.sh | 3 + bin/local-down.sh | 3 + bin/local-up.sh | 4 + bin/local-wp-shell.sh | 3 + bin/test-build.sh | 3 + bin/test-down.sh | 3 + bin/test-run.sh | 3 + bin/test-up.sh | 6 + bin/wait-for-it.sh | 17 + bin/wp-install.sh | 9 + block.json | 12 - client/src/block.json | 10 + client/src/editor.js | 1 + client/src/search.ts | 6 +- codeception.dist.yml | 28 + composer.json | 94 +- composer.lock | 6811 ++++++++++++----- config/development/Dockerfile | 31 + .../usr/local/etc/php/conf.d/xdebug.ini | 15 + docker-compose.yml | 75 + docs/architecture.md | 14 + docs/schema.md | 78 + index.php | 6 + indexed-search.php | 77 + jest.config.cjs | 14 + jest.config.js | 24 - lint-staged.config.js | 17 + package-lock.json | 3798 ++++----- package.json | 81 +- phpcs.xml | 36 +- phpstan.neon => phpstan.neon.dist | 15 +- phpunit.xml | 31 - readme.txt | 8 +- search.php | 39 - server/src/enqueue.php | 9 - server/src/modal.php | 5 - server/src/rest.php | 68 - server/src/variation.php | 168 - src/Compat/WP_HTML_Tag_Processor.php | 2594 +++++++ src/Contracts/EngineContract.php | 46 + src/Contracts/Runnable.php | 13 + src/Exceptions/IndexNotFoundException.php | 5 + src/Exceptions/IndexedSearchException.php | 7 + src/Exceptions/TokenizationException.php | 5 + src/Helpers/Str.php | 40 + src/Index/IndexRepository.php | 8 + src/Stemmer/ArabicStemmer.php | 180 + src/Stemmer/CroatianStemmer.php | 340 + src/Stemmer/FrenchStemmer.php | 720 ++ src/Stemmer/GermanStemmer.php | 258 + src/Stemmer/ItalianStemmer.php | 463 ++ src/Stemmer/LatvianStemmer.php | 212 + src/Stemmer/NoStemmer.php | 11 + src/Stemmer/PolishStemmer.php | 163 + src/Stemmer/PorterStemmer.php | 403 + src/Stemmer/PortugeseStemmer.php | 766 ++ src/Stemmer/RussianStemmer.php | 112 + src/Stemmer/Stemmer.php | 8 + src/Stemmer/UkrainianStemmer.php | 113 + src/Stopwords/croatian.json | 182 + src/Stopwords/english.json | 187 + src/Stopwords/french.json | 159 + src/Stopwords/german.json | 234 + src/Stopwords/italian.json | 281 + src/Stopwords/latvian.json | 165 + src/Stopwords/russian.json | 153 + src/Stopwords/spanish.json | 315 + src/Stopwords/ukrainian.json | 1279 ++++ src/Support/TokenInterface.php | 14 + src/Support/TokenizerInterface.php | 16 + src/Tokenizer/HtmlTokenizer.php | 90 + src/Tokenizer/Token.php | 34 + src/Tokenizer/Tokenizer.php | 23 + src/enqueue.php | 10 + src/modal.php | 7 + src/rest.php | 70 + src/variation.php | 169 + tests/.env.example | 39 + tests/_data/.gitignore | 2 + tests/_output/.gitignore | 2 + tests/_support/AcceptanceTester.php | 30 + tests/_support/Data/.gitkeep | 0 tests/_support/EndToEndTester.php | 30 + tests/_support/_generated/.gitignore | 2 + tests/acceptance.suite.yml | 27 + tests/acceptance/ActivationCest.php | 27 + tests/acceptance/_bootstrap.php | 18 + tests/docker-compose.yml | 71 + tests/unit.suite.yml | 4 + tests/unit/Tokenizer/TokenizerTest.php | 22 + tests/unit/_bootstrap.php | 4 + tsconfig.eslint.json | 5 +- tsconfig.json | 3 +- webpack.config.cjs | 10 - 111 files changed, 17426 insertions(+), 4670 deletions(-) create mode 100644 .distignore create mode 100644 .env.example create mode 100644 .github/actions/install/action.yml create mode 100644 .github/workflows/coding-standards.yml create mode 100644 .github/workflows/test-suite.yml create mode 100755 .husky/pre-commit rename .prettierrc.js => .prettierrc.cjs (100%) create mode 100644 .stylelintignore delete mode 100644 .wp-env.json create mode 100755 bin/dump-acceptance-db.sh create mode 100755 bin/init-pipeline.sh create mode 100755 bin/local-down.sh create mode 100755 bin/local-up.sh create mode 100755 bin/local-wp-shell.sh create mode 100755 bin/test-build.sh create mode 100755 bin/test-down.sh create mode 100755 bin/test-run.sh create mode 100755 bin/test-up.sh create mode 100755 bin/wait-for-it.sh create mode 100755 bin/wp-install.sh delete mode 100644 block.json create mode 100644 client/src/block.json create mode 100644 client/src/editor.js create mode 100644 codeception.dist.yml create mode 100644 config/development/Dockerfile create mode 100644 config/development/files-to-copy/usr/local/etc/php/conf.d/xdebug.ini create mode 100644 docker-compose.yml create mode 100644 docs/architecture.md create mode 100644 docs/schema.md create mode 100644 index.php create mode 100644 indexed-search.php create mode 100644 jest.config.cjs delete mode 100644 jest.config.js create mode 100644 lint-staged.config.js rename phpstan.neon => phpstan.neon.dist (58%) delete mode 100644 phpunit.xml delete mode 100644 search.php delete mode 100644 server/src/enqueue.php delete mode 100644 server/src/modal.php delete mode 100644 server/src/rest.php delete mode 100644 server/src/variation.php create mode 100644 src/Compat/WP_HTML_Tag_Processor.php create mode 100644 src/Contracts/EngineContract.php create mode 100644 src/Contracts/Runnable.php create mode 100644 src/Exceptions/IndexNotFoundException.php create mode 100644 src/Exceptions/IndexedSearchException.php create mode 100644 src/Exceptions/TokenizationException.php create mode 100644 src/Helpers/Str.php create mode 100644 src/Index/IndexRepository.php create mode 100644 src/Stemmer/ArabicStemmer.php create mode 100644 src/Stemmer/CroatianStemmer.php create mode 100644 src/Stemmer/FrenchStemmer.php create mode 100644 src/Stemmer/GermanStemmer.php create mode 100644 src/Stemmer/ItalianStemmer.php create mode 100644 src/Stemmer/LatvianStemmer.php create mode 100644 src/Stemmer/NoStemmer.php create mode 100644 src/Stemmer/PolishStemmer.php create mode 100644 src/Stemmer/PorterStemmer.php create mode 100644 src/Stemmer/PortugeseStemmer.php create mode 100644 src/Stemmer/RussianStemmer.php create mode 100644 src/Stemmer/Stemmer.php create mode 100644 src/Stemmer/UkrainianStemmer.php create mode 100644 src/Stopwords/croatian.json create mode 100644 src/Stopwords/english.json create mode 100644 src/Stopwords/french.json create mode 100644 src/Stopwords/german.json create mode 100644 src/Stopwords/italian.json create mode 100644 src/Stopwords/latvian.json create mode 100644 src/Stopwords/russian.json create mode 100644 src/Stopwords/spanish.json create mode 100644 src/Stopwords/ukrainian.json create mode 100644 src/Support/TokenInterface.php create mode 100644 src/Support/TokenizerInterface.php create mode 100644 src/Tokenizer/HtmlTokenizer.php create mode 100644 src/Tokenizer/Token.php create mode 100644 src/Tokenizer/Tokenizer.php create mode 100644 src/enqueue.php create mode 100644 src/modal.php create mode 100644 src/rest.php create mode 100644 src/variation.php create mode 100644 tests/.env.example create mode 100644 tests/_data/.gitignore create mode 100644 tests/_output/.gitignore create mode 100644 tests/_support/AcceptanceTester.php create mode 100644 tests/_support/Data/.gitkeep create mode 100644 tests/_support/EndToEndTester.php create mode 100644 tests/_support/_generated/.gitignore create mode 100644 tests/acceptance.suite.yml create mode 100644 tests/acceptance/ActivationCest.php create mode 100644 tests/acceptance/_bootstrap.php create mode 100644 tests/docker-compose.yml create mode 100644 tests/unit.suite.yml create mode 100644 tests/unit/Tokenizer/TokenizerTest.php create mode 100644 tests/unit/_bootstrap.php diff --git a/.distignore b/.distignore new file mode 100644 index 0000000..1091565 --- /dev/null +++ b/.distignore @@ -0,0 +1,43 @@ +.git +.github +.idea +.husky +.vscode +bin +client +tests +node_modules +vendor +.composer +.distignore +.editorconfig +.env +.env.example +.eslintignore +.eslintrc.json +.gitattributes +.gitignore +.npmrc +.nvmrc +.php-cs-fixer.cache +.php-cs-fixer.php +.php-cs-fixer.dist.php +.prettierignore +.prettierrc.js +.stylelintignore +babel.config.cjs +codeception.yml +codeception.dist.yml +composer.json +composer.lock +jest.config.cjs +package-lock.json +package.json +phpcs.xml +phpstan.neon +phpstan.neon.dist +README.md +tsconfig.eslint.json +tsconfig.json +webpack.config.cjs +$GITHUB_WORKSPACE diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9ef6a09 --- /dev/null +++ b/.env.example @@ -0,0 +1,36 @@ +# The path to the WordPress root directory, the one containing the wp-load.php file. +# This can be a relative path from the directory that contains the codeception.yml file, +# or an absolute path. +WORDPRESS_ROOT_FOLDER="/var/www/html" + +# The port on which the WordPress installation is served. +WORDPRESS_LOCALHOST_PORT=3389 + +# The URL and domain of the WordPress site used in end-to-end tests. +WORDPRESS_URL="http://localhost:3389" +WORDPRESS_DOMAIN=localhost:3389 + +# Tests will require a MySQL database to run. +# The database will be created if it does not exist. +# Do not use a database that contains important data! +WORDPRESS_DB_DSN="mysql:host=database;port=3306;dbname=wordpress" +WORDPRESS_DB_HOST=database:3306 +WORDPRESS_DB_NAME=wordpress +WORDPRESS_DB_USER=wordpress +WORDPRESS_DB_PASSWORD=wordpress +WORDPRESS_DB_URL=mysql://wordpress:wordpress@database:3306/wordpress +WORDPRESS_DB_LOCALHOST_PORT=3391 + +# The Integration suite will use this table prefix for the WordPress tables. +TEST_TABLE_PREFIX=test_ + +# This table prefix used by the WordPress site in end-to-end tests. +WORDPRESS_TABLE_PREFIX=wp_ + +# The username and password of the administrator user of the WordPress site used in end-to-end tests. +WORDPRESS_ADMIN_USER=admin +WORDPRESS_ADMIN_PASSWORD=password + +WORDPRESS_ADMIN_PATH="/wp-admin" + +WORDPRESS_XDEBUG=true diff --git a/.eslintignore b/.eslintignore index abc5277..810c81b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,3 +4,6 @@ build-module build-types coverage vendor +vendor-prod + +tests/_wordpress diff --git a/.eslintrc.json b/.eslintrc.json index c29b0ed..e53c69c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,8 +1,7 @@ { "parser": "@typescript-eslint/parser", "parserOptions": { - "project": true, - "tsconfigRootDir": "." + "project": ["./tsconfig.json", "./tsconfig.eslint.json"] }, "extends": ["plugin:@wordpress/eslint-plugin/recommended"], "rules": { @@ -48,7 +47,7 @@ "import/resolver": { "typescript": { "alwaysTryTypes": true, - "project": ["./tsconfig.eslint.json"] + "project": ["./tsconfig.json", "./tsconfig.eslint.json"] } } }, diff --git a/.github/actions/install/action.yml b/.github/actions/install/action.yml new file mode 100644 index 0000000..faefd03 --- /dev/null +++ b/.github/actions/install/action.yml @@ -0,0 +1,39 @@ +name: Install dependencies +description: Setup Node.js, Composer, and install dependencies + +runs: + using: "composite" + steps: + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: | + vendor + vendor-prod + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + + - name: Composer install + uses: php-actions/composer@v6 + with: + php_version: "8.2" + version: 2.x + dev: yes + args: --optimize-autoloader --ignore-platform-reqs + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version-file: .nvmrc + cache: npm + cache-dependency-path: package-lock.json + + - name: NPM install + shell: bash + run: npm ci --ignore-scripts + + - name: Build NPM dependencies + shell: bash + run: npm rebuild && npm run prepare --if-present diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml new file mode 100644 index 0000000..04205b4 --- /dev/null +++ b/.github/workflows/coding-standards.yml @@ -0,0 +1,40 @@ +name: Coding Standards + +on: + # pull_request: + # branches: [main, epic/*] + workflow_dispatch: + +jobs: + lint: + name: Check Coding Standards + runs-on: ubuntu-latest + environment: testing + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install dependenices + uses: ./.github/actions/install + + - name: Generate testing files + shell: bash + run: | + envsubst < tests/.env.example > tests/.env + php vendor/bin/codecept build + + - name: Lint PHP + shell: bash + run: | + composer run-script lint + composer run-script analyze + + - name: Lint JavaScript + shell: bash + run: | + npm run lint:js + npm run check + + - name: Lint Styles + shell: bash + run: npm run lint:css diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml new file mode 100644 index 0000000..d25c795 --- /dev/null +++ b/.github/workflows/test-suite.yml @@ -0,0 +1,56 @@ +name: Test Suite + +on: + pull_request: + branches: [main, epic/*] + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + test: ["unit", "acceptance"] + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install dependenices + uses: ./.github/actions/install + + - name: Setup environment + shell: bash + run: envsubst < tests/.env.example > tests/.env + + - name: Cache Docker images. + uses: ScribeMD/docker-cache@0.3.6 + with: + key: docker-${{ runner.os }}-${{ hashFiles('docker-compose.yml') }} + + - name: Build testing files + shell: bash + run: php vendor/bin/codecept build + + - name: Setup docker + shell: bash + run: sudo bin/test-up.sh + + - name: Run unit tests + if: matrix.test != 'acceptance' + run: bin/test-run.sh ${{ matrix.test }} + + - name: Run acceptance tests + if: matrix.test == 'acceptance' + run: php vendor/bin/codecept run acceptance + + - name: Upload codeception output + if: ${{ failure() }} + uses: actions/upload-artifact@v2.2.1 + with: + name: "${{ matrix.test }}-output" + path: "./tests/_output" + + - name: Stop testing container + shell: bash + run: bin/test-down.sh diff --git a/.gitignore b/.gitignore index c04108c..385fcad 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ artifacts # Dependency directories node_modules/ vendor/ +vendor-prod/ # Optional npm cache directory .npm @@ -36,7 +37,15 @@ vendor/ .idea .vscode +# Local config files +.php-cs-fixer.php +codeception.yml +phpstan.neon + # Cache files .phpunit.cache .phpunit.result.cache .php-cs-fixer.cache + +# Testing artifacts +tests/_wordpress diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..d24fdfc --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx lint-staged diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index cebe18f..a59c133 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -9,9 +9,11 @@ // allows using the latest version of the rules. $finder = Finder::create() + ->notPath(['WP_HTML_Tag_Processor.php']) + ->exclude(['vendor', 'vendor-prod', '_support/_generated', '_wordpress']) ->in([ - __DIR__ . '/server/src', - __DIR__ . '/server/tests', + __DIR__ . '/src', + __DIR__ . '/tests', ]) ->name('*.php') ->ignoreDotFiles(true) diff --git a/.prettierignore b/.prettierignore index 6745600..9bce50d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,5 +4,11 @@ build-module build-types coverage vendor +vendor-prod + +composer.lock +package-lock.json **/*.md + +tests/_wordpress diff --git a/.prettierrc.js b/.prettierrc.cjs similarity index 100% rename from .prettierrc.js rename to .prettierrc.cjs diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 0000000..5b408c5 --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,13 @@ +.cache +build +build-module +build-types + +tests +coverage + +vendor +vendor-prod +node_modules + +tests/_wordpress diff --git a/.wp-env.json b/.wp-env.json deleted file mode 100644 index 42168e4..0000000 --- a/.wp-env.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "core": "WordPress/WordPress", - "plugins": ["."] -} diff --git a/LICENSE.md b/LICENSE.md index ebfd939..1fd2637 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -WP-Blocks Search, a WordPress plugin. +Indexed Search, a WordPress plugin. Copyright (C) 2023 The Contributors This program is free software: you can redistribute it and/or modify diff --git a/README.md b/README.md index d1aa40a..e20cf76 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,50 @@ -# Search +# Indexed Search -An advanced WordPress search block. +An advanced WordPress indexed search plugin. + +## Description + +A super cool search plugin which uses indexing to make the search of post content speedy! + +## Development + +### Getting started + +The development environment is setup in a Docker container. + +```sh +# Create a development environment file +cp .env.example .env + +# Command to start the development WordPress instance. +docker-compose up -d +``` + +## Testing + +The development environment is setup in a separate Docker container than development. + +```sh +# Create a testing environment file +cp tests/.env.example tests/.env + +# Command to start the testing WordPress instance. +bin/test-up.sh + +# Command to run Codeception unit tests from inside the container. +bin/test-run.sh unit + +# Command to run Codeception acceptance tests from outside the container. +vendor/bin/codecept run acceptance +``` + +### Testing database + +The testing container does not persist volumes. If a local database dump exists, it will be loaded when initializing the database container. + +Use the following command to create a local database dump. + +```sh +# Command to dump the testing database to tests/_data/dump.sql +bin/dump-acceptance-db.sh +``` diff --git a/bin/dump-acceptance-db.sh b/bin/dump-acceptance-db.sh new file mode 100755 index 0000000..576d3fa --- /dev/null +++ b/bin/dump-acceptance-db.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker compose --file tests/docker-compose.yml --env-file tests/.env exec database /usr/bin/mysqldump -uwordpress -pwordpress wordpress > tests/_data/dump.sql diff --git a/bin/init-pipeline.sh b/bin/init-pipeline.sh new file mode 100755 index 0000000..f2f0e28 --- /dev/null +++ b/bin/init-pipeline.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./bin/test-up.sh diff --git a/bin/local-down.sh b/bin/local-down.sh new file mode 100755 index 0000000..2bff485 --- /dev/null +++ b/bin/local-down.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker compose --file docker-compose.yml --env-file .env down diff --git a/bin/local-up.sh b/bin/local-up.sh new file mode 100755 index 0000000..4381e23 --- /dev/null +++ b/bin/local-up.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +docker compose --file docker-compose.yml --env-file .env up --wait +docker compose --file docker-compose.yml --env-file .env exec -T wordpress chown www-data:www-data wp-content wp-content/plugins diff --git a/bin/local-wp-shell.sh b/bin/local-wp-shell.sh new file mode 100755 index 0000000..652f377 --- /dev/null +++ b/bin/local-wp-shell.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker compose --file docker-compose.yml --env-file .env exec -w /var/www/html/wp-content/plugins/indexed-search wordpress bash -c "vendor/bin/wp --allow-root shell" diff --git a/bin/test-build.sh b/bin/test-build.sh new file mode 100755 index 0000000..1fdd8f2 --- /dev/null +++ b/bin/test-build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker compose --file tests/docker-compose.yml --env-file tests/.env exec -T -w /var/www/html/wp-content/plugins/indexed-search wordpress ./vendor/bin/codecept build diff --git a/bin/test-down.sh b/bin/test-down.sh new file mode 100755 index 0000000..2b643dd --- /dev/null +++ b/bin/test-down.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker compose --file tests/docker-compose.yml --env-file tests/.env down diff --git a/bin/test-run.sh b/bin/test-run.sh new file mode 100755 index 0000000..1c8c909 --- /dev/null +++ b/bin/test-run.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +docker compose --file tests/docker-compose.yml --env-file tests/.env exec -T -w /var/www/html/wp-content/plugins/indexed-search wordpress ./vendor/bin/codecept run "$1" diff --git a/bin/test-up.sh b/bin/test-up.sh new file mode 100755 index 0000000..c1305f1 --- /dev/null +++ b/bin/test-up.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +docker compose --file tests/docker-compose.yml --env-file tests/.env up -d +./bin/wait-for-it.sh http://localhost:5389 +docker compose --file tests/docker-compose.yml --env-file tests/.env exec -T wordpress chown www-data:www-data wp-content wp-content/plugins +docker compose --file tests/docker-compose.yml --env-file tests/.env exec -T -w /var/www/html/wp-content/plugins/indexed-search wordpress bash bin/wp-install.sh diff --git a/bin/wait-for-it.sh b/bin/wait-for-it.sh new file mode 100755 index 0000000..3072f0d --- /dev/null +++ b/bin/wait-for-it.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +attempt_counter=0 +max_attempts=30 + +until curl --output /dev/null --silent --fail "$1"; do + if [ ${attempt_counter} -eq ${max_attempts} ];then + echo "Max attempts reached" + exit 1 + fi + + printf '.' + attempt_counter=$(($attempt_counter+1)) + sleep 1 +done + +echo "Connected to host" diff --git a/bin/wp-install.sh b/bin/wp-install.sh new file mode 100755 index 0000000..7aa8d44 --- /dev/null +++ b/bin/wp-install.sh @@ -0,0 +1,9 @@ +vendor/bin/wp --allow-root core install \ + --url=$WORDPRESS_URL \ + --title="Test Site 01" \ + --admin_user=$WORDPRESS_ADMIN_USER \ + --admin_password=$WORDPRESS_ADMIN_PASSWORD \ + --admin_email="admin@gmail.com" \ + --skip-email + +vendor/bin/wp --allow-root plugin activate indexed-search diff --git a/block.json b/block.json deleted file mode 100644 index 2652abe..0000000 --- a/block.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "apiVersion": 2, - "name": "wp-blocks/search", - "title": "search", - "description": "An advanced search block", - "keywords": ["block", "search"], - "category": "media", - "editorScript": "file:./build/search.js", - "editorStyle": "file:./build/search.css", - "viewScript": "file:./build/frontend.js", - "style": "file:./build/style-search.css" -} diff --git a/client/src/block.json b/client/src/block.json new file mode 100644 index 0000000..a72a25a --- /dev/null +++ b/client/src/block.json @@ -0,0 +1,10 @@ +{ + "apiVersion": 2, + "name": "wp-blocks/indexed-search", + "title": "search", + "description": "An advanced search block", + "keywords": ["block", "search"], + "category": "media", + "editorScript": "file:./editor.js", + "viewScript": "file:./frontend.js" +} diff --git a/client/src/editor.js b/client/src/editor.js new file mode 100644 index 0000000..45632e2 --- /dev/null +++ b/client/src/editor.js @@ -0,0 +1 @@ +import './style/style.scss'; diff --git a/client/src/search.ts b/client/src/search.ts index b18b5ad..a573f1a 100644 --- a/client/src/search.ts +++ b/client/src/search.ts @@ -7,11 +7,11 @@ import { debounce, hideSpinner, liveSearch, showSpinner } from './utils'; * The `initLiveSearch` function initializes a live search functionality for a search input element in * a React TypeScript application. * - * @param searchBlock - The `searchBlock` parameter is the HTML element that contains the search input + * @param searchBlock The `searchBlock` parameter is the HTML element that contains the search input * field and the search results. It is the parent element that holds all the elements related to the * search functionality. */ -export function initLiveSearch(searchBlock) { +export function initLiveSearch(searchBlock: Element) { let searchResultsWrapper: HTMLElement; let isWrapperFocused = false; let hasResultsWrapper = false; @@ -22,7 +22,7 @@ export function initLiveSearch(searchBlock) { /** * The function appends a search results wrapper to a search input element and returns the wrapper. * - * @param {HTMLInputElement} input - The input parameter is an HTMLInputElement, which represents an + * @param {HTMLInputElement} input The input parameter is an HTMLInputElement, which represents an * input element in an HTML form. * @return the searchResultsWrapper, which is a newly created div element with the class * 'search-results'. diff --git a/codeception.dist.yml b/codeception.dist.yml new file mode 100644 index 0000000..4f6896b --- /dev/null +++ b/codeception.dist.yml @@ -0,0 +1,28 @@ +namespace: Tests +support_namespace: Support +paths: + tests: tests + data: tests/_data + output: tests/_output + log: tests/_output + support: tests/_support + envs: tests/_envs +actor_suffix: Tester +settings: + colors: true + memory_limit: 1024M +params: + - tests/.env +extensions: + enabled: + - "Codeception\\Extension\\RunFailed" + commands: + - "lucatume\\WPBrowser\\Command\\RunOriginal" + - "lucatume\\WPBrowser\\Command\\RunAll" + - "lucatume\\WPBrowser\\Command\\GenerateWPUnit" + - "lucatume\\WPBrowser\\Command\\DbExport" + - "lucatume\\WPBrowser\\Command\\DbImport" + - "lucatume\\WPBrowser\\Command\\DevStart" + - "lucatume\\WPBrowser\\Command\\DevStop" + - "lucatume\\WPBrowser\\Command\\DevInfo" + - "lucatume\\WPBrowser\\Command\\DevRestart" diff --git a/composer.json b/composer.json index 6e7504e..e0cfa1c 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "wp-blocks/search", - "description": "An advanced WordPress search block", + "name": "wp-blocks/indexed-search", + "description": "An advanced WordPress indexed search plugin", "type": "project", "license": "GPL-2-or-later", "authors": [ @@ -15,30 +15,34 @@ ], "minimum-stability": "stable", "require": { - "psr/container": "^2.0", - "stellarwp/validation": "^1.4", - "stellarwp/container-contract": "^1.0", - "psr/log": "^1.0", - "symfony/http-foundation": "^5.4", - "fakerphp/faker": "^1.23" + "php": "^7.4 | ^8.0", + "pimple/pimple": "^3.5" }, "require-dev": { + "ext-pdo": "*", + "ext-sqlite3": "*", + "brianhenryie/strauss": "^0.14.1", + "codeception/codeception": "^5.0", + "codeception/module-asserts": "^3.0", + "codeception/module-phpbrowser": "^3.0", + "codeception/module-webdriver": "^3.0", + "codeception/module-db": "^3.0", + "codeception/module-filesystem": "^3.0", + "codeception/module-cli": "^2.0", "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "friendsofphp/php-cs-fixer": "^3.38", + "lucatume/wp-browser": "^4.0", "php-stubs/wordpress-tests-stubs": "^6.3", - "php-stubs/wp-cli-stubs": "^2.8", - "phpcompatibility/php-compatibility": "^9.3", + "php-stubs/wp-cli-stubs": "^2.9", "phpcompatibility/phpcompatibility-wp": "*", "phpstan/extension-installer": "^1.3", "phpstan/phpstan": "^1.10", - "phpstan/phpstan-phpunit": "^1.3", "phpunit/phpunit": "^9.6", - "squizlabs/php_codesniffer": "^3.5", + "squizlabs/php_codesniffer": "^3.7", "szepeviktor/phpstan-wordpress": "^1.3", "wordpress/wordpress": "dev-trunk", - "wp-cli/wp-cli-bundle": "^2.5", - "wp-coding-standards/wpcs": "^3.0", - "yoast/phpunit-polyfills": "^1.1.0" + "wp-cli/wp-cli-bundle": "^2.9", + "wp-coding-standards/wpcs": "^3.0" }, "repositories": [ { @@ -49,7 +53,65 @@ "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true, - "phpstan/extension-installer": true + "phpstan/extension-installer": true, + "webdriver-binary/binary-chromedriver": true + } + }, + "autoload": { + "psr-4": { + "IndexedSearch\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\Support\\": "tests/_support" + } + }, + "scripts": { + "post-install-cmd": [ + "@strauss" + ], + "post-update-cmd": [ + "@strauss" + ], + "strauss": [ + "@php vendor/bin/strauss" + ], + "test:acceptance": [ + "@php vendor/bin/codecept run acceptance" + ], + "analyze": [ + "@php vendor/bin/phpstan analyse --memory-limit=4G --no-progress --no-interaction --ansi" + ], + "lint": [ + "@php vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php --ansi" + ], + "lint:fix": [ + "@php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --ansi" + ] + }, + "scripts-descriptions": { + "strauss": "Copy composer's `require` and prefix their namespace and classnames.", + "test": "Run full test suite.", + "test:analyze": "Run static code analysis.", + "lint:fix": "Fix PHP code formatting." + }, + "extra": { + "strauss": { + "target_directory": "vendor-prod", + "namespace_prefix": "IndexedSearch\\", + "classmap_prefix": "Indexed_Search_", + "constant_prefix": "INDEXED_SEARCH_", + "delete_vendor_files": true, + "packages": [], + "exclude_from_copy": { + "packages": [] + }, + "excluded_from_prefix": { + "file_patterns": [] + }, + "include_modified_date": false, + "include_author": false } } } diff --git a/composer.lock b/composer.lock index 9c345b3..51f7f3e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,53 +4,38 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "36cd0c9829d2a69f1c30072c9fd8c02e", + "content-hash": "85e641c8926c5d053ed5cc42536f4ba1", "packages": [ { - "name": "fakerphp/faker", - "version": "v1.23.0", + "name": "pimple/pimple", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/FakerPHP/Faker.git", - "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01" + "url": "https://github.com/silexphp/Pimple.git", + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", - "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "psr/container": "^1.0 || ^2.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "conflict": { - "fzaninotto/faker": "*" + "php": ">=7.2.5", + "psr/container": "^1.1 || ^2.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "doctrine/persistence": "^1.3 || ^2.0", - "ext-intl": "*", - "phpunit/phpunit": "^9.5.26", - "symfony/phpunit-bridge": "^5.4.16" - }, - "suggest": { - "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", - "ext-curl": "Required by Faker\\Provider\\Image to download images.", - "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", - "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", - "ext-mbstring": "Required for multibyte Unicode string functionality." + "symfony/phpunit-bridge": "^5.4@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "v1.21-dev" + "dev-master": "3.4.x-dev" } }, "autoload": { - "psr-4": { - "Faker\\": "src/Faker/" + "psr-0": { + "Pimple": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -59,20 +44,20 @@ ], "authors": [ { - "name": "François Zaninotto" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" } ], - "description": "Faker is a PHP library that generates fake data for you.", + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "https://pimple.symfony.com", "keywords": [ - "data", - "faker", - "fixtures" + "container", + "dependency injection" ], "support": { - "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.23.0" + "source": "https://github.com/silexphp/Pimple/tree/v3.5.0" }, - "time": "2023-06-12T08:44:38+00:00" + "time": "2021-10-28T11:13:42+00:00" }, { "name": "psr/container", @@ -126,33 +111,43 @@ "source": "https://github.com/php-fig/container/tree/2.0.2" }, "time": "2021-11-05T16:47:00+00:00" - }, + } + ], + "packages-dev": [ { - "name": "psr/log", - "version": "1.1.4", + "name": "behat/gherkin", + "version": "v4.9.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "url": "https://github.com/Behat/Gherkin.git", + "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4", + "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "~7.2|~8.0" + }, + "require-dev": { + "cucumber/cucumber": "dev-gherkin-22.0.0", + "phpunit/phpunit": "~8|~9", + "symfony/yaml": "~3|~4|~5" + }, + "suggest": { + "symfony/yaml": "If you want to parse features, represented in YAML files" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "4.x-dev" } }, "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "psr-0": { + "Behat\\Gherkin": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -161,202 +156,293 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Gherkin DSL parser for PHP", + "homepage": "http://behat.org/", "keywords": [ - "log", - "psr", - "psr-3" + "BDD", + "Behat", + "Cucumber", + "DSL", + "gherkin", + "parser" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "issues": "https://github.com/Behat/Gherkin/issues", + "source": "https://github.com/Behat/Gherkin/tree/v4.9.0" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-10-12T13:05:09+00:00" }, { - "name": "stellarwp/container-contract", - "version": "1.0.4", + "name": "brianhenryie/strauss", + "version": "0.14.1", "source": { "type": "git", - "url": "https://github.com/stellarwp/container-contract.git", - "reference": "37becc9edbecb0ff95556048337600dd9cc888f0" + "url": "https://github.com/BrianHenryIE/strauss.git", + "reference": "82c2b6119e56ea15394fbe9b74e54e76846eb9fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stellarwp/container-contract/zipball/37becc9edbecb0ff95556048337600dd9cc888f0", - "reference": "37becc9edbecb0ff95556048337600dd9cc888f0", + "url": "https://api.github.com/repos/BrianHenryIE/strauss/zipball/82c2b6119e56ea15394fbe9b74e54e76846eb9fc", + "reference": "82c2b6119e56ea15394fbe9b74e54e76846eb9fc", "shasum": "" }, "require": { - "php": ">=7.0.0" + "composer/composer": "*", + "json-mapper/json-mapper": "^2.2", + "league/flysystem": "^1.0", + "symfony/console": "^4|^5|^6", + "symfony/finder": "^4|^5|^6" + }, + "replace": { + "coenjacobs/mozart": "*" + }, + "require-dev": { + "brianhenryie/php-diff-test": "dev-master", + "clue/phar-composer": "^1.2", + "ext-json": "*", + "jaschilz/php-coverage-badger": "^2.0", + "mheap/phpunit-github-actions-printer": "^1.4", + "php": "^7.4|^8.0", + "phpunit/phpunit": "^9|^10", + "squizlabs/php_codesniffer": "^3.5" }, + "bin": [ + "bin/strauss" + ], "type": "library", "autoload": { "psr-4": { - "StellarWP\\ContainerContract\\": "src/" + "BrianHenryIE\\Strauss\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0-or-later" + "MIT" ], "authors": [ { - "name": "StellarWP", - "homepage": "https://stellarwp.com" + "name": "Brian Henry", + "email": "BrianHenryIE@gmail.com" + }, + { + "name": "Coen Jacobs", + "email": "coenjacobs@gmail.com" } ], - "description": "StellarWP Container Interface", - "homepage": "https://github.com/stellarwp/container-contract", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop" - ], + "description": "Composes all dependencies as a package inside a WordPress plugin", "support": { - "issues": "https://github.com/stellarwp/container-contract/issues", - "source": "https://github.com/stellarwp/container-contract/tree/1.0.4" + "issues": "https://github.com/BrianHenryIE/strauss/issues", + "source": "https://github.com/BrianHenryIE/strauss/tree/0.14.1" }, - "time": "2022-12-20T21:29:17+00:00" + "time": "2023-10-31T02:45:37+00:00" }, { - "name": "stellarwp/field-conditions", - "version": "1.1.1", + "name": "codeception/codeception", + "version": "5.0.12", "source": { "type": "git", - "url": "https://github.com/stellarwp/field-conditions.git", - "reference": "03f5aff2f4977359e672efe5426bbb4ef62101cd" + "url": "https://github.com/Codeception/Codeception.git", + "reference": "7f528f5fd8cdcd05cd0a85eb1e24d05df989e0c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stellarwp/field-conditions/zipball/03f5aff2f4977359e672efe5426bbb4ef62101cd", - "reference": "03f5aff2f4977359e672efe5426bbb4ef62101cd", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/7f528f5fd8cdcd05cd0a85eb1e24d05df989e0c4", + "reference": "7f528f5fd8cdcd05cd0a85eb1e24d05df989e0c4", "shasum": "" }, "require": { - "ext-json": "*" + "behat/gherkin": "^4.6.2", + "codeception/lib-asserts": "^2.0", + "codeception/stub": "^4.1", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.0", + "phpunit/php-code-coverage": "^9.2 || ^10.0", + "phpunit/php-text-template": "^2.0 || ^3.0", + "phpunit/php-timer": "^5.0.3 || ^6.0", + "phpunit/phpunit": "^9.5.20 || ^10.0", + "psy/psysh": "^0.11.2", + "sebastian/comparator": "^4.0.5 || ^5.0", + "sebastian/diff": "^4.0.3 || ^5.0", + "symfony/console": ">=4.4.24 <7.0", + "symfony/css-selector": ">=4.4.24 <7.0", + "symfony/event-dispatcher": ">=4.4.24 <7.0", + "symfony/finder": ">=4.4.24 <7.0", + "symfony/var-dumper": ">=4.4.24 < 7.0", + "symfony/yaml": ">=4.4.24 <7.0" + }, + "conflict": { + "codeception/lib-innerbrowser": "<3.1.3", + "codeception/module-filesystem": "<3.0", + "codeception/module-phpbrowser": "<2.5" + }, + "replace": { + "codeception/phpunit-wrapper": "*" }, "require-dev": { - "codeception/module-asserts": "^1.0.0", - "codeception/module-phpbrowser": "^1.0.0", - "lucatume/wp-browser": "^3.0.14", - "phpunit/phpunit": "~6.0" + "codeception/lib-innerbrowser": "*@dev", + "codeception/lib-web": "^1.0", + "codeception/module-asserts": "*@dev", + "codeception/module-cli": "*@dev", + "codeception/module-db": "*@dev", + "codeception/module-filesystem": "*@dev", + "codeception/module-phpbrowser": "*@dev", + "codeception/util-universalframework": "*@dev", + "ext-simplexml": "*", + "jetbrains/phpstorm-attributes": "^1.0", + "symfony/dotenv": ">=4.4.24 <7.0", + "symfony/process": ">=4.4.24 <7.0", + "vlucas/phpdotenv": "^5.1" }, + "suggest": { + "codeception/specify": "BDD-style code blocks", + "codeception/verify": "BDD-style assertions", + "ext-simplexml": "For loading params from XML files", + "stecman/symfony-console-completion": "For BASH autocompletion", + "symfony/dotenv": "For loading params from .env files", + "symfony/phpunit-bridge": "For phpunit-bridge support", + "vlucas/phpdotenv": "For loading params from .env files" + }, + "bin": [ + "codecept" + ], "type": "library", "autoload": { + "files": [ + "functions.php" + ], "psr-4": { - "StellarWP\\FieldConditions\\": "src/" - } + "Codeception\\": "src/Codeception", + "Codeception\\Extension\\": "ext" + }, + "classmap": [ + "src/PHPUnit/TestCase.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0-or-later" + "MIT" ], "authors": [ { - "name": "StellarWP", - "email": "dev@stellarwp.com" - }, - { - "name": "Jason Adams", - "email": "jason.adams@givewp.com" + "name": "Michael Bodnarchuk", + "email": "davert.ua@gmail.com", + "homepage": "https://codeception.com" } ], - "description": "A set of serializable classes for handling conditional logic for fields in PHP", + "description": "BDD-style testing framework", + "homepage": "https://codeception.com/", + "keywords": [ + "BDD", + "TDD", + "acceptance testing", + "functional testing", + "unit testing" + ], "support": { - "issues": "https://github.com/stellarwp/field-conditions/issues", - "source": "https://github.com/stellarwp/field-conditions/tree/1.1.1" + "issues": "https://github.com/Codeception/Codeception/issues", + "source": "https://github.com/Codeception/Codeception/tree/5.0.12" }, - "time": "2023-04-01T00:38:22+00:00" + "funding": [ + { + "url": "https://opencollective.com/codeception", + "type": "open_collective" + } + ], + "time": "2023-10-15T18:04:50+00:00" }, { - "name": "stellarwp/validation", - "version": "1.4.1", + "name": "codeception/lib-asserts", + "version": "2.1.0", "source": { "type": "git", - "url": "https://github.com/stellarwp/validation.git", - "reference": "0f0d0dbc28b9b0780c61f81a6462c467e6d0358f" + "url": "https://github.com/Codeception/lib-asserts.git", + "reference": "b8c7dff552249e560879c682ba44a4b963af91bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stellarwp/validation/zipball/0f0d0dbc28b9b0780c61f81a6462c467e6d0358f", - "reference": "0f0d0dbc28b9b0780c61f81a6462c467e6d0358f", + "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/b8c7dff552249e560879c682ba44a4b963af91bc", + "reference": "b8c7dff552249e560879c682ba44a4b963af91bc", "shasum": "" }, "require": { - "ext-json": "*", - "stellarwp/container-contract": "1.0.4", - "stellarwp/field-conditions": "^1.0" - }, - "require-dev": { - "codeception/module-asserts": "^1.0.0", - "codeception/module-phpbrowser": "^1.0.0", - "lucatume/di52": "^3.0", - "lucatume/wp-browser": "^3.0.14", - "phpunit/phpunit": "~6.0" + "codeception/phpunit-wrapper": "^7.7.1 | ^8.0.3 | ^9.0", + "ext-dom": "*", + "php": "^7.4 | ^8.0" }, "type": "library", "autoload": { - "psr-4": { - "StellarWP\\Validation\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-2.0-or-later" + "MIT" ], "authors": [ { - "name": "StellarWP", - "email": "dev@stellarwp.com" + "name": "Michael Bodnarchuk", + "email": "davert@mail.ua", + "homepage": "http://codegyre.com" }, { - "name": "Jason Adams", - "email": "jason.adams@givewp.com" + "name": "Gintautas Miselis" + }, + { + "name": "Gustavo Nieves", + "homepage": "https://medium.com/@ganieves" } ], - "description": "An end-to-end ready PHP validation library", + "description": "Assertion methods used by Codeception core and Asserts module", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception" + ], "support": { - "issues": "https://github.com/stellarwp/validation/issues", - "source": "https://github.com/stellarwp/validation/tree/1.4.1" + "issues": "https://github.com/Codeception/lib-asserts/issues", + "source": "https://github.com/Codeception/lib-asserts/tree/2.1.0" }, - "time": "2023-08-15T15:24:53+00:00" + "time": "2023-02-10T18:36:23+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "name": "codeception/lib-innerbrowser", + "version": "3.1.3", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "url": "https://github.com/Codeception/lib-innerbrowser.git", + "reference": "10482f7e34c0537bf5b87bc82a3d65a1842a8b4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/Codeception/lib-innerbrowser/zipball/10482f7e34c0537bf5b87bc82a3d65a1842a8b4f", + "reference": "10482f7e34c0537bf5b87bc82a3d65a1842a8b4f", "shasum": "" }, "require": { - "php": ">=8.1" + "codeception/codeception": "^5.0", + "codeception/lib-web": "^1.0.1", + "ext-dom": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.0", + "phpunit/phpunit": "^9.5", + "symfony/browser-kit": "^4.4.24 || ^5.4 || ^6.0", + "symfony/dom-crawler": "^4.4.30 || ^5.4 || ^6.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "require-dev": { + "codeception/util-universalframework": "dev-master" }, + "type": "library", "autoload": { - "files": [ - "function.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -365,74 +451,56 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Michael Bodnarchuk", + "email": "davert@mail.ua", + "homepage": "https://codegyre.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Gintautas Miselis" } ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", + "description": "Parent library for all Codeception framework modules and PhpBrowser", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception" + ], "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "issues": "https://github.com/Codeception/lib-innerbrowser/issues", + "source": "https://github.com/Codeception/lib-innerbrowser/tree/3.1.3" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2022-10-03T15:33:34+00:00" }, { - "name": "symfony/http-foundation", - "version": "v5.4.31", + "name": "codeception/lib-web", + "version": "1.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "f84fd4fd8311a541ceb2ae3f257841d002450a90" + "url": "https://github.com/Codeception/lib-web.git", + "reference": "28cb2ed1169de18e720bec758015aadc37d8344c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f84fd4fd8311a541ceb2ae3f257841d002450a90", - "reference": "f84fd4fd8311a541ceb2ae3f257841d002450a90", + "url": "https://api.github.com/repos/Codeception/lib-web/zipball/28cb2ed1169de18e720bec758015aadc37d8344c", + "reference": "28cb2ed1169de18e720bec758015aadc37d8344c", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.16" + "ext-mbstring": "*", + "guzzlehttp/psr7": "^2.0", + "php": "^8.0", + "symfony/css-selector": ">=4.4.24 <8.0" }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/cache": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^4.4|^5.0|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" + "conflict": { + "codeception/codeception": "<5.0.0-alpha3" }, - "suggest": { - "symfony/mime": "To use the file extension guesser" + "require-dev": { + "php-webdriver/webdriver": "^1.12", + "phpunit/phpunit": "^9.5 | ^10.0" }, "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -441,75 +509,47 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Gintautas Miselis" } ], - "description": "Defines an object-oriented layer for the HTTP specification", - "homepage": "https://symfony.com", + "description": "Library containing files used by module-webdriver and lib-innerbrowser or module-phpbrowser", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception" + ], "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.31" + "issues": "https://github.com/Codeception/lib-web/issues", + "source": "https://github.com/Codeception/lib-web/tree/1.0.4" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-11-06T22:05:57+00:00" + "time": "2023-12-01T11:38:22+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", + "name": "codeception/module-asserts", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" + "url": "https://github.com/Codeception/module-asserts.git", + "reference": "1b6b150b30586c3614e7e5761b31834ed7968603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", + "url": "https://api.github.com/repos/Codeception/module-asserts/zipball/1b6b150b30586c3614e7e5761b31834ed7968603", + "reference": "1b6b150b30586c3614e7e5761b31834ed7968603", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" + "codeception/codeception": "*@dev", + "codeception/lib-asserts": "^2.0", + "php": "^8.0" }, - "suggest": { - "ext-mbstring": "For best performance" + "conflict": { + "codeception/codeception": "<5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -517,78 +557,157 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Michael Bodnarchuk" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Gintautas Miselis" + }, + { + "name": "Gustavo Nieves", + "homepage": "https://medium.com/@ganieves" } ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", + "description": "Codeception module containing various assertions", + "homepage": "https://codeception.com/", "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" + "assertions", + "asserts", + "codeception" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + "issues": "https://github.com/Codeception/module-asserts/issues", + "source": "https://github.com/Codeception/module-asserts/tree/3.0.0" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-07-28T09:04:16+00:00" + "time": "2022-02-16T19:48:08+00:00" }, { - "name": "symfony/polyfill-php80", - "version": "v1.28.0", + "name": "codeception/module-cli", + "version": "2.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + "url": "https://github.com/Codeception/module-cli.git", + "reference": "a3a101fae4049fa2f810107f7bd5db3b3266ce63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "url": "https://api.github.com/repos/Codeception/module-cli/zipball/a3a101fae4049fa2f810107f7bd5db3b3266ce63", + "reference": "a3a101fae4049fa2f810107f7bd5db3b3266ce63", "shasum": "" }, "require": { - "php": ">=7.1" + "codeception/codeception": "*@dev", + "codeception/module-asserts": "*", + "php": "^7.4 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } + "conflict": { + "codeception/codeception": "<4.0" }, + "type": "library", "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk" + } + ], + "description": "Codeception module for testing basic shell commands and shell output", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception" + ], + "support": { + "issues": "https://github.com/Codeception/module-cli/issues", + "source": "https://github.com/Codeception/module-cli/tree/2.0.1" + }, + "time": "2023-01-13T18:41:03+00:00" + }, + { + "name": "codeception/module-db", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/Codeception/module-db.git", + "reference": "185889230bccfc65d2c03624879ade5357ec43f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/module-db/zipball/185889230bccfc65d2c03624879ade5357ec43f9", + "reference": "185889230bccfc65d2c03624879ade5357ec43f9", + "shasum": "" + }, + "require": { + "codeception/codeception": "*@dev", + "ext-json": "*", + "ext-pdo": "*", + "php": "^8.0" + }, + "conflict": { + "codeception/codeception": "<5.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk" }, + { + "name": "Gintautas Miselis" + } + ], + "description": "DB module for Codeception", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception", + "database-testing", + "db-testing" + ], + "support": { + "issues": "https://github.com/Codeception/module-db/issues", + "source": "https://github.com/Codeception/module-db/tree/3.1.1" + }, + "time": "2023-03-18T07:35:25+00:00" + }, + { + "name": "codeception/module-filesystem", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/Codeception/module-filesystem.git", + "reference": "0fd78cf941cb72dc2a650c6132c5999c26ad4f9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/module-filesystem/zipball/0fd78cf941cb72dc2a650c6132c5999c26ad4f9a", + "reference": "0fd78cf941cb72dc2a650c6132c5999c26ad4f9a", + "shasum": "" + }, + "require": { + "codeception/codeception": "*@dev", + "php": "^8.0", + "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0" + }, + "conflict": { + "codeception/codeception": "<5.0" + }, + "type": "library", + "autoload": { "classmap": [ - "Resources/stubs" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -597,47 +716,191 @@ ], "authors": [ { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" + "name": "Michael Bodnarchuk" }, { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Gintautas Miselis" + } + ], + "description": "Codeception module for testing local filesystem", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception", + "filesystem" + ], + "support": { + "issues": "https://github.com/Codeception/module-filesystem/issues", + "source": "https://github.com/Codeception/module-filesystem/tree/3.0.1" + }, + "time": "2023-12-08T19:23:28+00:00" + }, + { + "name": "codeception/module-phpbrowser", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/Codeception/module-phpbrowser.git", + "reference": "a972411f60cd00d00d5e5e3b35496ba4a23bcffc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/module-phpbrowser/zipball/a972411f60cd00d00d5e5e3b35496ba4a23bcffc", + "reference": "a972411f60cd00d00d5e5e3b35496ba4a23bcffc", + "shasum": "" + }, + "require": { + "codeception/codeception": "*@dev", + "codeception/lib-innerbrowser": "*@dev", + "ext-json": "*", + "guzzlehttp/guzzle": "^7.4", + "php": "^8.0", + "symfony/browser-kit": "^5.4 || ^6.0 || ^7.0" + }, + "conflict": { + "codeception/codeception": "<5.0", + "codeception/lib-innerbrowser": "<3.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.199", + "codeception/module-rest": "^2.0 || *@dev", + "ext-curl": "*" + }, + "suggest": { + "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Bodnarchuk" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Gintautas Miselis" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", + "description": "Codeception module for testing web application over HTTP", + "homepage": "https://codeception.com/", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "codeception", + "functional-testing", + "http" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + "issues": "https://github.com/Codeception/module-phpbrowser/issues", + "source": "https://github.com/Codeception/module-phpbrowser/tree/3.0.1" }, - "funding": [ + "time": "2023-12-08T19:41:28+00:00" + }, + { + "name": "codeception/module-webdriver", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/Codeception/module-webdriver.git", + "reference": "59b6fe426dddbe889c23593f8698c52e08bba6e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/module-webdriver/zipball/59b6fe426dddbe889c23593f8698c52e08bba6e9", + "reference": "59b6fe426dddbe889c23593f8698c52e08bba6e9", + "shasum": "" + }, + "require": { + "codeception/codeception": "^5.0.0-RC2", + "codeception/lib-web": "^1.0.1", + "codeception/stub": "^4.0", + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.0", + "php-webdriver/webdriver": "^1.8.0", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" + "name": "Michael Bodnarchuk" }, { - "url": "https://github.com/fabpot", - "type": "github" + "name": "Gintautas Miselis" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" + "name": "Zaahid Bateson" } ], - "time": "2023-01-26T09:26:14+00:00" - } - ], - "packages-dev": [ + "description": "WebDriver module for Codeception", + "homepage": "https://codeception.com/", + "keywords": [ + "acceptance-testing", + "browser-testing", + "codeception" + ], + "support": { + "issues": "https://github.com/Codeception/module-webdriver/issues", + "source": "https://github.com/Codeception/module-webdriver/tree/3.2.1" + }, + "time": "2023-02-03T21:46:32+00:00" + }, + { + "name": "codeception/stub", + "version": "4.1.2", + "source": { + "type": "git", + "url": "https://github.com/Codeception/Stub.git", + "reference": "f6bc56e33e3f5ba7a831dfb968c49b27cf1676ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/Stub/zipball/f6bc56e33e3f5ba7a831dfb968c49b27cf1676ad", + "reference": "f6bc56e33e3f5ba7a831dfb968c49b27cf1676ad", + "shasum": "" + }, + "require": { + "php": "^7.4 | ^8.0", + "phpunit/phpunit": "^8.4 | ^9.0 | ^10.0 | 10.0.x-dev" + }, + "conflict": { + "codeception/codeception": "<5.0.6" + }, + "require-dev": { + "consolidation/robo": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Codeception\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", + "support": { + "issues": "https://github.com/Codeception/Stub/issues", + "source": "https://github.com/Codeception/Stub/tree/4.1.2" + }, + "time": "2023-10-07T19:22:36+00:00" + }, { "name": "composer/ca-bundle", "version": "1.3.7", @@ -1388,16 +1651,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.40.0", + "version": "v3.41.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "27d2b3265b5d550ec411b4319967ae7cfddfb2e0" + "reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/27d2b3265b5d550ec411b4319967ae7cfddfb2e0", - "reference": "27d2b3265b5d550ec411b4319967ae7cfddfb2e0", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8b6ae8dcbaf23f09680643ab832a4a3a260265f6", + "reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6", "shasum": "" }, "require": { @@ -1427,8 +1690,6 @@ "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", - "phpspec/prophecy": "^1.17", - "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.6", "symfony/phpunit-bridge": "^6.3.8 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" @@ -1469,7 +1730,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.40.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.1" }, "funding": [ { @@ -1477,7 +1738,7 @@ "type": "github" } ], - "time": "2023-11-26T09:25:53+00:00" + "time": "2023-12-10T19:59:27+00:00" }, { "name": "gettext/gettext", @@ -1635,39 +1896,30 @@ "time": "2022-10-18T15:00:10+00:00" }, { - "name": "justinrainbow/json-schema", - "version": "v5.2.13", + "name": "graham-campbell/result-type", + "version": "v1.1.2", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", - "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.35" + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" }, - "bin": [ - "bin/validate-json" - ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, "autoload": { "psr-4": { - "JsonSchema\\": "src/JsonSchema/" + "GrahamCampbell\\ResultType\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1676,108 +1928,192 @@ ], "authors": [ { - "name": "Bruno Prieto Reis", - "email": "bruno.p.reis@gmail.com" - }, - { - "name": "Justin Rainbow", - "email": "justin.rainbow@gmail.com" - }, - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - }, - { - "name": "Robert Schönthal", - "email": "seroscho@googlemail.com" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" } ], - "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", + "description": "An Implementation Of The Result Type", "keywords": [ - "json", - "schema" + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" }, - "time": "2023-09-26T02:20:38+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:16:48+00:00" }, { - "name": "mck89/peast", - "version": "v1.15.4", + "name": "guzzlehttp/guzzle", + "version": "7.8.1", "source": { "type": "git", - "url": "https://github.com/mck89/peast.git", - "reference": "1df4dc28a6b5bb7ab117ab073c1712256e954e18" + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mck89/peast/zipball/1df4dc28a6b5bb7ab117ab073c1712256e954e18", - "reference": "1df4dc28a6b5bb7ab117ab073c1712256e954e18", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=5.4.0" + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.15.4-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { + "files": [ + "src/functions_include.php" + ], "psr-4": { - "Peast\\": "lib/Peast/" + "GuzzleHttp\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Marco Marchiò", - "email": "marco.mm89@gmail.com" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], - "description": "Peast is PHP library that generates AST for JavaScript code", + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], "support": { - "issues": "https://github.com/mck89/peast/issues", - "source": "https://github.com/mck89/peast/tree/v1.15.4" + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" }, - "time": "2023-08-12T08:29:29+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:35:24+00:00" }, { - "name": "mustache/mustache", - "version": "v2.14.2", + "name": "guzzlehttp/promises", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/bobthecow/mustache.php.git", - "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb" + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/e62b7c3849d22ec55f3ec425507bf7968193a6cb", - "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~1.11", - "phpunit/phpunit": "~3.7|~4.0|~5.0" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "psr-0": { - "Mustache": "src/" + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1786,933 +2122,3001 @@ ], "authors": [ { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], - "description": "A Mustache implementation in PHP.", - "homepage": "https://github.com/bobthecow/mustache.php", + "description": "Guzzle promises library", "keywords": [ - "mustache", - "templating" + "promise" ], "support": { - "issues": "https://github.com/bobthecow/mustache.php/issues", - "source": "https://github.com/bobthecow/mustache.php/tree/v2.14.2" + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" }, - "time": "2022-08-23T13:07:01+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:19:20+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.11.1", + "name": "guzzlehttp/psr7", + "version": "2.6.2", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" }, "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "GuzzleHttp\\Psr7\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2023-12-03T20:05:35+00:00" }, { - "name": "nb/oxymel", - "version": "v0.1.0", + "name": "ifsnop/mysqldump-php", + "version": "v2.12", "source": { "type": "git", - "url": "https://github.com/nb/oxymel.git", - "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c" + "url": "https://github.com/ifsnop/mysqldump-php.git", + "reference": "2d3a43fc0c49f23bf7dee392b0dd1f8c799f89d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nb/oxymel/zipball/cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", - "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", + "url": "https://api.github.com/repos/ifsnop/mysqldump-php/zipball/2d3a43fc0c49f23bf7dee392b0dd1f8c799f89d3", + "reference": "2d3a43fc0c49f23bf7dee392b0dd1f8c799f89d3", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.8.36", + "squizlabs/php_codesniffer": "1.*" }, "type": "library", "autoload": { - "psr-0": { - "Oxymel": "" + "psr-4": { + "Ifsnop\\": "src/Ifsnop/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "GPL-3.0-or-later" ], "authors": [ { - "name": "Nikolay Bachiyski", - "email": "nb@nikolay.bg", - "homepage": "http://extrapolate.me/" + "name": "Diego Torres", + "homepage": "https://github.com/ifsnop", + "role": "Developer" } ], - "description": "A sweet XML builder", - "homepage": "https://github.com/nb/oxymel", + "description": "PHP version of mysqldump cli that comes with MySQL", + "homepage": "https://github.com/ifsnop/mysqldump-php", "keywords": [ - "xml" + "PHP7", + "database", + "hhvm", + "mariadb", + "mysql", + "mysql-backup", + "mysqldump", + "pdo", + "php", + "php5", + "sql" ], "support": { - "issues": "https://github.com/nb/oxymel/issues", - "source": "https://github.com/nb/oxymel/tree/master" + "issues": "https://github.com/ifsnop/mysqldump-php/issues", + "source": "https://github.com/ifsnop/mysqldump-php/tree/v2.12" }, - "time": "2013-02-24T15:01:54+00:00" + "time": "2023-04-12T07:43:14+00:00" }, { - "name": "nikic/php-parser", - "version": "v4.17.1", + "name": "json-mapper/json-mapper", + "version": "2.21.0", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "url": "https://github.com/JsonMapper/JsonMapper.git", + "reference": "df180e75e45f2d4224064eac948f6c9521262b49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/JsonMapper/JsonMapper/zipball/df180e75e45f2d4224064eac948f6c9521262b49", + "reference": "df180e75e45f2d4224064eac948f6c9521262b49", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=7.0" + "ext-json": "*", + "myclabs/php-enum": "^1.7", + "nikic/php-parser": "^4.13", + "php": "^7.1 || ^8.0", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "psr/simple-cache": " ^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.0 || ^6.0", + "symfony/polyfill-php73": "^1.18" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "guzzlehttp/guzzle": "^6.5 || ^7.0", + "php-coveralls/php-coveralls": "^2.4", + "phpstan/phpstan": "^0.12.14", + "phpstan/phpstan-phpunit": "^0.12.17", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.5", + "symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0", + "vimeo/psalm": "^4.10 || ^5.0" }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } + "suggest": { + "json-mapper/laravel-package": "Use JsonMapper directly with Laravel", + "json-mapper/symfony-bundle": "Use JsonMapper directly with Symfony" }, + "type": "library", "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "JsonMapper\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } + "MIT" ], - "description": "A PHP parser written in PHP", + "description": "Map JSON structures to PHP classes", + "homepage": "https://jsonmapper.net", "keywords": [ - "parser", - "php" + "json", + "jsonmapper", + "mapper", + "middleware" ], "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "docs": "https://jsonmapper.net", + "issues": "https://github.com/JsonMapper/JsonMapper/issues", + "source": "https://github.com/JsonMapper/JsonMapper" }, - "time": "2023-08-13T19:53:39+00:00" + "funding": [ + { + "url": "https://github.com/DannyvdSluijs", + "type": "github" + } + ], + "time": "2023-12-12T11:57:53+00:00" }, { - "name": "phar-io/manifest", - "version": "2.0.3", + "name": "justinrainbow/json-schema", + "version": "v5.2.13", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" + "php": ">=5.3.3" }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "5.0.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" }, - "time": "2021-07-20T11:28:43+00:00" + "time": "2023-09-26T02:20:38+00:00" }, { - "name": "phar-io/version", - "version": "3.2.1", + "name": "league/flysystem", + "version": "1.1.10", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1", + "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "ext-fileinfo": "*", + "league/mime-type-detection": "^1.3", + "php": "^7.2.5 || ^8.0" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "phpspec/prophecy": "^1.11.1", + "phpunit/phpunit": "^8.5.8" + }, + "suggest": { + "ext-ftp": "Allows you to use FTP server storage", + "ext-openssl": "Allows you to use FTPS server storage", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", + "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", + "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "League\\Flysystem\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "name": "Frank de Jonge", + "email": "info@frenky.net" } ], - "description": "Library for handling version information and constraints", + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" }, - "time": "2022-02-21T01:04:05+00:00" + "funding": [ + { + "url": "https://offset.earth/frankdejonge", + "type": "other" + } + ], + "time": "2022-10-04T09:16:37+00:00" }, { - "name": "php-stubs/wordpress-stubs", - "version": "v6.4.1", + "name": "league/mime-type-detection", + "version": "1.14.0", "source": { "type": "git", - "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "6d6063cf9464a306ca2a0529705d41312b08500b" + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/6d6063cf9464a306ca2a0529705d41312b08500b", - "reference": "6d6063cf9464a306ca2a0529705d41312b08500b", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b6a5854368533df0295c5761a0253656a2e52d9e", + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e", "shasum": "" }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "nikic/php-parser": "^4.13", - "php": "^7.4 || ~8.0.0", - "php-stubs/generator": "^0.8.3", - "phpdocumentor/reflection-docblock": "^5.3", - "phpstan/phpstan": "^1.10.12", - "phpunit/phpunit": "^9.5", - "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.8" + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" }, - "suggest": { - "paragonie/sodium_compat": "Pure PHP implementation of libsodium", - "symfony/polyfill-php80": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" }, "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "WordPress function and class declaration stubs for static analysis.", - "homepage": "https://github.com/php-stubs/wordpress-stubs", - "keywords": [ - "PHPStan", - "static analysis", - "wordpress" + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } ], + "description": "Mime-type detection for Flysystem", "support": { - "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.4.1" + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.14.0" }, - "time": "2023-11-10T00:33:47+00:00" + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2023-10-17T14:13:20+00:00" }, { - "name": "php-stubs/wordpress-tests-stubs", - "version": "v6.3.0", + "name": "lucatume/wp-browser", + "version": "4.0.17", "source": { "type": "git", - "url": "https://github.com/php-stubs/wordpress-tests-stubs.git", - "reference": "c603908a8e70895ba3d5b5050ed791511cabc60f" + "url": "https://github.com/lucatume/wp-browser.git", + "reference": "8bc87c0ab9e154eff6e5fa40b707f06c452387aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-tests-stubs/zipball/c603908a8e70895ba3d5b5050ed791511cabc60f", - "reference": "c603908a8e70895ba3d5b5050ed791511cabc60f", + "url": "https://api.github.com/repos/lucatume/wp-browser/zipball/8bc87c0ab9e154eff6e5fa40b707f06c452387aa", + "reference": "8bc87c0ab9e154eff6e5fa40b707f06c452387aa", "shasum": "" }, + "require": { + "codeception/codeception": "^5.0", + "codeception/module-asserts": "^2.0 || ^3.0", + "codeception/module-cli": "^2.0 || ^3.0", + "codeception/module-db": "^2.0 || ^3.0", + "codeception/module-filesystem": "^2.0 || ^3.0", + "codeception/module-phpbrowser": "^2.0 || ^3.0", + "codeception/module-webdriver": "^2.0 || ^3.0", + "composer-runtime-api": "^2.2", + "ext-curl": "*", + "ext-fileinfo": "*", + "ext-json": "*", + "ext-mysqli": "*", + "ext-pdo": "*", + "ext-zip": "*", + "ifsnop/mysqldump-php": "^2.12", + "php": "^8.0", + "symfony/filesystem": ">=4.4.24 <7.0", + "symfony/process": ">=4.4.24 <7.0", + "vlucas/phpdotenv": "^5.0" + }, "require-dev": { - "php": "~7.3 || ~8.0", - "php-stubs/generator": "^0.8.0" + "gumlet/php-image-resize": "^1.6", + "lucatume/codeception-snapshot-assertions": "^1.0.0", + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan": "*", + "phpstan/phpstan-symfony": "^1.3", + "rector/rector": "^0.18.5", + "squizlabs/php_codesniffer": "^3.7", + "szepeviktor/phpstan-wordpress": "^1.3" }, "suggest": { - "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + "ext-pdo_sqlite": "For SQLite database support.", + "ext-sqlite3": "For SQLite database support." }, "type": "library", + "extra": { + "_hash": "484f861f69198089cab0e642f27e5653" + }, + "autoload": { + "files": [ + "src/version-4-aliases.php", + "src/Deprecated/deprecated-functions.php", + "src/functions.php" + ], + "psr-4": { + "Hautelook\\Phpass\\": "includes/Hautelook/Phpass", + "lucatume\\WPBrowser\\": [ + "src/", + "src/Deprecated" + ], + "lucatume\\WPBrowser\\Opis\\Closure\\": "includes/opis/closure/src" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "WordPress Tests function and class declaration stubs for static analysis.", - "homepage": "https://github.com/php-stubs/wordpress-tests-stubs", + "authors": [ + { + "name": "theAverageDev (Luca Tumedei)", + "email": "luca@theaveragedev.com", + "homepage": "https://theaveragedev.com", + "role": "Developer" + } + ], + "description": "A set of Codeception modules to test WordPress projects.", + "homepage": "https://github.com/lucatume/wp-browser", "keywords": [ - "PHPStan", - "static analysis", + "codeception", "wordpress" ], "support": { - "issues": "https://github.com/php-stubs/wordpress-tests-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-tests-stubs/tree/v6.3.0" + "issues": "https://github.com/lucatume/wp-browser/issues", + "source": "https://github.com/lucatume/wp-browser/tree/4.0.17" }, - "time": "2023-08-10T16:09:20+00:00" + "funding": [ + { + "url": "https://github.com/lucatume", + "type": "github" + } + ], + "time": "2023-12-14T07:30:37+00:00" }, { - "name": "php-stubs/wp-cli-stubs", - "version": "v2.9.0", + "name": "masterminds/html5", + "version": "2.8.1", "source": { "type": "git", - "url": "https://github.com/php-stubs/wp-cli-stubs.git", - "reference": "aa2afe94cd02f314659a3d9ef8821a3f81761c37" + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wp-cli-stubs/zipball/aa2afe94cd02f314659a3d9ef8821a3f81761c37", - "reference": "aa2afe94cd02f314659a3d9ef8821a3f81761c37", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", "shasum": "" }, "require": { - "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0" + "ext-dom": "*", + "php": ">=5.3.0" }, "require-dev": { - "php": "~7.3 || ~8.0", - "php-stubs/generator": "^0.8.0" - }, - "suggest": { - "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "WP-CLI function and class declaration stubs for static analysis.", - "homepage": "https://github.com/php-stubs/wp-cli-stubs", + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", "keywords": [ - "PHPStan", - "static analysis", - "wordpress", - "wp-cli" + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" ], "support": { - "issues": "https://github.com/php-stubs/wp-cli-stubs/issues", - "source": "https://github.com/php-stubs/wp-cli-stubs/tree/v2.9.0" + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" }, - "time": "2023-10-25T09:19:29+00:00" + "time": "2023-05-10T11:58:31+00:00" }, { - "name": "phpcompatibility/php-compatibility", - "version": "9.3.5", + "name": "mck89/peast", + "version": "v1.15.4", "source": { "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" + "url": "https://github.com/mck89/peast.git", + "reference": "1df4dc28a6b5bb7ab117ab073c1712256e954e18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", + "url": "https://api.github.com/repos/mck89/peast/zipball/1df4dc28a6b5bb7ab117ab073c1712256e954e18", + "reference": "1df4dc28a6b5bb7ab117ab073c1712256e954e18", "shasum": "" }, "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + "ext-mbstring": "*", + "php": ">=5.4.0" }, - "conflict": { - "squizlabs/php_codesniffer": "2.6.2" + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15.4-dev" + } + }, + "autoload": { + "psr-4": { + "Peast\\": "lib/Peast/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Marco Marchiò", + "email": "marco.mm89@gmail.com" + } + ], + "description": "Peast is PHP library that generates AST for JavaScript code", + "support": { + "issues": "https://github.com/mck89/peast/issues", + "source": "https://github.com/mck89/peast/tree/v1.15.4" + }, + "time": "2023-08-12T08:29:29+00:00" + }, + { + "name": "mustache/mustache", + "version": "v2.14.2", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/mustache.php.git", + "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/e62b7c3849d22ec55f3ec425507bf7968193a6cb", + "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~1.11", + "phpunit/phpunit": "~3.7|~4.0|~5.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Mustache": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "A Mustache implementation in PHP.", + "homepage": "https://github.com/bobthecow/mustache.php", + "keywords": [ + "mustache", + "templating" + ], + "support": { + "issues": "https://github.com/bobthecow/mustache.php/issues", + "source": "https://github.com/bobthecow/mustache.php/tree/v2.14.2" + }, + "time": "2022-08-23T13:07:01+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "myclabs/php-enum", + "version": "1.8.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^4.6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.4" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2022-08-04T09:53:51+00:00" + }, + { + "name": "nb/oxymel", + "version": "v0.1.0", + "source": { + "type": "git", + "url": "https://github.com/nb/oxymel.git", + "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nb/oxymel/zipball/cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", + "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "type": "library", + "autoload": { + "psr-0": { + "Oxymel": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nikolay Bachiyski", + "email": "nb@nikolay.bg", + "homepage": "http://extrapolate.me/" + } + ], + "description": "A sweet XML builder", + "homepage": "https://github.com/nb/oxymel", + "keywords": [ + "xml" + ], + "support": { + "issues": "https://github.com/nb/oxymel/issues", + "source": "https://github.com/nb/oxymel/tree/master" + }, + "time": "2013-02-24T15:01:54+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.18.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + }, + "time": "2023-12-10T21:03:43+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-stubs/wordpress-stubs", + "version": "v6.4.1", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wordpress-stubs.git", + "reference": "6d6063cf9464a306ca2a0529705d41312b08500b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/6d6063cf9464a306ca2a0529705d41312b08500b", + "reference": "6d6063cf9464a306ca2a0529705d41312b08500b", + "shasum": "" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "nikic/php-parser": "^4.13", + "php": "^7.4 || ~8.0.0", + "php-stubs/generator": "^0.8.3", + "phpdocumentor/reflection-docblock": "^5.3", + "phpstan/phpstan": "^1.10.12", + "phpunit/phpunit": "^9.5", + "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.8" + }, + "suggest": { + "paragonie/sodium_compat": "Pure PHP implementation of libsodium", + "symfony/polyfill-php80": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WordPress function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wordpress-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress" + ], + "support": { + "issues": "https://github.com/php-stubs/wordpress-stubs/issues", + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.4.1" + }, + "time": "2023-11-10T00:33:47+00:00" + }, + { + "name": "php-stubs/wordpress-tests-stubs", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wordpress-tests-stubs.git", + "reference": "c603908a8e70895ba3d5b5050ed791511cabc60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wordpress-tests-stubs/zipball/c603908a8e70895ba3d5b5050ed791511cabc60f", + "reference": "c603908a8e70895ba3d5b5050ed791511cabc60f", + "shasum": "" + }, + "require-dev": { + "php": "~7.3 || ~8.0", + "php-stubs/generator": "^0.8.0" + }, + "suggest": { + "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WordPress Tests function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wordpress-tests-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress" + ], + "support": { + "issues": "https://github.com/php-stubs/wordpress-tests-stubs/issues", + "source": "https://github.com/php-stubs/wordpress-tests-stubs/tree/v6.3.0" + }, + "time": "2023-08-10T16:09:20+00:00" + }, + { + "name": "php-stubs/wp-cli-stubs", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wp-cli-stubs.git", + "reference": "aa2afe94cd02f314659a3d9ef8821a3f81761c37" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wp-cli-stubs/zipball/aa2afe94cd02f314659a3d9ef8821a3f81761c37", + "reference": "aa2afe94cd02f314659a3d9ef8821a3f81761c37", + "shasum": "" + }, + "require": { + "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0" + }, + "require-dev": { + "php": "~7.3 || ~8.0", + "php-stubs/generator": "^0.8.0" + }, + "suggest": { + "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WP-CLI function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wp-cli-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress", + "wp-cli" + ], + "support": { + "issues": "https://github.com/php-stubs/wp-cli-stubs/issues", + "source": "https://github.com/php-stubs/wp-cli-stubs/tree/v2.9.0" + }, + "time": "2023-10-25T09:19:29+00:00" + }, + { + "name": "php-webdriver/webdriver", + "version": "1.15.1", + "source": { + "type": "git", + "url": "https://github.com/php-webdriver/php-webdriver.git", + "reference": "cd52d9342c5aa738c2e75a67e47a1b6df97154e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/cd52d9342c5aa738c2e75a67e47a1b6df97154e8", + "reference": "cd52d9342c5aa738c2e75a67e47a1b6df97154e8", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-zip": "*", + "php": "^7.3 || ^8.0", + "symfony/polyfill-mbstring": "^1.12", + "symfony/process": "^5.0 || ^6.0 || ^7.0" + }, + "replace": { + "facebook/webdriver": "*" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.20.0", + "ondram/ci-detector": "^4.0", + "php-coveralls/php-coveralls": "^2.4", + "php-mock/php-mock-phpunit": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.5", + "symfony/var-dumper": "^5.0 || ^6.0" + }, + "suggest": { + "ext-SimpleXML": "For Firefox profile creation" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Exception/TimeoutException.php" + ], + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.", + "homepage": "https://github.com/php-webdriver/php-webdriver", + "keywords": [ + "Chromedriver", + "geckodriver", + "php", + "selenium", + "webdriver" + ], + "support": { + "issues": "https://github.com/php-webdriver/php-webdriver/issues", + "source": "https://github.com/php-webdriver/php-webdriver/tree/1.15.1" + }, + "time": "2023-10-20T12:21:20+00:00" + }, + { + "name": "phpcompatibility/php-compatibility", + "version": "9.3.5", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + }, + "conflict": { + "squizlabs/php_codesniffer": "2.6.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "homepage": "https://github.com/wimg", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + } + ], + "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", + "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "keywords": [ + "compatibility", + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibility" + }, + "time": "2019-12-27T09:44:58+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-paragonie", + "version": "1.3.2", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", + "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", + "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7", + "paragonie/random_compat": "dev-master", + "paragonie/sodium_compat": "dev-master" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "paragonie", + "phpcs", + "polyfill", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" + }, + "time": "2022-10-25T01:46:02+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-wp", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", + "reference": "b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5", + "reference": "b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/phpcompatibility-paragonie": "^1.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "phpcs", + "standards", + "static analysis", + "wordpress" + ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" + }, + "time": "2022-10-24T09:00:36+00:00" + }, + { + "name": "phpcsstandards/phpcsextra", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHPCSExtra.git", + "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", + "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "phpcsstandards/phpcsutils": "^1.0.9", + "squizlabs/php_codesniffer": "^3.8.0" + }, + "require-dev": { + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcsstandards/phpcsdevcs": "^1.1.6", + "phpcsstandards/phpcsdevtools": "^1.2.1", + "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-stable": "1.x-dev", + "dev-develop": "1.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHPCSExtra/graphs/contributors" + } + ], + "description": "A collection of sniffs and standards for use with PHP_CodeSniffer.", + "keywords": [ + "PHP_CodeSniffer", + "phpcbf", + "phpcodesniffer-standard", + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHPCSExtra/issues", + "security": "https://github.com/PHPCSStandards/PHPCSExtra/security/policy", + "source": "https://github.com/PHPCSStandards/PHPCSExtra" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2023-12-08T16:49:07+00:00" + }, + { + "name": "phpcsstandards/phpcsutils", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", + "reference": "908247bc65010c7b7541a9551e002db12e9dae70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/908247bc65010c7b7541a9551e002db12e9dae70", + "reference": "908247bc65010c7b7541a9551e002db12e9dae70", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^3.8.0 || 4.0.x-dev@dev" + }, + "require-dev": { + "ext-filter": "*", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcsstandards/phpcsdevcs": "^1.1.6", + "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-stable": "1.x-dev", + "dev-develop": "1.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPCSUtils/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHPCSUtils/graphs/contributors" + } + ], + "description": "A suite of utility functions for use with PHP_CodeSniffer", + "homepage": "https://phpcsutils.com/", + "keywords": [ + "PHP_CodeSniffer", + "phpcbf", + "phpcodesniffer-standard", + "phpcs", + "phpcs3", + "standards", + "static analysis", + "tokens", + "utility" + ], + "support": { + "docs": "https://phpcsutils.com/", + "issues": "https://github.com/PHPCSStandards/PHPCSUtils/issues", + "security": "https://github.com/PHPCSStandards/PHPCSUtils/security/policy", + "source": "https://github.com/PHPCSStandards/PHPCSUtils" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2023-12-08T14:50:00+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.2", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2023-11-12T21:59:55+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.3.1" + }, + "time": "2023-05-24T08:59:17+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.50", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/06a98513ac72c03e8366b5a0cb00750b487032e4", + "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2023-12-13T10:59:42+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.29", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-19T04:57:46+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.15", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1", + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.28", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-12-01T16:55:19+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", + "shasum": "" }, - "require-dev": { - "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + "require": { + "php": ">=8.0.0" }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } }, - "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "MIT" ], "authors": [ { - "name": "Wim Godden", - "homepage": "https://github.com/wimg", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", - "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ - "compatibility", - "phpcs", - "standards" + "log", + "psr", + "psr-3" ], "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibility" + "source": "https://github.com/php-fig/log/tree/2.0.0" }, - "time": "2019-12-27T09:44:58+00:00" + "time": "2021-07-14T16:41:46+00:00" }, { - "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.2", + "name": "psr/simple-cache", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26" + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", - "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", "shasum": "" }, "require": { - "phpcompatibility/php-compatibility": "^9.0" + "php": ">=8.0.0" }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "paragonie/random_compat": "dev-master", - "paragonie/sodium_compat": "dev-master" + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } }, - "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "MIT" ], "authors": [ { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", - "homepage": "http://phpcompatibility.com/", + "description": "Common interfaces for simple caching", "keywords": [ - "compatibility", - "paragonie", - "phpcs", - "polyfill", - "standards", - "static analysis" + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" ], "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" }, - "time": "2022-10-25T01:46:02+00:00" + "time": "2021-10-29T13:26:27+00:00" }, { - "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.4", + "name": "psy/psysh", + "version": "v0.11.22", "source": { "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5" + "url": "https://github.com/bobthecow/psysh.git", + "reference": "128fa1b608be651999ed9789c95e6e2a31b5802b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5", - "reference": "b6c1e3ee1c35de6c41a511d5eb9bd03e447480a5", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/128fa1b608be651999ed9789c95e6e2a31b5802b", + "reference": "128fa1b608be651999ed9789c95e6e2a31b5802b", "shasum": "" }, "require": { - "phpcompatibility/php-compatibility": "^9.0", - "phpcompatibility/phpcompatibility-paragonie": "^1.0" + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^4.0 || ^3.1", + "php": "^8.0 || ^7.0.8", + "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7" + "bamarni/composer-bin-plugin": "^1.2" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-0.11": "0.11.x-dev" + }, + "bamarni-bin": { + "bin-links": false, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } }, - "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "MIT" ], "authors": [ { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" } ], - "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", - "homepage": "http://phpcompatibility.com/", + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", "keywords": [ - "compatibility", - "phpcs", - "standards", - "static analysis", - "wordpress" + "REPL", + "console", + "interactive", + "shell" ], "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.11.22" }, - "time": "2022-10-24T09:00:36+00:00" + "time": "2023-10-14T21:56:36+00:00" }, { - "name": "phpcsstandards/phpcsextra", - "version": "1.1.2", + "name": "ralouphie/getallheaders", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/PHPCSExtra.git", - "reference": "746c3190ba8eb2f212087c947ba75f4f5b9a58d5" + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/746c3190ba8eb2f212087c947ba75f4f5b9a58d5", - "reference": "746c3190ba8eb2f212087c947ba75f4f5b9a58d5", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", "shasum": "" }, "require": { - "php": ">=5.4", - "phpcsstandards/phpcsutils": "^1.0.8", - "squizlabs/php_codesniffer": "^3.7.1" + "php": ">=5.6" }, "require-dev": { - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcsstandards/phpcsdevcs": "^1.1.6", - "phpcsstandards/phpcsdevtools": "^1.2.1", - "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0" + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-stable": "1.x-dev", - "dev-develop": "1.x-dev" - } + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "MIT" ], "authors": [ { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHPCSExtra/graphs/contributors" + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" } ], - "description": "A collection of sniffs and standards for use with PHP_CodeSniffer.", - "keywords": [ - "PHP_CodeSniffer", - "phpcbf", - "phpcodesniffer-standard", - "phpcs", - "standards", - "static analysis" - ], + "description": "A polyfill for getallheaders.", "support": { - "issues": "https://github.com/PHPCSStandards/PHPCSExtra/issues", - "source": "https://github.com/PHPCSStandards/PHPCSExtra" + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" }, - "time": "2023-09-20T22:06:18+00:00" + "time": "2019-03-08T08:55:37+00:00" }, { - "name": "phpcsstandards/phpcsutils", - "version": "1.0.8", + "name": "react/promise", + "version": "v2.11.0", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", - "reference": "69465cab9d12454e5e7767b9041af0cd8cd13be7" + "url": "https://github.com/reactphp/promise.git", + "reference": "1a8460931ea36dc5c76838fec5734d55c88c6831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/69465cab9d12454e5e7767b9041af0cd8cd13be7", - "reference": "69465cab9d12454e5e7767b9041af0cd8cd13be7", + "url": "https://api.github.com/repos/reactphp/promise/zipball/1a8460931ea36dc5c76838fec5734d55c88c6831", + "reference": "1a8460931ea36dc5c76838fec5734d55c88c6831", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0", - "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.7.1 || 4.0.x-dev@dev" + "php": ">=5.4.0" }, "require-dev": { - "ext-filter": "*", - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcsstandards/phpcsdevcs": "^1.1.6", - "yoast/phpunit-polyfills": "^1.0.5 || ^2.0.0" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-stable": "1.x-dev", - "dev-develop": "1.x-dev" - } + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, + "type": "library", "autoload": { - "classmap": [ - "PHPCSUtils/" - ] + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "MIT" ], "authors": [ { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" }, { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHPCSUtils/graphs/contributors" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "A suite of utility functions for use with PHP_CodeSniffer", - "homepage": "https://phpcsutils.com/", + "description": "A lightweight implementation of CommonJS Promises/A for PHP", "keywords": [ - "PHP_CodeSniffer", - "phpcbf", - "phpcodesniffer-standard", - "phpcs", - "phpcs3", - "standards", - "static analysis", - "tokens", - "utility" + "promise", + "promises" ], - "support": { - "docs": "https://phpcsutils.com/", - "issues": "https://github.com/PHPCSStandards/PHPCSUtils/issues", - "source": "https://github.com/PHPCSStandards/PHPCSUtils" + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v2.11.0" }, - "time": "2023-07-16T21:39:41+00:00" + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-16T16:16:50+00:00" }, { - "name": "phpstan/extension-installer", - "version": "1.3.1", + "name": "sebastian/cli-parser", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/phpstan/extension-installer.git", - "reference": "f45734bfb9984c6c56c4486b71230355f066a58a" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a", - "reference": "f45734bfb9984c6c56c4486b71230355f066a58a", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", "shasum": "" }, "require": { - "composer-plugin-api": "^2.0", - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.9.0" + "php": ">=7.3" }, "require-dev": { - "composer/composer": "^2.0", - "php-parallel-lint/php-parallel-lint": "^1.2.0", - "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + "phpunit/phpunit": "^9.3" }, - "type": "composer-plugin", + "type": "library", "extra": { - "class": "PHPStan\\ExtensionInstaller\\Plugin" + "branch-alias": { + "dev-master": "1.0-dev" + } }, "autoload": { - "psr-4": { - "PHPStan\\ExtensionInstaller\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "Composer plugin for automatic installation of PHPStan extensions", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { - "issues": "https://github.com/phpstan/extension-installer/issues", - "source": "https://github.com/phpstan/extension-installer/tree/1.3.1" + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" }, - "time": "2023-05-24T08:59:17+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" }, { - "name": "phpstan/phpstan", - "version": "1.10.44", + "name": "sebastian/code-unit", + "version": "1.0.8", "source": { "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "bf84367c53a23f759513985c54ffe0d0c249825b" + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bf84367c53a23f759513985c54ffe0d0c249825b", - "reference": "bf84367c53a23f759513985c54ffe0d0c249825b", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": ">=7.3" }, - "conflict": { - "phpstan/phpstan-shim": "*" + "require-dev": { + "phpunit/phpunit": "^9.3" }, - "bin": [ - "phpstan", - "phpstan.phar" - ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "autoload": { - "files": [ - "bootstrap.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "PHPStan - PHP Static Analysis Tool", - "keywords": [ - "dev", - "static analysis" + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { - "docs": "https://phpstan.org/user-guide/getting-started", - "forum": "https://github.com/phpstan/phpstan/discussions", - "issues": "https://github.com/phpstan/phpstan/issues", - "security": "https://github.com/phpstan/phpstan/security/policy", - "source": "https://github.com/phpstan/phpstan-src" + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" }, "funding": [ { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2023-11-21T16:30:46+00:00" + "time": "2020-10-26T13:08:54+00:00" }, { - "name": "phpstan/phpstan-phpunit", - "version": "1.3.15", + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", "source": { "type": "git", - "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "70ecacc64fe8090d8d2a33db5a51fe8e88acd93a" + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/70ecacc64fe8090d8d2a33db5a51fe8e88acd93a", - "reference": "70ecacc64fe8090d8d2a33db5a51fe8e88acd93a", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10" - }, - "conflict": { - "phpunit/phpunit": "<7.0" + "php": ">=7.3" }, "require-dev": { - "nikic/php-parser": "^4.13.0", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-strict-rules": "^1.5.1", - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.3" }, - "type": "phpstan-extension", + "type": "library", "extra": { - "phpstan": { - "includes": [ - "extension.neon", - "rules.neon" - ] + "branch-alias": { + "dev-master": "2.0-dev" } }, "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "PHPUnit extensions and rules for PHPStan", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { - "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.15" + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" }, - "time": "2023-10-09T18:58:39+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "name": "sebastian/comparator", + "version": "4.0.8", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" }, "require-dev": { "phpunit/phpunit": "^9.3" }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -2727,21 +5131,31 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ - "coverage", - "testing", - "xunit" + "comparator", + "compare", + "equality" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -2749,23 +5163,24 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "name": "sebastian/complexity", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", "shasum": "" }, "require": { + "nikic/php-parser": "^4.7", "php": ">=7.3" }, "require-dev": { @@ -2774,7 +5189,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -2790,18 +5205,14 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" + "role": "lead" + } ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" }, "funding": [ { @@ -2809,36 +5220,33 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2020-10-26T15:52:27+00:00" }, { - "name": "phpunit/php-invoker", - "version": "3.1.1", + "name": "sebastian/diff", + "version": "4.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -2853,18 +5261,24 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "process" + "diff", + "udiff", + "unidiff", + "unified diff" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" }, "funding": [ { @@ -2872,20 +5286,20 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2023-05-07T05:35:17+00:00" }, { - "name": "phpunit/php-text-template", - "version": "2.0.4", + "name": "sebastian/environment", + "version": "5.1.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -2894,10 +5308,13 @@ "require-dev": { "phpunit/phpunit": "^9.3" }, + "suggest": { + "ext-posix": "*" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -2912,18 +5329,19 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ - "template" + "Xdebug", + "environment", + "hhvm" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -2931,32 +5349,34 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { - "name": "phpunit/php-timer", - "version": "5.0.3", + "name": "sebastian/exporter", + "version": "4.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" }, "require-dev": { + "ext-mbstring": "*", "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -2971,18 +5391,34 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ - "timer" + "export", + "exporter" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -2990,68 +5426,41 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { - "name": "phpunit/phpunit", - "version": "9.6.13", + "name": "sebastian/global-state", + "version": "5.0.6", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bde739e7565280bda77be70044ac1047bc007e34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", - "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1 || ^2", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.28", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", - "sebastian/version": "^3.0.2" + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "ext-uopz": "*" }, - "bin": [ - "phpunit" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "9.6-dev" + "dev-master": "5.0-dev" } }, "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], "classmap": [ "src/" ] @@ -3063,172 +5472,152 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ - "phpunit", - "testing", - "xunit" + "global state" ], "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" }, "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, { "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" } ], - "time": "2023-09-19T05:39:22+00:00" + "time": "2023-08-02T09:26:13+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "sebastian/lines-of-code", + "version": "1.0.3", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", "shasum": "" }, "require": { - "php": ">=7.2.0" + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" }, - "time": "2019-01-08T18:20:26+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" }, { - "name": "react/promise", - "version": "v2.11.0", + "name": "sebastian/object-enumerator", + "version": "4.0.4", "source": { "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "1a8460931ea36dc5c76838fec5734d55c88c6831" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/1a8460931ea36dc5c76838fec5734d55c88c6831", - "reference": "1a8460931ea36dc5c76838fec5734d55c88c6831", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + "phpunit/phpunit": "^9.3" }, "type": "library", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "React\\Promise\\": "src/" + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com", - "homepage": "https://sorgalla.com/" - }, - { - "name": "Christian Lück", - "email": "christian@clue.engineering", - "homepage": "https://clue.engineering/" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "reactphp@ceesjankiewiet.nl", - "homepage": "https://wyrihaximus.net/" - }, - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "https://cboden.dev/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "A lightweight implementation of CommonJS Promises/A for PHP", - "keywords": [ - "promise", - "promises" - ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v2.11.0" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" }, "funding": [ { - "url": "https://opencollective.com/reactphp", - "type": "open_collective" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "time": "2023-11-16T16:16:50+00:00" + "time": "2020-10-26T13:12:34+00:00" }, { - "name": "sebastian/cli-parser", - "version": "1.0.1", + "name": "sebastian/object-reflector", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { @@ -3240,7 +5629,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -3255,15 +5644,14 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" }, "funding": [ { @@ -3271,20 +5659,20 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2020-10-26T13:14:26+00:00" }, { - "name": "sebastian/code-unit", - "version": "1.0.8", + "name": "sebastian/recursion-context", + "version": "4.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -3296,7 +5684,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -3311,15 +5699,22 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -3327,32 +5722,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "name": "sebastian/resource-operations", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -3370,11 +5765,11 @@ "email": "sebastian@phpunit.de" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" }, "funding": [ { @@ -3382,34 +5777,32 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2020-09-28T06:45:17+00:00" }, { - "name": "sebastian/comparator", - "version": "4.0.8", + "name": "sebastian/type", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -3424,31 +5817,15 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -3456,33 +5833,29 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { - "name": "sebastian/complexity", - "version": "2.0.2", + "name": "sebastian/version", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", "php": ">=7.3" }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -3501,11 +5874,11 @@ "role": "lead" } ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" }, "funding": [ { @@ -3513,702 +5886,849 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2020-09-28T06:39:44+00:00" }, { - "name": "sebastian/diff", - "version": "4.0.5", + "name": "seld/jsonlint", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/594fd6462aad8ecee0b45ca5045acea4776667f1", + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1", "shasum": "" }, "require": { - "php": ">=7.3" + "php": "^5.3 || ^7.0 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" }, + "bin": [ + "bin/jsonlint" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", + "description": "JSON Linter", "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" + "json", + "linter", + "parser", + "validator" ], "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + "issues": "https://github.com/Seldaek/jsonlint/issues", + "source": "https://github.com/Seldaek/jsonlint/tree/1.10.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/Seldaek", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "type": "tidelift" } ], - "time": "2023-05-07T05:35:17+00:00" + "time": "2023-05-11T13:16:46+00:00" }, { - "name": "sebastian/environment", - "version": "5.1.5", + "name": "seld/phar-utils", + "version": "1.2.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" + "php": ">=5.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "1.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Seld\\PharUtils\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "description": "PHAR file format utilities, for when PHP phars you up", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "phar" ], "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "issues": "https://github.com/Seldaek/phar-utils/issues", + "source": "https://github.com/Seldaek/phar-utils/tree/1.2.1" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2022-08-31T10:31:18+00:00" }, { - "name": "sebastian/exporter", - "version": "4.0.5", + "name": "squizlabs/php_codesniffer", + "version": "3.8.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5805f7a4e4958dbb5e944ef1e6edae0a303765e7", + "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "3.x-dev" } }, - "autoload": { - "classmap": [ - "src/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "name": "Greg Sherwood", + "role": "Former lead" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Juliette Reinders Folmer", + "role": "Current lead" }, { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ - "export", - "exporter" + "phpcs", + "standards", + "static analysis" ], "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2023-12-08T12:32:31+00:00" }, { - "name": "sebastian/global-state", - "version": "5.0.6", + "name": "symfony/browser-kit", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bde739e7565280bda77be70044ac1047bc007e34" + "url": "https://github.com/symfony/browser-kit.git", + "reference": "a3bb210e001580ec75e1d02b27fae3452e6bf502" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", - "reference": "bde739e7565280bda77be70044ac1047bc007e34", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/a3bb210e001580ec75e1d02b27fae3452e6bf502", + "reference": "a3bb210e001580ec75e1d02b27fae3452e6bf502", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "symfony/dom-crawler": "^5.4|^6.0|^7.0" }, "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], + "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" + "source": "https://github.com/symfony/browser-kit/tree/v6.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-08-02T09:26:13+00:00" + "time": "2023-10-31T08:18:17+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "1.0.3", + "name": "symfony/cache", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "url": "https://github.com/symfony/cache.git", + "reference": "ac2d25f97b17eec6e19760b6b9962a4f7c44356a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/symfony/cache/zipball/ac2d25f97b17eec6e19760b6b9962a4f7c44356a", + "reference": "ac2d25f97b17eec6e19760b6b9962a4f7c44356a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" + "php": ">=8.1", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.3.6|^7.0" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/var-dumper": "<5.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, "classmap": [ - "src/" + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/symfony/cache/tree/v6.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-11-24T19:28:07+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "4.0.4", + "name": "symfony/cache-contracts", + "version": "v3.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "1d74b127da04ffa87aa940abe15446fa89653778" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/1d74b127da04ffa87aa940abe15446fa89653778", + "reference": "1d74b127da04ffa87aa940abe15446fa89653778", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=8.1", + "psr/cache": "^3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/symfony/cache-contracts/tree/v3.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2023-09-25T12:52:38+00:00" }, { - "name": "sebastian/object-reflector", - "version": "2.0.4", + "name": "symfony/console", + "version": "v5.4.32", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "url": "https://github.com/symfony/console.git", + "reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/symfony/console/zipball/c70df1ffaf23a8d340bded3cfab1b86752ad6ed7", + "reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" + }, + "conflict": { + "psr/log": ">=3", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" }, + "type": "library", "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/symfony/console/tree/v5.4.32" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2023-11-18T18:23:04+00:00" }, { - "name": "sebastian/recursion-context", - "version": "4.0.5", + "name": "symfony/css-selector", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "url": "https://github.com/symfony/css-selector.git", + "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/d036c6c0d0b09e24a14a35f8292146a658f986e4", + "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=8.1" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "source": "https://github.com/symfony/css-selector/tree/v6.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T06:07:39+00:00" + "time": "2023-10-31T08:40:20+00:00" }, { - "name": "sebastian/resource-operations", - "version": "3.0.3", + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "classmap": [ - "src/" + "files": [ + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { - "name": "sebastian/type", - "version": "3.2.1", + "name": "symfony/dom-crawler", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "14ff4fd2a5c8969d6158dbe7ef5b17d6a9c6ba33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/14ff4fd2a5c8969d6158dbe7ef5b17d6a9c6ba33", + "reference": "14ff4fd2a5c8969d6158dbe7ef5b17d6a9c6ba33", "shasum": "" }, "require": { - "php": ">=7.3" + "masterminds/html5": "^2.6", + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "symfony/css-selector": "^5.4|^6.0|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Eases DOM navigation for HTML and XML documents", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2023-02-03T06:13:03+00:00" + "time": "2023-11-20T16:41:16+00:00" }, { - "name": "sebastian/version", - "version": "3.0.2", + "name": "symfony/event-dispatcher", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d76d2632cfc2206eecb5ad2b26cd5934082941b6", + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, + "type": "library", "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2023-07-27T06:52:43+00:00" }, { - "name": "seld/jsonlint", - "version": "1.10.0", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.4.0", "source": { "type": "git", - "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/594fd6462aad8ecee0b45ca5045acea4776667f1", - "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { - "php": "^5.3 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.5", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, - "bin": [ - "bin/jsonlint" - ], "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, "autoload": { "psr-4": { - "Seld\\JsonLint\\": "src/Seld/JsonLint/" + "Symfony\\Contracts\\EventDispatcher\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -4217,61 +6737,70 @@ ], "authors": [ { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "JSON Linter", + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", "keywords": [ - "json", - "linter", - "parser", - "validator" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.10.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" }, "funding": [ { - "url": "https://github.com/Seldaek", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-05-11T13:16:46+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { - "name": "seld/phar-utils", - "version": "1.2.1", + "name": "symfony/filesystem", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c" + "url": "https://github.com/symfony/filesystem.git", + "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", - "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/952a8cb588c3bc6ce76f6023000fb932f16a6e59", + "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59", "shasum": "" }, "require": { - "php": ">=5.3" + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, "autoload": { "psr-4": { - "Seld\\PharUtils\\": "src/" - } + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4279,130 +6808,121 @@ ], "authors": [ { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "PHAR file format utilities, for when PHP phars you up", - "keywords": [ - "phar" - ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/Seldaek/phar-utils/issues", - "source": "https://github.com/Seldaek/phar-utils/tree/1.2.1" + "source": "https://github.com/symfony/filesystem/tree/v6.4.0" }, - "time": "2022-08-31T10:31:18+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-26T17:27:13+00:00" }, { - "name": "squizlabs/php_codesniffer", - "version": "3.7.2", + "name": "symfony/finder", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + "url": "https://github.com/symfony/finder.git", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", "shasum": "" }, "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "symfony/filesystem": "^6.0|^7.0" }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Greg Sherwood", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + "source": "https://github.com/symfony/finder/tree/v6.4.0" }, - "time": "2023-02-22T23:07:41+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-10-31T17:30:12+00:00" }, { - "name": "symfony/console", - "version": "v5.4.31", + "name": "symfony/options-resolver", + "version": "v7.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "700ff4096e346f54cb628ea650767c8130f1001f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/11ac5f154e0e5c4c77af83ad11ead9165280b92a", - "reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f", + "reference": "700ff4096e346f54cb628ea650767c8130f1001f", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" - }, - "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0" - }, - "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Console\\": "" + "Symfony\\Component\\OptionsResolver\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -4422,16 +6942,15 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Eases the creation of beautiful and testable command line interfaces", + "description": "Provides an improved replacement for the array_replace PHP function", "homepage": "https://symfony.com", "keywords": [ - "cli", - "command-line", - "console", - "terminal" + "config", + "configuration", + "options" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.31" + "source": "https://github.com/symfony/options-resolver/tree/v7.0.0" }, "funding": [ { @@ -4447,52 +6966,48 @@ "type": "tidelift" } ], - "time": "2023-10-31T07:58:33+00:00" + "time": "2023-08-08T10:20:21+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v6.3.2", + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", - "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/event-dispatcher-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/service-contracts": "<2.5" + "php": ">=7.1" }, "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0|3.0" + "ext-ctype": "*" }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0" + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4500,18 +7015,24 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" }, "funding": [ { @@ -4527,39 +7048,44 @@ "type": "tidelift" } ], - "time": "2023-07-06T06:56:43+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "1.28-dev" }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -4576,18 +7102,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to dispatching event", + "description": "Symfony polyfill for intl's grapheme_* functions", "homepage": "https://symfony.com", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" }, "funding": [ { @@ -4603,34 +7129,47 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/filesystem", - "version": "v6.3.1", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", - "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -4639,18 +7178,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides basic utilities for the filesystem", + "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.3.1" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" }, "funding": [ { @@ -4666,36 +7213,48 @@ "type": "tidelift" } ], - "time": "2023-06-01T08:30:39+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/finder", - "version": "v6.3.5", + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4", - "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.1" }, - "require-dev": { - "symfony/filesystem": "^6.0" + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4703,18 +7262,25 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Finds files and directories via an intuitive fluent interface", + "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/finder/tree/v6.3.5" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, "funding": [ { @@ -4730,33 +7296,44 @@ "type": "tidelift" } ], - "time": "2023-09-26T12:56:25+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { - "name": "symfony/options-resolver", - "version": "v6.3.0", + "name": "symfony/polyfill-php73", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=7.1" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" + "Symfony\\Polyfill\\Php73\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -4765,23 +7342,24 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an improved replacement for the array_replace PHP function", + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ - "config", - "configuration", - "options" + "compatibility", + "polyfill", + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" }, "funding": [ { @@ -4797,31 +7375,25 @@ "type": "tidelift" } ], - "time": "2023-05-12T14:21:09+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/polyfill-ctype", + "name": "symfony/polyfill-php80", "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { "php": ">=7.1" }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, "type": "library", "extra": { "branch-alias": { @@ -4837,8 +7409,11 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4846,24 +7421,28 @@ ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "ctype", "polyfill", - "portable" + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" }, "funding": [ { @@ -4882,25 +7461,22 @@ "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/polyfill-intl-grapheme", + "name": "symfony/polyfill-php81", "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "875e90aeea2777b6f135677f618529449334a612" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", - "reference": "875e90aeea2777b6f135677f618529449334a612", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", "shasum": "" }, "require": { "php": ">=7.1" }, - "suggest": { - "ext-intl": "For best performance" - }, "type": "library", "extra": { "branch-alias": { @@ -4916,8 +7492,11 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4933,18 +7512,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's grapheme_* functions", + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "grapheme", - "intl", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" }, "funding": [ { @@ -4963,44 +7540,29 @@ "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", + "name": "symfony/process", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + "url": "https://github.com/symfony/process.git", + "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "url": "https://api.github.com/repos/symfony/process/zipball/191703b1566d97a5425dc969e4350d32b8ef17aa", + "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=8.1" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + "Symfony\\Component\\Process\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5009,26 +7571,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + "source": "https://github.com/symfony/process/tree/v6.4.0" }, "funding": [ { @@ -5044,44 +7598,45 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2023-11-17T21:06:49+00:00" }, { - "name": "symfony/polyfill-php73", - "version": "v1.28.0", + "name": "symfony/service-contracts", + "version": "v3.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", - "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.28-dev" + "dev-main": "3.4-dev" }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" + "Symfony\\Contracts\\Service\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5098,16 +7653,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" }, "funding": [ { @@ -5123,44 +7680,33 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { - "name": "symfony/polyfill-php81", - "version": "v1.28.0", + "name": "symfony/stopwatch", + "version": "v7.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", - "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" + "Symfony\\Component\\Stopwatch\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5169,24 +7715,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "description": "Provides a way to profile code", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.0.0" }, "funding": [ { @@ -5202,29 +7742,46 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2023-07-05T13:06:06+00:00" }, { - "name": "symfony/process", - "version": "v6.3.4", + "name": "symfony/string", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" + "url": "https://github.com/symfony/string.git", + "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54", - "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", + "url": "https://api.github.com/repos/symfony/string/zipball/b45fcf399ea9c3af543a92edf7172ba21174d809", + "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { + "files": [ + "Resources/functions.php" + ], "psr-4": { - "Symfony\\Component\\Process\\": "" + "Symfony\\Component\\String\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5236,18 +7793,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Executes commands in sub-processes", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], "support": { - "source": "https://github.com/symfony/process/tree/v6.3.4" + "source": "https://github.com/symfony/string/tree/v6.4.0" }, "funding": [ { @@ -5263,45 +7828,52 @@ "type": "tidelift" } ], - "time": "2023-08-07T10:39:22+00:00" + "time": "2023-11-28T20:41:49+00:00" }, { - "name": "symfony/service-contracts", - "version": "v3.4.0", + "name": "symfony/var-dumper", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" + "url": "https://github.com/symfony/var-dumper.git", + "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c40f7d17e91d8b407582ed51a2bbf83c52c367f6", + "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^2.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "ext-psr": "<1.1|>=2" + "symfony/console": "<5.4" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "twig/twig": "^2.13|^3.0.4" }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", "autoload": { + "files": [ + "Resources/functions/dump.php" + ], "psr-4": { - "Symfony\\Contracts\\Service\\": "" + "Symfony\\Component\\VarDumper\\": "" }, "exclude-from-classmap": [ - "/Test/" + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5318,18 +7890,14 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to writing services", + "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "debug", + "dump" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.0" }, "funding": [ { @@ -5345,30 +7913,32 @@ "type": "tidelift" } ], - "time": "2023-07-30T20:28:31+00:00" + "time": "2023-11-09T08:28:32+00:00" }, { - "name": "symfony/stopwatch", - "version": "v6.3.0", + "name": "symfony/var-exporter", + "version": "v7.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + "url": "https://github.com/symfony/var-exporter.git", + "reference": "a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3", + "reference": "a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/service-contracts": "^2.5|^3" + "php": ">=8.2" + }, + "require-dev": { + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" + "Symfony\\Component\\VarExporter\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5380,18 +7950,28 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a way to profile code", + "description": "Allows exporting any serializable PHP data structure to plain PHP code", "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" + "source": "https://github.com/symfony/var-exporter/tree/v7.0.1" }, "funding": [ { @@ -5407,46 +7987,40 @@ "type": "tidelift" } ], - "time": "2023-02-16T10:14:28+00:00" + "time": "2023-11-30T11:38:21+00:00" }, { - "name": "symfony/string", - "version": "v6.3.8", + "name": "symfony/yaml", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "13880a87790c76ef994c91e87efb96134522577a" + "url": "https://github.com/symfony/yaml.git", + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/13880a87790c76ef994c91e87efb96134522577a", - "reference": "13880a87790c76ef994c91e87efb96134522577a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/translation-contracts": "<2.5" + "symfony/console": "<5.4" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0" + "symfony/console": "^5.4|^6.0|^7.0" }, + "bin": [ + "Resources/bin/yaml-lint" + ], "type": "library", "autoload": { - "files": [ - "Resources/functions.php" - ], "psr-4": { - "Symfony\\Component\\String\\": "" + "Symfony\\Component\\Yaml\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5458,26 +8032,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], "support": { - "source": "https://github.com/symfony/string/tree/v6.3.8" + "source": "https://github.com/symfony/yaml/tree/v6.4.0" }, "funding": [ { @@ -5493,7 +8059,7 @@ "type": "tidelift" } ], - "time": "2023-11-09T08:28:21+00:00" + "time": "2023-11-06T11:00:25+00:00" }, { "name": "szepeviktor/phpstan-wordpress", @@ -5607,13 +8173,97 @@ ], "time": "2023-11-20T00:12:19+00:00" }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:43:29+00:00" + }, { "name": "wordpress/wordpress", "version": "dev-trunk", "source": { "type": "git", "url": "https://github.com/wordpress/wordpress-develop.git", - "reference": "cd5cf79e54826e17f0e0776e933402f2cee4218c" + "reference": "59947c5623a940191fc202de25bd02b6a409e90f" }, "require": { "php": ">=7.0" @@ -5661,7 +8311,7 @@ "support": { "issues": "https://core.trac.wordpress.org/" }, - "time": "2023-11-25T21:17:28+00:00" + "time": "2023-12-17T02:46:38+00:00" }, { "name": "wp-cli/cache-command", @@ -5740,16 +8390,16 @@ }, { "name": "wp-cli/checksum-command", - "version": "v2.2.4", + "version": "v2.2.5", "source": { "type": "git", "url": "https://github.com/wp-cli/checksum-command.git", - "reference": "7ae020192bc6ee9042be0bf664bd998b1861e994" + "reference": "f6911998734018da08f75464a168feb0d07b4475" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/checksum-command/zipball/7ae020192bc6ee9042be0bf664bd998b1861e994", - "reference": "7ae020192bc6ee9042be0bf664bd998b1861e994", + "url": "https://api.github.com/repos/wp-cli/checksum-command/zipball/f6911998734018da08f75464a168feb0d07b4475", + "reference": "f6911998734018da08f75464a168feb0d07b4475", "shasum": "" }, "require": { @@ -5793,9 +8443,9 @@ "homepage": "https://github.com/wp-cli/checksum-command", "support": { "issues": "https://github.com/wp-cli/checksum-command/issues", - "source": "https://github.com/wp-cli/checksum-command/tree/v2.2.4" + "source": "https://github.com/wp-cli/checksum-command/tree/v2.2.5" }, - "time": "2023-08-30T13:34:47+00:00" + "time": "2023-11-10T21:54:15+00:00" }, { "name": "wp-cli/config-command", @@ -5873,16 +8523,16 @@ }, { "name": "wp-cli/core-command", - "version": "v2.1.15", + "version": "v2.1.16", "source": { "type": "git", "url": "https://github.com/wp-cli/core-command.git", - "reference": "7a81a8658620078bf5f2785836cb33aa382e8bb4" + "reference": "9d6ebb4545df0b8bc7e688a49910ddcdd86dbe93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/core-command/zipball/7a81a8658620078bf5f2785836cb33aa382e8bb4", - "reference": "7a81a8658620078bf5f2785836cb33aa382e8bb4", + "url": "https://api.github.com/repos/wp-cli/core-command/zipball/9d6ebb4545df0b8bc7e688a49910ddcdd86dbe93", + "reference": "9d6ebb4545df0b8bc7e688a49910ddcdd86dbe93", "shasum": "" }, "require": { @@ -5938,9 +8588,9 @@ "homepage": "https://github.com/wp-cli/core-command", "support": { "issues": "https://github.com/wp-cli/core-command/issues", - "source": "https://github.com/wp-cli/core-command/tree/v2.1.15" + "source": "https://github.com/wp-cli/core-command/tree/v2.1.16" }, - "time": "2023-08-30T15:54:16+00:00" + "time": "2023-11-10T23:54:33+00:00" }, { "name": "wp-cli/cron-command", @@ -6013,16 +8663,16 @@ }, { "name": "wp-cli/db-command", - "version": "v2.0.26", + "version": "v2.0.27", "source": { "type": "git", "url": "https://github.com/wp-cli/db-command.git", - "reference": "0908bf5182b830c302199037070292e20d9f4ea6" + "reference": "eea28dd115fb381c82641a2a3060856d3a67242d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/db-command/zipball/0908bf5182b830c302199037070292e20d9f4ea6", - "reference": "0908bf5182b830c302199037070292e20d9f4ea6", + "url": "https://api.github.com/repos/wp-cli/db-command/zipball/eea28dd115fb381c82641a2a3060856d3a67242d", + "reference": "eea28dd115fb381c82641a2a3060856d3a67242d", "shasum": "" }, "require": { @@ -6081,9 +8731,9 @@ "homepage": "https://github.com/wp-cli/db-command", "support": { "issues": "https://github.com/wp-cli/db-command/issues", - "source": "https://github.com/wp-cli/db-command/tree/v2.0.26" + "source": "https://github.com/wp-cli/db-command/tree/v2.0.27" }, - "time": "2023-08-30T15:50:59+00:00" + "time": "2023-11-13T12:34:44+00:00" }, { "name": "wp-cli/embed-command", @@ -6486,16 +9136,16 @@ }, { "name": "wp-cli/extension-command", - "version": "v2.1.15", + "version": "v2.1.16", "source": { "type": "git", "url": "https://github.com/wp-cli/extension-command.git", - "reference": "1fe271c5ebb1815732a8cf6bb6979c9261ee6375" + "reference": "71183254b1e403bc0f9b4a97fab48e284cfe1367" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/extension-command/zipball/1fe271c5ebb1815732a8cf6bb6979c9261ee6375", - "reference": "1fe271c5ebb1815732a8cf6bb6979c9261ee6375", + "url": "https://api.github.com/repos/wp-cli/extension-command/zipball/71183254b1e403bc0f9b4a97fab48e284cfe1367", + "reference": "71183254b1e403bc0f9b4a97fab48e284cfe1367", "shasum": "" }, "require": { @@ -6578,22 +9228,22 @@ "homepage": "https://github.com/wp-cli/extension-command", "support": { "issues": "https://github.com/wp-cli/extension-command/issues", - "source": "https://github.com/wp-cli/extension-command/tree/v2.1.15" + "source": "https://github.com/wp-cli/extension-command/tree/v2.1.16" }, - "time": "2023-10-11T14:55:49+00:00" + "time": "2023-11-10T12:24:35+00:00" }, { "name": "wp-cli/i18n-command", - "version": "v2.4.4", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/wp-cli/i18n-command.git", - "reference": "7d82e675f271359b1af614e6325d8eeaeb7d7474" + "reference": "9cf9b40f6bad64ade8660cc26bf1f28f2d223268" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/i18n-command/zipball/7d82e675f271359b1af614e6325d8eeaeb7d7474", - "reference": "7d82e675f271359b1af614e6325d8eeaeb7d7474", + "url": "https://api.github.com/repos/wp-cli/i18n-command/zipball/9cf9b40f6bad64ade8660cc26bf1f28f2d223268", + "reference": "9cf9b40f6bad64ade8660cc26bf1f28f2d223268", "shasum": "" }, "require": { @@ -6646,9 +9296,9 @@ "homepage": "https://github.com/wp-cli/i18n-command", "support": { "issues": "https://github.com/wp-cli/i18n-command/issues", - "source": "https://github.com/wp-cli/i18n-command/tree/v2.4.4" + "source": "https://github.com/wp-cli/i18n-command/tree/v2.5.0" }, - "time": "2023-08-30T18:00:10+00:00" + "time": "2023-11-16T17:09:37+00:00" }, { "name": "wp-cli/import-command", @@ -6712,16 +9362,16 @@ }, { "name": "wp-cli/language-command", - "version": "v2.0.17", + "version": "v2.0.18", "source": { "type": "git", "url": "https://github.com/wp-cli/language-command.git", - "reference": "23636769d7dd0f55adbb84929afdf833723cfe8c" + "reference": "24f76e35f477887d09f1fd40a60d9011a6da18bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/language-command/zipball/23636769d7dd0f55adbb84929afdf833723cfe8c", - "reference": "23636769d7dd0f55adbb84929afdf833723cfe8c", + "url": "https://api.github.com/repos/wp-cli/language-command/zipball/24f76e35f477887d09f1fd40a60d9011a6da18bf", + "reference": "24f76e35f477887d09f1fd40a60d9011a6da18bf", "shasum": "" }, "require": { @@ -6785,22 +9435,22 @@ "homepage": "https://github.com/wp-cli/language-command", "support": { "issues": "https://github.com/wp-cli/language-command/issues", - "source": "https://github.com/wp-cli/language-command/tree/v2.0.17" + "source": "https://github.com/wp-cli/language-command/tree/v2.0.18" }, - "time": "2023-11-07T21:41:39+00:00" + "time": "2023-11-10T13:27:16+00:00" }, { "name": "wp-cli/maintenance-mode-command", - "version": "v2.0.10", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/wp-cli/maintenance-mode-command.git", - "reference": "599f8f08045ed2ef26a53d1432a4845b39d54f7d" + "reference": "2e9845a1cd1678b960dd8d0dd0c936648113788c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/maintenance-mode-command/zipball/599f8f08045ed2ef26a53d1432a4845b39d54f7d", - "reference": "599f8f08045ed2ef26a53d1432a4845b39d54f7d", + "url": "https://api.github.com/repos/wp-cli/maintenance-mode-command/zipball/2e9845a1cd1678b960dd8d0dd0c936648113788c", + "reference": "2e9845a1cd1678b960dd8d0dd0c936648113788c", "shasum": "" }, "require": { @@ -6846,22 +9496,22 @@ "homepage": "https://github.com/wp-cli/maintenance-mode-command", "support": { "issues": "https://github.com/wp-cli/maintenance-mode-command/issues", - "source": "https://github.com/wp-cli/maintenance-mode-command/tree/v2.0.10" + "source": "https://github.com/wp-cli/maintenance-mode-command/tree/v2.1.0" }, - "time": "2023-08-30T14:54:15+00:00" + "time": "2023-11-06T14:04:13+00:00" }, { "name": "wp-cli/media-command", - "version": "v2.0.20", + "version": "v2.0.21", "source": { "type": "git", "url": "https://github.com/wp-cli/media-command.git", - "reference": "49ef52c657de7ac1e50010ce3f6b0cdc40c02dc7" + "reference": "4950ed4ded35c52068d30fec080d545a33baa85c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/media-command/zipball/49ef52c657de7ac1e50010ce3f6b0cdc40c02dc7", - "reference": "49ef52c657de7ac1e50010ce3f6b0cdc40c02dc7", + "url": "https://api.github.com/repos/wp-cli/media-command/zipball/4950ed4ded35c52068d30fec080d545a33baa85c", + "reference": "4950ed4ded35c52068d30fec080d545a33baa85c", "shasum": "" }, "require": { @@ -6908,9 +9558,9 @@ "homepage": "https://github.com/wp-cli/media-command", "support": { "issues": "https://github.com/wp-cli/media-command/issues", - "source": "https://github.com/wp-cli/media-command/tree/v2.0.20" + "source": "https://github.com/wp-cli/media-command/tree/v2.0.21" }, - "time": "2023-09-01T13:08:38+00:00" + "time": "2023-11-10T21:56:52+00:00" }, { "name": "wp-cli/mustangostang-spyc", @@ -6965,20 +9615,20 @@ }, { "name": "wp-cli/package-command", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/wp-cli/package-command.git", - "reference": "f295538382b970cca506172b892f5f1c8adbedb2" + "reference": "71683195f8c27ad97009628e2a72d2a4155503b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/package-command/zipball/f295538382b970cca506172b892f5f1c8adbedb2", - "reference": "f295538382b970cca506172b892f5f1c8adbedb2", + "url": "https://api.github.com/repos/wp-cli/package-command/zipball/71683195f8c27ad97009628e2a72d2a4155503b2", + "reference": "71683195f8c27ad97009628e2a72d2a4155503b2", "shasum": "" }, "require": { - "composer/composer": "^1.10.23 || ~2.2.17", + "composer/composer": "^1.10.23 || ^2.2.17", "ext-json": "*", "wp-cli/wp-cli": "^2.8" }, @@ -7024,22 +9674,22 @@ "homepage": "https://github.com/wp-cli/package-command", "support": { "issues": "https://github.com/wp-cli/package-command/issues", - "source": "https://github.com/wp-cli/package-command/tree/v2.4.0" + "source": "https://github.com/wp-cli/package-command/tree/v2.5.0" }, - "time": "2023-09-06T21:10:16+00:00" + "time": "2023-12-08T10:38:16+00:00" }, { "name": "wp-cli/php-cli-tools", - "version": "v0.11.21", + "version": "v0.11.22", "source": { "type": "git", "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "b3457a8d60cd0b1c48cab76ad95df136d266f0b6" + "reference": "a6bb94664ca36d0962f9c2ff25591c315a550c51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/b3457a8d60cd0b1c48cab76ad95df136d266f0b6", - "reference": "b3457a8d60cd0b1c48cab76ad95df136d266f0b6", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/a6bb94664ca36d0962f9c2ff25591c315a550c51", + "reference": "a6bb94664ca36d0962f9c2ff25591c315a550c51", "shasum": "" }, "require": { @@ -7087,9 +9737,9 @@ ], "support": { "issues": "https://github.com/wp-cli/php-cli-tools/issues", - "source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.21" + "source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.22" }, - "time": "2023-09-29T15:28:10+00:00" + "time": "2023-12-03T19:25:05+00:00" }, { "name": "wp-cli/rewrite-command", @@ -7220,16 +9870,16 @@ }, { "name": "wp-cli/scaffold-command", - "version": "v2.1.3", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/wp-cli/scaffold-command.git", - "reference": "4125a31134e1bad3d28cff71c178dcee1393f605" + "reference": "8aa906c3ec6ae7d95f38c962fc2561714f9c7145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/scaffold-command/zipball/4125a31134e1bad3d28cff71c178dcee1393f605", - "reference": "4125a31134e1bad3d28cff71c178dcee1393f605", + "url": "https://api.github.com/repos/wp-cli/scaffold-command/zipball/8aa906c3ec6ae7d95f38c962fc2561714f9c7145", + "reference": "8aa906c3ec6ae7d95f38c962fc2561714f9c7145", "shasum": "" }, "require": { @@ -7280,9 +9930,9 @@ "homepage": "https://github.com/wp-cli/scaffold-command", "support": { "issues": "https://github.com/wp-cli/scaffold-command/issues", - "source": "https://github.com/wp-cli/scaffold-command/tree/v2.1.3" + "source": "https://github.com/wp-cli/scaffold-command/tree/v2.2.0" }, - "time": "2023-08-30T14:29:02+00:00" + "time": "2023-11-16T15:25:33+00:00" }, { "name": "wp-cli/search-replace-command", @@ -7733,16 +10383,16 @@ }, { "name": "wp-cli/wp-config-transformer", - "version": "v1.3.4", + "version": "v1.3.5", "source": { "type": "git", "url": "https://github.com/wp-cli/wp-config-transformer.git", - "reference": "1f80df413c0d779a813223d9dd5dd58358eee60c" + "reference": "202aa80528939159d52bc4026cee5453aec382db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/1f80df413c0d779a813223d9dd5dd58358eee60c", - "reference": "1f80df413c0d779a813223d9dd5dd58358eee60c", + "url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/202aa80528939159d52bc4026cee5453aec382db", + "reference": "202aa80528939159d52bc4026cee5453aec382db", "shasum": "" }, "require": { @@ -7771,9 +10421,9 @@ "homepage": "https://github.com/wp-cli/wp-config-transformer", "support": { "issues": "https://github.com/wp-cli/wp-config-transformer/issues", - "source": "https://github.com/wp-cli/wp-config-transformer/tree/v1.3.4" + "source": "https://github.com/wp-cli/wp-config-transformer/tree/v1.3.5" }, - "time": "2023-08-31T10:11:36+00:00" + "time": "2023-11-10T14:28:03+00:00" }, { "name": "wp-coding-standards/wpcs", @@ -7840,66 +10490,6 @@ } ], "time": "2023-09-14T07:06:09+00:00" - }, - { - "name": "yoast/phpunit-polyfills", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", - "reference": "224e4a1329c03d8bad520e3fc4ec980034a4b212" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/224e4a1329c03d8bad520e3fc4ec980034a4b212", - "reference": "224e4a1329c03d8bad520e3fc4ec980034a4b212", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "require-dev": { - "yoast/yoastcs": "^2.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.x-dev" - } - }, - "autoload": { - "files": [ - "phpunitpolyfills-autoload.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Team Yoast", - "email": "support@yoast.com", - "homepage": "https://yoast.com" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Yoast/PHPUnit-Polyfills/graphs/contributors" - } - ], - "description": "Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests", - "homepage": "https://github.com/Yoast/PHPUnit-Polyfills", - "keywords": [ - "phpunit", - "polyfill", - "testing" - ], - "support": { - "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", - "source": "https://github.com/Yoast/PHPUnit-Polyfills" - }, - "time": "2023-08-19T14:25:08+00:00" } ], "aliases": [], @@ -7909,7 +10499,12 @@ }, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], + "platform": { + "php": "^7.4 | ^8.0" + }, + "platform-dev": { + "ext-pdo": "*", + "ext-sqlite3": "*" + }, "plugin-api-version": "2.3.0" } diff --git a/config/development/Dockerfile b/config/development/Dockerfile new file mode 100644 index 0000000..c658154 --- /dev/null +++ b/config/development/Dockerfile @@ -0,0 +1,31 @@ +# Conatiner configuration for adding XDebug to the offical WordPress image +# https://github.com/wpdiaries/wordpress-xdebug.git + +FROM wordpress:6.4.1-php8.2-apache + +# Install packages under Debian +RUN apt-get update && \ + apt-get -y install git + +# Install XDebug from source as described here: +# https://xdebug.org/docs/install +# Available branches of XDebug could be seen here: +# https://github.com/xdebug/xdebug/branches +RUN cd /tmp && \ + git clone https://github.com/xdebug/xdebug.git && \ + cd xdebug && \ + git checkout xdebug_3_2 && \ + phpize && \ + ./configure --enable-xdebug && \ + make && \ + make install && \ + rm -rf /tmp/xdebug + +# Copy xdebug.ini to /usr/local/etc/php/conf.d/ +COPY files-to-copy/ / + +# Since this Dockerfile extends the official Docker image `wordpress`, +# and since `wordpress`, in turn, extends the official Docker image `php`, +# the helper script docker-php-ext-enable (defined for image `php`) +# works here, and we can use it to enable xdebug: +RUN docker-php-ext-enable xdebug diff --git a/config/development/files-to-copy/usr/local/etc/php/conf.d/xdebug.ini b/config/development/files-to-copy/usr/local/etc/php/conf.d/xdebug.ini new file mode 100644 index 0000000..5e2f08c --- /dev/null +++ b/config/development/files-to-copy/usr/local/etc/php/conf.d/xdebug.ini @@ -0,0 +1,15 @@ +# Parameters description could be found here: https://xdebug.org/docs/remote +# Also, for PhpStorm, configuration tips could be found here: https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html +zend_extension=xdebug.so + +xdebug.idekey="PHPSTORM" + +xdebug.start_with_request=yes +xdebug.mode=develop,debug +xdebug.discover_client_host=0 +xdebug.client_host=host.docker.internal +xdebug.client_port=9003 + +xdebug.var_display_max_children=2048 +xdebug.var_display_max_data=2048 +xdebug.var_display_max_depth=64 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..116abfc --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,75 @@ +version: "3.8" + +services: + wordpress: + restart: always + build: + context: ./config/development + + env_file: + - .env + + ports: + - ${WORDPRESS_LOCALHOST_PORT}:80 + + environment: + WORDPRESS_DB_HOST: database + WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME} + WORDPRESS_DB_USER: ${WORDPRESS_DB_NAME} # Same as db name. + WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_NAME} # Same as db name. + WORDPRESS_SKIP_INSTALL: "yes" + # Set the XDEBUG_CONFIG as described here: https://xdebug.org/docs/all_settings#XDEBUG_CONFIG + XDEBUG_CONFIG: client_host=192.168.1.2 # This is for XDebug 3. + + healthcheck: + test: + [ + "CMD", + "curl", + "--output", + "/dev/null", + "--silent", + "--fail", + "http://localhost:80", + ] + interval: 30s + timeout: 30s + retries: 3 + + tmpfs: + - /var/www/html + + volumes: + # - wordpress:/var/www/html + - ./:/var/www/html/wp-content/plugins/indexed-search + + depends_on: + - database + + database: + image: mariadb:10.8 + restart: always + + env_file: + - .env + + ports: + - "${WORDPRESS_DB_LOCALHOST_PORT}:3306" + + environment: + MYSQL_ROOT_PASSWORD: ${WORDPRESS_DB_PASSWORD} + MYSQL_USER: ${WORDPRESS_DB_NAME} # Same as db name. + MYSQL_PASSWORD: ${WORDPRESS_DB_NAME} # Same as db name. + MYSQL_DATABASE: ${WORDPRESS_DB_NAME} # Same as db name. + + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 30s + timeout: 30s + retries: 3 + + tmpfs: + - /var/lib/mysql + + volumes: + - ./tests/_data:/docker-entrypoint-initdb.d diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..280a409 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,14 @@ +# Architecture + +- Tokenization / Lexer + - HTML tokenization + - Stemming +- Index + - Repository + - Cron +- Ranking +- Query + - Parser / Lexer + - Repository +- Stop Words +- Config diff --git a/docs/schema.md b/docs/schema.md new file mode 100644 index 0000000..cc1f741 --- /dev/null +++ b/docs/schema.md @@ -0,0 +1,78 @@ +# Schema + +The database base structure used to index WordPress documents for search. + +## Document + +Has many words through the `document_word` table. + +Has many meta words through the `document_meta` table. + +Has many hits through the `query_hit` table. + +The biggest documents to index will be posts. + +There will need to be a way to indicated document type. + +|id|index_id| +|--|--------| + +## Index + +Used to group indexed documents and track queries. + +Has many documents. + +|id|name|description|type| +|--|----|-----------|----| + +## DocumentWord + +Ranking the importance of a word in the document based on meta words could be done during the index process, if we know how to rank the words at the time of indexing. + +|id|doc_id|word_id|position| +|--|------|-------|--------| + +## DocumentMeta + +Meta word table. `meta_id` is an enum of meta word types. + +|id|doc_id|meta_id|position| +|--|------|-------|--------| + +## Word + +Has many documents through `document_word` table. + +|id|value| +|--|-----| + +## Gram + +Unique segments of words. + +Have many words through the `gram_word` table. + +|id|value|length| +|--|-----|------| + +## GramWord + +Map partial word to full word + +|id|word_id|gram_id|hit_count| +|--|-------|-------|---------| + +## Query + +User input queries. + +|id|value| +|--|-----| + +## Query Hit + +Match successful queries to specific words contained in a document, independent of location with in the document. The concept is to have permanent link between query -> word -> document, used for ranking based on previous results. + +|id|query_id|word_id|document_id|count| +|--|--------|-------|-----------|-----| diff --git a/index.php b/index.php new file mode 100644 index 0000000..82f4b36 --- /dev/null +++ b/index.php @@ -0,0 +1,6 @@ + diff --git a/indexed-search.php b/indexed-search.php new file mode 100644 index 0000000..0342571 --- /dev/null +++ b/indexed-search.php @@ -0,0 +1,77 @@ +

' . esc_html__( 'Indexed Search requires PHP 7.4 or higher.', 'indexed-search' ) . '

'; + } + + add_action( 'admin_notices', 'indexed_search_minimum_php_version_notice' ); + + return; +} + +if ( version_compare( $GLOBALS['wp_version'], '6.2', '<' ) ) { + /** + * @return void + */ + function indexed_search_minimum_wp_version_notice() { + echo '

' . esc_html__( 'Indexed Search requires WordPress 6.2 or later.', 'indexed-search' ) . '

'; + } + + add_action( 'admin_notices', 'indexed_search_minimum_wp_version_notice' ); + + return; +} + +if ( file_exists( __DIR__ . '/vendor-prod/autoload.php' ) ) { + require_once( __DIR__ . '/vendor-prod/autoload.php' ); +} + +// Defines the path to the main plugin file. +define( 'S_FILE', __FILE__ ); + +// Defines the path to be used for includes. +define( 'S_PATH', plugin_dir_path( S_FILE ) ); + +// Defines the URL to the plugin. +define( 'S_URL', plugin_dir_url( S_FILE ) ); + +/** +* The block variation + */ +include_once S_PATH . 'src/variation.php'; + +/** +* The modal window + */ +include_once S_PATH . 'src/modal.php'; +add_action( 'wp_footer', 'live_search_modal_window' ); + +/** +* The rest api controller + */ +include_once S_PATH . 'src/rest.php'; +add_action( 'rest_api_init', 'register_live_search_endpoint' ); + +/** + * The rest api that will handle the search request + */ +include_once S_PATH . 'src/enqueue.php'; +add_action( 'rest_api_init', 'register_live_search_endpoint' ); diff --git a/jest.config.cjs b/jest.config.cjs new file mode 100644 index 0000000..e442dbb --- /dev/null +++ b/jest.config.cjs @@ -0,0 +1,14 @@ +const jestConfig = { + verbose: true, + preset: '@wordpress/jest-preset-default', + setupFilesAfterEnv: ['@wordpress/jest-console'], + modulePaths: ['/client'], + projects: [ + { + displayName: 'unit', + testMatch: ['/client/tests/unit/**/*.test.ts'], + }, + ], +}; + +module.exports = jestConfig; diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 6584d57..0000000 --- a/jest.config.js +++ /dev/null @@ -1,24 +0,0 @@ -const jestConfig = { - verbose: true, - preset: '@wordpress/jest-preset-default', - setupFilesAfterEnv: [ - '@wordpress/jest-console', - '@wordpress/jest-puppeteer-axe', - 'expect-puppeteer', - 'puppeteer-testing-library/extend-expect', - ], - modulePaths: [''], - projects: [ - { - displayName: 'unit', - testMatch: ['/tests/unit/**/*.test.ts'], - }, - { - displayName: 'e2e', - preset: 'jest-puppeteer', - testMatch: ['/tests/e2e/**/*.test.ts'], - }, - ], -}; - -module.exports = jestConfig; diff --git a/lint-staged.config.js b/lint-staged.config.js new file mode 100644 index 0000000..d0c69bc --- /dev/null +++ b/lint-staged.config.js @@ -0,0 +1,17 @@ +export default { + '**/*.(json|yml|yaml)': (filenames) => { + const files = filenames.join(' '); + return [`prettier --write ${files}`]; + }, + '**/*.(js|jsx|cjs|mjs|ts|tsx)': (filenames) => { + const files = filenames.join(' '); + return [`eslint --ext .js,.jsx,.cjs,.mjs,.ts,.tsx --fix ${files}`]; + }, + '**/*.(php)': (filenames) => { + const files = filenames.join(' '); + return [ + `./vendor/bin/phpstan analyze --memory-limit=4G --ansi ${files}`, + `./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --ansi ${files}`, + ]; + }, +}; diff --git a/package-lock.json b/package-lock.json index 787d5a4..5960b58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,45 +1,44 @@ { - "name": "search", + "name": "@wp-blocks/indexed-search", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "search", - "version": "0.0.1", + "name": "@wp-blocks/indexed-search", "license": "GPL-2.0-or-later", "devDependencies": { - "@babel/core": "^7.21.0", - "@babel/preset-typescript": "^7.21.0", - "@jest/globals": "^29.4.3", - "@types/babel__core": "^7.20.0", - "@types/expect-puppeteer": "^5.0.3", - "@types/jest": "^29.4.0", - "@types/jest-environment-puppeteer": "^5.0.3", - "@types/node": "^18.14.1", - "@types/puppeteer": "^7.0.4", - "@types/wordpress__block-editor": "^11.0.1", - "@types/wordpress__blocks": "^12.0.3", - "@types/wordpress__components": "^23.0.1", - "@types/wordpress__compose": "^6.0.1", - "@typescript-eslint/eslint-plugin": "^5.53.0", - "@typescript-eslint/parser": "^5.53.0", - "@wordpress/babel-plugin-makepot": "^5.30.0", - "@wordpress/block-editor": "^12.14.0", - "@wordpress/blocks": "^12.23.0", - "@wordpress/e2e-test-utils": "^10.17.0", - "@wordpress/e2e-tests": "^7.17.0", - "@wordpress/env": "^8.12.0", - "@wordpress/jest-preset-default": "^11.17.0", - "@wordpress/prettier-config": "^3.3.0", - "@wordpress/scripts": "^26.17.0", - "@wordpress/stylelint-config": "^21.29.0", + "@babel/core": "^7.23.5", + "@babel/preset-typescript": "^7.23.3", + "@jest/globals": "^29.7.0", + "@types/babel__core": "^7.20.5", + "@types/jest": "^29.5.10", + "@types/node": "^18.19.1", + "@types/wordpress__block-editor": "^11.5.7", + "@types/wordpress__blocks": "^12.5.11", + "@types/wordpress__components": "^23.0.8", + "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/parser": "^6.13.1", + "@wordpress/babel-plugin-makepot": "^5.31.0", + "@wordpress/block-editor": "^12.15.0", + "@wordpress/blocks": "^12.24.0", + "@wordpress/components": "^25.13.0", + "@wordpress/e2e-test-utils-playwright": "^0.15.0", + "@wordpress/env": "^8.13.0", + "@wordpress/jest-preset-default": "^11.18.0", + "@wordpress/prettier-config": "^3.4.0", + "@wordpress/scripts": "^26.18.0", + "@wordpress/stylelint-config": "^21.30.0", "@wp-blocks/tsconfig": "^0.1.0", - "babel-jest": "^29.4.3", - "eslint-import-resolver-typescript": "^3.5.3", - "eslint-plugin-import": "^2.27.5", - "jest-puppeteer": "^6.2.0", + "babel-jest": "^29.7.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.0", + "husky": "^8.0.3", + "lint-staged": "^15.1.0", "prettier": "^3.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "stylelint": "^14.16.1", "typescript": "^5.3.2" } }, @@ -66,18 +65,18 @@ } }, "node_modules/@ariakit/core": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.3.4.tgz", - "integrity": "sha512-mMTWYOs0SvkrBbLPy4IY15E+fgvSbZKg4XzpBwE17meBG+G7wJjnuHq8lNiIAn9VnQBIc/lsXxqH3FCD7hHaUg==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.3.6.tgz", + "integrity": "sha512-Mh+goslCo4XhjLnruhuU8kg8IyR+frEVDgKXXTmj1KqnZpi7CQH/NEc5/SHZhukQhVzc8xogc5r8x+HJNdoMOw==", "dev": true }, "node_modules/@ariakit/react": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.3.5.tgz", - "integrity": "sha512-x7LfGP0on0lVV1NcDNO8+aEBb64sUI6YYB1akEWXkb4lTiU4uG1sHGc8YhfHVh0cFS1kwpQcqyiNPzyB8OgymA==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.3.7.tgz", + "integrity": "sha512-Rb8tn6Rb8zVbUdwfkf7+tSOFY59woosFgCgMHIalLceBlkcB8mOlq6pfowDSSuvFa+VPAIdLe89MXvFr8AJqtQ==", "dev": true, "dependencies": { - "@ariakit/react-core": "0.3.5" + "@ariakit/react-core": "0.3.7" }, "funding": { "type": "opencollective", @@ -89,12 +88,12 @@ } }, "node_modules/@ariakit/react-core": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.3.5.tgz", - "integrity": "sha512-TdQmUj7BPJ7QWjpjlpP5M1YbANDQL/voYYvKq1Hele7uoEWk51v2nZNaNXo9DZ4He/bkG99ISDx5Tgkzi5En8Q==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.3.7.tgz", + "integrity": "sha512-Z2bICFdYL+Bu2FSUDdBWvzzKyFj1TRMTIsPrUskpJio6EtPtxUE/2E3fPDWvfevsTA3n8kYP2CLODsPpNeAGjw==", "dev": true, "dependencies": { - "@ariakit/core": "0.3.4", + "@ariakit/core": "0.3.6", "@floating-ui/dom": "^1.0.0", "use-sync-external-store": "^1.2.0" }, @@ -103,25 +102,10 @@ "react-dom": "^17.0.0 || ^18.0.0" } }, - "node_modules/@axe-core/puppeteer": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@axe-core/puppeteer/-/puppeteer-4.8.1.tgz", - "integrity": "sha512-1gAeYS/wWlEBtRkJQ0E3PqB7cvF/aMb2rAbJBfzDox0fBcYZpPS3Q5aJE6U+DnRXy5JADMHPI69YSJx3Vdlj8g==", - "dev": true, - "dependencies": { - "axe-core": "~4.8.2" - }, - "engines": { - "node": ">=6.4.0" - }, - "peerDependencies": { - "puppeteer": ">=1.10.0" - } - }, "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { "@babel/highlight": "^7.23.4", @@ -141,21 +125,21 @@ } }, "node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -198,12 +182,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", - "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "dev": true, "dependencies": { - "@babel/types": "^7.23.4", + "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -518,14 +502,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", - "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.4", - "@babel/types": "^7.23.4" + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" }, "engines": { "node": ">=6.9.0" @@ -546,9 +530,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", - "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1964,19 +1948,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", - "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.23.4", - "@babel/generator": "^7.23.4", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", "@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.4", - "@babel/types": "^7.23.4", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1985,9 +1969,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", - "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -2310,9 +2294,9 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", - "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.1.tgz", + "integrity": "sha512-QgcKYwzcc8vvZ4n/5uklchy8KVdjJwcOeI+HnnTNclJjs2nYsy23DOCf+sSV1kBwD9yDAoVKCkv/gEPzgQU3Pw==", "dev": true, "dependencies": { "@floating-ui/utils": "^0.1.3" @@ -3472,47 +3456,6 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@puppeteer/browsers": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.8.0.tgz", - "integrity": "sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==", - "dev": true, - "dependencies": { - "debug": "4.3.4", - "extract-zip": "2.0.1", - "progress": "2.0.3", - "proxy-agent": "6.3.1", - "tar-fs": "3.0.4", - "unbzip2-stream": "1.4.3", - "yargs": "17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=16.3.0" - } - }, - "node_modules/@puppeteer/browsers/node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, "node_modules/@radix-ui/primitive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", @@ -4729,9 +4672,9 @@ } }, "node_modules/@types/babel__core": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.4.tgz", - "integrity": "sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", @@ -4845,25 +4788,6 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "node_modules/@types/expect-puppeteer": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/expect-puppeteer/-/expect-puppeteer-5.0.6.tgz", - "integrity": "sha512-71TRn11EozNfUYredjmVRuwtVnk0ZJIUmUcJhpMr0ffQ9M32RNUgz/w0G4nfgcAx9GAuBQhJ0lBZxLbkj+eZkA==", - "dev": true, - "dependencies": { - "@types/jest": "*", - "@types/puppeteer": "^5.4.0" - } - }, - "node_modules/@types/expect-puppeteer/node_modules/@types/puppeteer": { - "version": "5.4.7", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.7.tgz", - "integrity": "sha512-JdGWZZYL0vKapXF4oQTC5hLVNfOgdPrqeZ1BiQnGk5cB7HeE91EWUiTdVSdQPobRN8rIcdffjiOgCYJ/S8QrnQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -4965,130 +4889,15 @@ } }, "node_modules/@types/jest": { - "version": "29.5.8", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.8.tgz", - "integrity": "sha512-fXEFTxMV2Co8ZF5aYFJv+YeA08RTYJfhtN5c9JSv/mFEMe+xxjufCb+PHL+bJcMs/ebPUsBu+UNTEz+ydXrR6g==", + "version": "29.5.10", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.10.tgz", + "integrity": "sha512-tE4yxKEphEyxj9s4inideLHktW/x6DwesIwWZ9NN1FKf9zbJYsnhBoA9vrHA/IuIOKwPa5PcFBNV4lpMIOEzyQ==", "dev": true, "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, - "node_modules/@types/jest-environment-puppeteer": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/jest-environment-puppeteer/-/jest-environment-puppeteer-5.0.6.tgz", - "integrity": "sha512-MAi9ey7sIRl0ddWsN3jaQQwC41eBfYghE6TKnJNbEXKxw1X6nF6TBCZA+DbQ+KDOb9e2BjUtiWWMZbgjhlTneg==", - "dev": true, - "dependencies": { - "@jest/types": ">=24 <=27", - "@types/puppeteer": "^5.4.0", - "jest-environment-node": ">=24 <=27" - } - }, - "node_modules/@types/jest-environment-puppeteer/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@types/jest-environment-puppeteer/node_modules/@types/puppeteer": { - "version": "5.4.7", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.7.tgz", - "integrity": "sha512-JdGWZZYL0vKapXF4oQTC5hLVNfOgdPrqeZ1BiQnGk5cB7HeE91EWUiTdVSdQPobRN8rIcdffjiOgCYJ/S8QrnQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/jest-environment-puppeteer/node_modules/@types/yargs": { - "version": "16.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.8.tgz", - "integrity": "sha512-1GwLEkmFafeb/HbE6pC7tFlgYSQ4Iqh2qlWCq8xN+Qfaiaxr2PcLfuhfRFRYqI6XJyeFoLYyKnhFbNsst9FMtQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/jest-environment-puppeteer/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/@types/jest-environment-puppeteer/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/@types/jest-environment-puppeteer/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/@types/jest-environment-puppeteer/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/@types/jest-environment-puppeteer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/jest-environment-puppeteer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@types/jsdom": { "version": "20.0.1", "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", @@ -5146,9 +4955,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.18.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.10.tgz", - "integrity": "sha512-luANqZxPmjTll8bduz4ACs/lNTCLuWssCyjqTY9yLdsv1xnViQp3ISKwsEWOIecO13JWUqjVdig/Vjjc09o8uA==", + "version": "18.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.1.tgz", + "integrity": "sha512-mZJ9V11gG5Vp0Ox2oERpeFDl+JvCwK24PGy76vVY/UgBtjwJWc5rYBThFxmbnYOm9UPZNm6wEl/sxHt2SU7x9A==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -5181,16 +4990,6 @@ "integrity": "sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==", "dev": true }, - "node_modules/@types/puppeteer": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-7.0.4.tgz", - "integrity": "sha512-ja78vquZc8y+GM2al07GZqWDKQskQXygCDiu0e3uO0DMRKqE0MjrFBFmTulfPYzLB6WnL7Kl2tFPy0WXSpPomg==", - "deprecated": "This is a stub types definition. puppeteer provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "puppeteer": "*" - } - }, "node_modules/@types/qs": { "version": "6.9.10", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", @@ -5245,9 +5044,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.5.tgz", - "integrity": "sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, "node_modules/@types/send": { @@ -5396,9 +5195,9 @@ } }, "node_modules/@types/wordpress__blocks": { - "version": "12.5.9", - "resolved": "https://registry.npmjs.org/@types/wordpress__blocks/-/wordpress__blocks-12.5.9.tgz", - "integrity": "sha512-htrqAFaib/k+7CXYjkzaWzvX/K8PqapC8VeQZRaB59Y74tEWYbQvomC/wwJXUYP7zN+o48MFVY4HOiYIIJNGTA==", + "version": "12.5.11", + "resolved": "https://registry.npmjs.org/@types/wordpress__blocks/-/wordpress__blocks-12.5.11.tgz", + "integrity": "sha512-VIQ5Ot/r9CK1h5SFTxjqJIQEsuULDF0nnvsFnKqE8ipdfvvoUmHqI1Vv8Pdfy8HubhMYP0HtiPgBCFKiUF9y3g==", "dev": true, "dependencies": { "@types/react": "*", @@ -5409,9 +5208,9 @@ } }, "node_modules/@types/wordpress__components": { - "version": "23.0.7", - "resolved": "https://registry.npmjs.org/@types/wordpress__components/-/wordpress__components-23.0.7.tgz", - "integrity": "sha512-zGm9YNyfyeHo3RkyTmkSRdjQDQsVR+yWsA8m3eOQuU8w/TNnv/1li/GramYEqQsePWiEI6Cq/6omdCjw8GgfPQ==", + "version": "23.0.8", + "resolved": "https://registry.npmjs.org/@types/wordpress__components/-/wordpress__components-23.0.8.tgz", + "integrity": "sha512-s6gGtSIIlXCh1w0Ja0Q0ppekN5N438lz0AT8IdLVMMmwDR3/gV3yOiDzmQNeAMYAPVqwge0mfS/sAOCgwZVt4Q==", "dev": true, "dependencies": { "@types/react": "*", @@ -5423,16 +5222,6 @@ "re-resizable": "^6.4.0" } }, - "node_modules/@types/wordpress__compose": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/wordpress__compose/-/wordpress__compose-6.1.0.tgz", - "integrity": "sha512-b6+IeFRBGxdzQDU0sTKwlPInJEakWzKU59oua899xWzPOPI9hLTGofhQMSJegq3JVe/6r7TIboIOxCFK7w7csw==", - "deprecated": "This is a stub types definition. @wordpress/compose provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "@wordpress/compose": "*" - } - }, "node_modules/@types/wordpress__keycodes": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/@types/wordpress__keycodes/-/wordpress__keycodes-2.3.3.tgz", @@ -5500,32 +5289,33 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.1.tgz", + "integrity": "sha512-5bQDGkXaxD46bPvQt08BUz9YSaO4S0fB1LB5JHQuXTfkGPI3+UUeS387C/e9jRie5GqT8u5kFTrMvAjtX4O5kA==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/type-utils": "6.13.1", + "@typescript-eslint/utils": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -5567,25 +5357,26 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.1.tgz", + "integrity": "sha512-fs2XOhWCzRhqMmQf0eicLa/CWSaYss2feXsy7xBD/pLyWke/jCIVc2s1ikEAtSW7ina1HNhv7kONoEfVNEcdDQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/typescript-estree": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -5594,16 +5385,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.1.tgz", + "integrity": "sha512-BW0kJ7ceiKi56GbT2KKzZzN+nDxzQK2DS6x0PiSMPjciPgd/JRQGMibyaN2cPt2cAvuoH0oNvn2fwonHI+4QUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -5611,25 +5402,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.1.tgz", + "integrity": "sha512-A2qPlgpxx2v//3meMqQyB1qqTg1h1dJvzca7TugM3Yc2USDY+fsRBiojAEo92HO7f5hW5mjAUF6qobOPzlBCBQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", + "@typescript-eslint/typescript-estree": "6.13.1", + "@typescript-eslint/utils": "6.13.1", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -5638,12 +5429,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.1.tgz", + "integrity": "sha512-gjeEskSmiEKKFIbnhDXUyiqVma1gRCQNbVZ1C8q7Zjcxh3WZMbzWVfGE9rHfWd1msQtPS0BVD9Jz9jded44eKg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -5651,21 +5442,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.1.tgz", + "integrity": "sha512-sBLQsvOC0Q7LGcUHO5qpG1HxRgePbT6wwqOiGLpR8uOJvPJbfs0mW3jPA3ujsDvfiVwVlWUDESNXv44KtINkUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/visitor-keys": "6.13.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -5711,29 +5502,28 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.1.tgz", + "integrity": "sha512-ouPn/zVoan92JgAegesTXDB/oUp6BP1v8WpfYcqh649ejNc9Qv+B4FF2Ff626kO1xg0wWwwG48lAJ4JuesgdOw==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.13.1", + "@typescript-eslint/types": "6.13.1", + "@typescript-eslint/typescript-estree": "6.13.1", + "semver": "^7.5.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { @@ -5770,16 +5560,16 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.1.tgz", + "integrity": "sha512-NDhQUy2tg6XGNBGDRm1XybOHSia8mcXmlbKWoQP+nm1BIIMxa55shyJfZkHpEBN62KNPLrocSM2PdPcaLgDKMQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.13.1", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -6001,37 +5791,37 @@ } }, "node_modules/@wordpress/a11y": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-3.46.0.tgz", - "integrity": "sha512-ixblk5YMbouTPonALm+NxvLE2rk/KwIBNlAoz0kFhk+PTdg05FKD2P891S5BeWBFIbshI0rdPA2OR+wForcilQ==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-3.47.0.tgz", + "integrity": "sha512-4Tnv0D2vJictPtg9nrga0iuliOUSxRrnLYK9Q49CHN4AVr9hE30ndZwn4zy/MYh3K+Oz6YgLBlJrpvL62L0b5w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/dom-ready": "^3.46.0", - "@wordpress/i18n": "^4.46.0" + "@wordpress/dom-ready": "^3.47.0", + "@wordpress/i18n": "^4.47.0" }, "engines": { "node": ">=12" } }, "node_modules/@wordpress/api-fetch": { - "version": "6.43.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-6.43.0.tgz", - "integrity": "sha512-DYtawNaOHDxgIl+B/E1oU+VMhFJJfy/oYR5e7+PFUX0t0yHhHuH8XaWKpZvpvo0Y/GOuJ2NkDcJDqSZXD2TFYw==", + "version": "6.44.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-6.44.0.tgz", + "integrity": "sha512-d8ouvBiKDFu67O9Y8MtlUR2YojCAjmLf0LuBKsSOS5r3MOiwte1tQwsLdzFmGYkdCK09mZhT3UVKdOOiAC3kKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^4.46.0", - "@wordpress/url": "^3.47.0" + "@wordpress/i18n": "^4.47.0", + "@wordpress/url": "^3.48.0" }, "engines": { "node": ">=12" } }, "node_modules/@wordpress/autop": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-3.46.0.tgz", - "integrity": "sha512-3sgXHWrbrsXY2nalkJYmJ+JxyfM6RQ5cCymqcs0KyIL+WNOVyxfbgiGsjL0HQjQLMlHdQoWT081rZLPEbJvodw==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-3.47.0.tgz", + "integrity": "sha512-fd9ubAnC5LWYBWv4OS6OOCjBJwDgpQU1Q2hbV5d4oxWh7mq5SiLEaR8OvyElI5+Yl3snYWNE9QHPX19VTlosLQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -6041,9 +5831,9 @@ } }, "node_modules/@wordpress/babel-plugin-import-jsx-pragma": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-4.29.0.tgz", - "integrity": "sha512-VPAn1iVZae1sQ6QaiMKbp3AzFPbhBl6YQeDr3AKpj24GTiUmsho6WgxijzyhBEBX5xPHVCahhQ8mjiZ5Ql6FwA==", + "version": "4.30.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-4.30.0.tgz", + "integrity": "sha512-UKkyFmEYk1UTO0ZPun6Kw5dNflTEDpDK/6RxAqxbVrsIWUVSkVahwBnqfS0v5LuvVU8y+5vJSR/WjlnKEmS3Sg==", "dev": true, "engines": { "node": ">=14" @@ -6053,9 +5843,9 @@ } }, "node_modules/@wordpress/babel-plugin-makepot": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-makepot/-/babel-plugin-makepot-5.30.0.tgz", - "integrity": "sha512-tKMNUU9X2kG1oP0utzb6Q96KLKtNTLAfQo1xL18vXRl0iwj3/0FtLTML1h+q80Knykwhu4joXSi2UWgt6b2wMA==", + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-makepot/-/babel-plugin-makepot-5.31.0.tgz", + "integrity": "sha512-Kem2/bhcRlVbTOKoP/2fL7NiZivydG2hNWu0s/Sg0IUl2WYIocdidxCmdbxoyEn3WJ4gxAOneHgvYGgsmNVgOw==", "dev": true, "dependencies": { "deepmerge": "^4.3.0", @@ -6070,9 +5860,9 @@ } }, "node_modules/@wordpress/babel-preset-default": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-7.30.0.tgz", - "integrity": "sha512-O/IA8Jvh6MzlTyeo0As2chhZ2w6WdvMYSjjTDDC66SkbnUxUf4jWqehncHGrtQLoQJfwsCUnyWSH4ePb/j+kIw==", + "version": "7.31.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-7.31.0.tgz", + "integrity": "sha512-LAiTOlolFvKW6xmL6qRkdbPG09LPwAsmDepz4zWrFXJZHSImDeO2QXHecF1GnFyzLLKr1myHR5MbN3K5MSzpqQ==", "dev": true, "dependencies": { "@babel/core": "^7.16.0", @@ -6081,9 +5871,9 @@ "@babel/preset-env": "^7.16.0", "@babel/preset-typescript": "^7.16.0", "@babel/runtime": "^7.16.0", - "@wordpress/babel-plugin-import-jsx-pragma": "^4.29.0", - "@wordpress/browserslist-config": "^5.29.0", - "@wordpress/warning": "^2.46.0", + "@wordpress/babel-plugin-import-jsx-pragma": "^4.30.0", + "@wordpress/browserslist-config": "^5.30.0", + "@wordpress/warning": "^2.47.0", "browserslist": "^4.21.10", "core-js": "^3.31.0", "react": "^18.2.0" @@ -6093,15 +5883,15 @@ } }, "node_modules/@wordpress/base-styles": { - "version": "4.37.0", - "resolved": "https://registry.npmjs.org/@wordpress/base-styles/-/base-styles-4.37.0.tgz", - "integrity": "sha512-HxYlZHHpq0XDd+/ixTjB0g2smw8NIhal0gZgKJsQSPra/TN5Swjt0e3QwW3MBGZKWhV9poNmsBGNZonVCe9bSA==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@wordpress/base-styles/-/base-styles-4.38.0.tgz", + "integrity": "sha512-w491MMHfoCHdWibyTAcmGWvXwNMptslFQOU+jQ5DVeDIgDux1KLo/7oZ41CCHwqYayrCf60BC9+JopDXqq1H+g==", "dev": true }, "node_modules/@wordpress/blob": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-3.46.0.tgz", - "integrity": "sha512-yWGes81l58SFeQ1/3tzKOjEutmwtQyBdtWpFyyg1vJC89WfENub7JM2yYRJZ/cpdu/7qMQY88TvVhH7MX5WRSA==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-3.47.0.tgz", + "integrity": "sha512-ABwo431Kr1MuipU3mmNbujRToicZAmpIW9hED/3T0NEmtcvKFjVhzYmSFRm9v1VuEbLjBdX7N5pI6Jm//Iq71w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -6111,44 +5901,44 @@ } }, "node_modules/@wordpress/block-editor": { - "version": "12.14.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-12.14.0.tgz", - "integrity": "sha512-xgfluTjTZB8nWRoN2Xob+taFiKZQ1TPzm2cPGXn8Srg2LkWPd2f+ln13YdTB6OZ3TIyulyMxGb3Q8duhXiBzZw==", + "version": "12.15.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-12.15.0.tgz", + "integrity": "sha512-B/wFN9LFBrbrqE4qQ5lr8fqAQ6U43zrlacmdLg1LDP57/o0o5EPo+1ylJ4JyvjVxULTCNM8yTuV7QvFi9fdh5w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", "@react-spring/web": "^9.4.5", - "@wordpress/a11y": "^3.46.0", - "@wordpress/api-fetch": "^6.43.0", - "@wordpress/blob": "^3.46.0", - "@wordpress/blocks": "^12.23.0", - "@wordpress/commands": "^0.17.0", - "@wordpress/components": "^25.12.0", - "@wordpress/compose": "^6.23.0", - "@wordpress/data": "^9.16.0", - "@wordpress/date": "^4.46.0", - "@wordpress/deprecated": "^3.46.0", - "@wordpress/dom": "^3.46.0", - "@wordpress/element": "^5.23.0", - "@wordpress/escape-html": "^2.46.0", - "@wordpress/hooks": "^3.46.0", - "@wordpress/html-entities": "^3.46.0", - "@wordpress/i18n": "^4.46.0", - "@wordpress/icons": "^9.37.0", - "@wordpress/is-shallow-equal": "^4.46.0", - "@wordpress/keyboard-shortcuts": "^4.23.0", - "@wordpress/keycodes": "^3.46.0", - "@wordpress/notices": "^4.14.0", - "@wordpress/preferences": "^3.23.0", - "@wordpress/private-apis": "^0.28.0", - "@wordpress/rich-text": "^6.23.0", - "@wordpress/style-engine": "^1.29.0", - "@wordpress/token-list": "^2.46.0", - "@wordpress/url": "^3.47.0", - "@wordpress/warning": "^2.46.0", - "@wordpress/wordcount": "^3.46.0", + "@wordpress/a11y": "^3.47.0", + "@wordpress/api-fetch": "^6.44.0", + "@wordpress/blob": "^3.47.0", + "@wordpress/blocks": "^12.24.0", + "@wordpress/commands": "^0.18.0", + "@wordpress/components": "^25.13.0", + "@wordpress/compose": "^6.24.0", + "@wordpress/data": "^9.17.0", + "@wordpress/date": "^4.47.0", + "@wordpress/deprecated": "^3.47.0", + "@wordpress/dom": "^3.47.0", + "@wordpress/element": "^5.24.0", + "@wordpress/escape-html": "^2.47.0", + "@wordpress/hooks": "^3.47.0", + "@wordpress/html-entities": "^3.47.0", + "@wordpress/i18n": "^4.47.0", + "@wordpress/icons": "^9.38.0", + "@wordpress/is-shallow-equal": "^4.47.0", + "@wordpress/keyboard-shortcuts": "^4.24.0", + "@wordpress/keycodes": "^3.47.0", + "@wordpress/notices": "^4.15.0", + "@wordpress/preferences": "^3.24.0", + "@wordpress/private-apis": "^0.29.0", + "@wordpress/rich-text": "^6.24.0", + "@wordpress/style-engine": "^1.30.0", + "@wordpress/token-list": "^2.47.0", + "@wordpress/url": "^3.48.0", + "@wordpress/warning": "^2.47.0", + "@wordpress/wordcount": "^3.47.0", "change-case": "^4.1.2", "classnames": "^2.3.1", "colord": "^2.7.0", @@ -6174,9 +5964,9 @@ } }, "node_modules/@wordpress/block-serialization-default-parser": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-4.46.0.tgz", - "integrity": "sha512-XjCdpde6+oixrqDMO3l6QjB5s7NCTyAVGf3W5iZ0PE7DmbI5xsl4G9AdhHUY05vEQQsDRY3pf1Bo3tN3TY3bNA==", + "version": "4.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-4.47.0.tgz", + "integrity": "sha512-4y8Gb+m1CDNlfflbpxrFPHeug94NFQABlbFOJZfo2/XOzMuG31mijskk8H1SlTrqwVgoUs6rejFEMXKagdcI0w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -6186,29 +5976,28 @@ } }, "node_modules/@wordpress/blocks": { - "version": "12.23.0", - "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-12.23.0.tgz", - "integrity": "sha512-V/3+VHCSbOIi6ltYhaKOOQes2FuvtbCdOoyaFHqSPuZmD4sYOZVtbjKcbEXbe7fE7lx9pRs0KFQTZrD7GmVRvQ==", + "version": "12.24.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-12.24.0.tgz", + "integrity": "sha512-zPZLLLNr9DPuctS1J/HGYi9MeA1roIIAJlWMlBGmRdAcRSm1LuEHqX9k0pktVzL0QWDd4n7sJIDV0zR+vxPnww==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/autop": "^3.46.0", - "@wordpress/blob": "^3.46.0", - "@wordpress/block-serialization-default-parser": "^4.46.0", - "@wordpress/compose": "^6.23.0", - "@wordpress/data": "^9.16.0", - "@wordpress/deprecated": "^3.46.0", - "@wordpress/dom": "^3.46.0", - "@wordpress/element": "^5.23.0", - "@wordpress/hooks": "^3.46.0", - "@wordpress/html-entities": "^3.46.0", - "@wordpress/i18n": "^4.46.0", - "@wordpress/is-shallow-equal": "^4.46.0", - "@wordpress/private-apis": "^0.28.0", - "@wordpress/shortcode": "^3.46.0", + "@wordpress/autop": "^3.47.0", + "@wordpress/blob": "^3.47.0", + "@wordpress/block-serialization-default-parser": "^4.47.0", + "@wordpress/compose": "^6.24.0", + "@wordpress/data": "^9.17.0", + "@wordpress/deprecated": "^3.47.0", + "@wordpress/dom": "^3.47.0", + "@wordpress/element": "^5.24.0", + "@wordpress/hooks": "^3.47.0", + "@wordpress/html-entities": "^3.47.0", + "@wordpress/i18n": "^4.47.0", + "@wordpress/is-shallow-equal": "^4.47.0", + "@wordpress/private-apis": "^0.29.0", + "@wordpress/shortcode": "^3.47.0", "change-case": "^4.1.2", "colord": "^2.7.0", - "deepmerge": "^4.3.0", "fast-deep-equal": "^3.1.3", "hpq": "^1.3.0", "is-plain-object": "^5.0.0", @@ -6227,28 +6016,28 @@ } }, "node_modules/@wordpress/browserslist-config": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-5.29.0.tgz", - "integrity": "sha512-sVDgPWcI3wdKd3cIvgf/NLO7HtEkwyV4bWuSztzoemNMGQW17BhH2Blx46HnJFXm9ooYw4SpAOyioHTkuT+JFg==", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-5.30.0.tgz", + "integrity": "sha512-HFgLCkvvxba+j7/qNjVn1od38tvMm1xVlIJBR+zukkTvvLu/AkdelWKAQpvAoFAXMaZJ7239VxDVBYbVolf6FQ==", "dev": true, "engines": { "node": ">=14" } }, "node_modules/@wordpress/commands": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-0.17.0.tgz", - "integrity": "sha512-wTCwfUN0epKGqLPKrbv0B1Y/dcAvoXGfuPJm6KOKrwEx2na8cAEKN63nTL0d81z+XpdPagQVTNAkVAoSBngLjw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-0.18.0.tgz", + "integrity": "sha512-qJyAz2WtpRcJIKWtdkI5wWAnjx5aU9NdsZNW59xf9k9Uh3N1+1dvfFl3FJpR3pGCJv3dmuyFaWXJNYXqswXj/w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/components": "^25.12.0", - "@wordpress/data": "^9.16.0", - "@wordpress/element": "^5.23.0", - "@wordpress/i18n": "^4.46.0", - "@wordpress/icons": "^9.37.0", - "@wordpress/keyboard-shortcuts": "^4.23.0", - "@wordpress/private-apis": "^0.28.0", + "@wordpress/components": "^25.13.0", + "@wordpress/data": "^9.17.0", + "@wordpress/element": "^5.24.0", + "@wordpress/i18n": "^4.47.0", + "@wordpress/icons": "^9.38.0", + "@wordpress/keyboard-shortcuts": "^4.24.0", + "@wordpress/private-apis": "^0.29.0", "classnames": "^2.3.1", "cmdk": "^0.2.0", "rememo": "^4.0.2" @@ -6262,9 +6051,9 @@ } }, "node_modules/@wordpress/components": { - "version": "25.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-25.12.0.tgz", - "integrity": "sha512-jWh71SsIwTVCbOiL5tYscI8zvTUhKMfnmpgF/WfPpEBU9Bgx4dqlWSYDCZOTAyn89GJPfn95+e+wW13H0qPQ1Q==", + "version": "25.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-25.13.0.tgz", + "integrity": "sha512-Ym/5Xv7NnkJu40jCSmt/t6B8vT2ue2vobwDEz1FKlB0xGm5bzzh5589m2nZqqY459/Qm9dl5R4BKSdvKqKB2MQ==", "dev": true, "dependencies": { "@ariakit/react": "^0.3.5", @@ -6280,23 +6069,23 @@ "@types/gradient-parser": "0.1.3", "@types/highlight-words-core": "1.2.1", "@use-gesture/react": "^10.2.24", - "@wordpress/a11y": "^3.46.0", - "@wordpress/compose": "^6.23.0", - "@wordpress/date": "^4.46.0", - "@wordpress/deprecated": "^3.46.0", - "@wordpress/dom": "^3.46.0", - "@wordpress/element": "^5.23.0", - "@wordpress/escape-html": "^2.46.0", - "@wordpress/hooks": "^3.46.0", - "@wordpress/html-entities": "^3.46.0", - "@wordpress/i18n": "^4.46.0", - "@wordpress/icons": "^9.37.0", - "@wordpress/is-shallow-equal": "^4.46.0", - "@wordpress/keycodes": "^3.46.0", - "@wordpress/primitives": "^3.44.0", - "@wordpress/private-apis": "^0.28.0", - "@wordpress/rich-text": "^6.23.0", - "@wordpress/warning": "^2.46.0", + "@wordpress/a11y": "^3.47.0", + "@wordpress/compose": "^6.24.0", + "@wordpress/date": "^4.47.0", + "@wordpress/deprecated": "^3.47.0", + "@wordpress/dom": "^3.47.0", + "@wordpress/element": "^5.24.0", + "@wordpress/escape-html": "^2.47.0", + "@wordpress/hooks": "^3.47.0", + "@wordpress/html-entities": "^3.47.0", + "@wordpress/i18n": "^4.47.0", + "@wordpress/icons": "^9.38.0", + "@wordpress/is-shallow-equal": "^4.47.0", + "@wordpress/keycodes": "^3.47.0", + "@wordpress/primitives": "^3.45.0", + "@wordpress/private-apis": "^0.29.0", + "@wordpress/rich-text": "^6.24.0", + "@wordpress/warning": "^2.47.0", "change-case": "^4.1.2", "classnames": "^2.3.1", "colord": "^2.7.0", @@ -6328,20 +6117,20 @@ } }, "node_modules/@wordpress/compose": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-6.23.0.tgz", - "integrity": "sha512-MMWwYkbmA4IkdZQ/p3BMvgD9MvCGK2lJd8PjnftDw6NjRteXyA6CQjP1h+/mTlNJvHytqRu2cNPey0V0mnRx6A==", + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-6.24.0.tgz", + "integrity": "sha512-aO0HWi12Y7Do5hyGEOXcRtRTIn7P/t4RrHYMTsHvufCrt6ZCLKvY2vBEaDA8XnWFQZ/Tzo4fBAnxAAxDt1DtEw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^3.46.0", - "@wordpress/dom": "^3.46.0", - "@wordpress/element": "^5.23.0", - "@wordpress/is-shallow-equal": "^4.46.0", - "@wordpress/keycodes": "^3.46.0", - "@wordpress/priority-queue": "^2.46.0", - "@wordpress/undo-manager": "^0.6.0", + "@wordpress/deprecated": "^3.47.0", + "@wordpress/dom": "^3.47.0", + "@wordpress/element": "^5.24.0", + "@wordpress/is-shallow-equal": "^4.47.0", + "@wordpress/keycodes": "^3.47.0", + "@wordpress/priority-queue": "^2.47.0", + "@wordpress/undo-manager": "^0.7.0", "change-case": "^4.1.2", "clipboard": "^2.0.8", "mousetrap": "^1.6.5", @@ -6355,19 +6144,19 @@ } }, "node_modules/@wordpress/data": { - "version": "9.16.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-9.16.0.tgz", - "integrity": "sha512-FEfHR5wlbtqssSVzey45Yq9+sFaFxiKZrY6MInkOVY7B/GtdSDpKDioDdTgmHKOnyaal4l1KHAE0bVEoMLfaFQ==", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-9.17.0.tgz", + "integrity": "sha512-0FfNL4mHMkX8cBbGAjP8EJ/RGOvf/74qyhBXiLEGUz6swhW6RFrSPm7Dkqe5cMRqXDGoJn15OsOFIuLRllwVoQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^6.23.0", - "@wordpress/deprecated": "^3.46.0", - "@wordpress/element": "^5.23.0", - "@wordpress/is-shallow-equal": "^4.46.0", - "@wordpress/priority-queue": "^2.46.0", - "@wordpress/private-apis": "^0.28.0", - "@wordpress/redux-routine": "^4.46.0", + "@wordpress/compose": "^6.24.0", + "@wordpress/deprecated": "^3.47.0", + "@wordpress/element": "^5.24.0", + "@wordpress/is-shallow-equal": "^4.47.0", + "@wordpress/priority-queue": "^2.47.0", + "@wordpress/private-apis": "^0.29.0", + "@wordpress/redux-routine": "^4.47.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -6384,13 +6173,13 @@ } }, "node_modules/@wordpress/date": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-4.46.0.tgz", - "integrity": "sha512-IsbAXOVYJfSVISGppERnZMWVvvCo07bjSXSKhbd6CDgzTFDPCyUrOmv8tcMUdHw7a4jbL0w/KRMqdhN/C8A0JQ==", + "version": "4.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-4.47.0.tgz", + "integrity": "sha512-HIruX+wMaQWKYLCFIu6JeEEoqRYkhpL4cWfZ1lJG78wNsgq3vRiHzXQaXHcbmJQCq0PZOxtmeSzldPiUMFVNpg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^3.46.0", + "@wordpress/deprecated": "^3.47.0", "moment": "^2.29.4", "moment-timezone": "^0.5.40" }, @@ -6399,9 +6188,9 @@ } }, "node_modules/@wordpress/dependency-extraction-webpack-plugin": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-4.29.0.tgz", - "integrity": "sha512-cYvTkjDvxpZSEjM1RRNciK/7W+RXC+qXXzbdRyGhkE0AzIspA7UAV3NoEyjtbL2V2wNJmBmsZKJf0wuYandDQA==", + "version": "4.30.0", + "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-4.30.0.tgz", + "integrity": "sha512-Z3AcceaoHFvJdRNVp8rf6EI+rxK0gUMGMfcXYZPAoaDhP6Gt0bsbVMP5zQH2EYl7JHsbRZIQmMqd2fG5E/VjSQ==", "dev": true, "dependencies": { "json2php": "^0.0.7", @@ -6415,35 +6204,35 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-3.46.0.tgz", - "integrity": "sha512-i7stkwWr9vUc2A9ILb0qIUfqtyjaG9yNbqRcfWDjqhOn6R4Drm4edwdpZKdYHSTiiH2qPCWZGTc6KVZm5wc9/Q==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-3.47.0.tgz", + "integrity": "sha512-Vq4h6LHGPUc/pqmLOANcPpiMrOVoTeZRDvKxE+ioR9ldEFo+uquMKrEmJZxXVXl0GZdMKQ4jGKx34z8S8VRwQw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^3.46.0" + "@wordpress/hooks": "^3.47.0" }, "engines": { "node": ">=12" } }, "node_modules/@wordpress/dom": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-3.46.0.tgz", - "integrity": "sha512-NiGBTpE7lzTAjkxw5HVp3EzyMxZA378/yed0id0krvEId4prmbIJWRwSNC+Yvn0nhuHczIl4wj9T9zYpksAcUg==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-3.47.0.tgz", + "integrity": "sha512-SY6wfAc4yrXYil8fm/uyeKQnPjGuc0G9Q1/5pUKO6dssst8fClsrxy+hXNl0FYFGWnAZBqg5ccrwYydrFt5k/g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^3.46.0" + "@wordpress/deprecated": "^3.47.0" }, "engines": { "node": ">=12" } }, "node_modules/@wordpress/dom-ready": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-3.46.0.tgz", - "integrity": "sha512-Xq/TPuOZk1DjBzuo4fPj226Lo8uoKk0v1Tydnb263gRmAniSXdwEyrLPMbo8DOAqEUPI9ZRbqomJo/mBR2V8TA==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-3.47.0.tgz", + "integrity": "sha512-VsqaTQJ5Z7Qa3Doi5qk4LMnW0K78JEKLYRcg3ohapgBrQ2tKTS67oWgJx2VgWz8ky6j9UosecSISP3zJHXfEeA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -6452,37 +6241,15 @@ "node": ">=12" } }, - "node_modules/@wordpress/e2e-test-utils": { - "version": "10.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils/-/e2e-test-utils-10.17.0.tgz", - "integrity": "sha512-oTotVb9P9zxcYd5Iqt3froS9R/7VjOVC33a2WjTsV/1+hKb/n6lF6J00JCCrz1Fp+zONsjZK68Zb/cL1i+akvA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/api-fetch": "^6.43.0", - "@wordpress/keycodes": "^3.46.0", - "@wordpress/url": "^3.47.0", - "change-case": "^4.1.2", - "form-data": "^4.0.0", - "node-fetch": "^2.6.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "jest": ">=29", - "puppeteer-core": ">=11" - } - }, "node_modules/@wordpress/e2e-test-utils-playwright": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils-playwright/-/e2e-test-utils-playwright-0.14.0.tgz", - "integrity": "sha512-aeH6HhI67lfUTZ1miMhI/xq61JDd5yMFMN5wH24e1/1w7SItXZtCz306tht5h4HeqFeS6xzRwA8j6lM7PNdWQg==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils-playwright/-/e2e-test-utils-playwright-0.15.0.tgz", + "integrity": "sha512-ZqCYcxT0Gc59isS42Q7WTQVu3ace8DDEED/RR8loTG+YjqEB1pW5hALFiVXBtM6vSjnnDO0M1NYAldh8l7SCmA==", "dev": true, "dependencies": { - "@wordpress/api-fetch": "^6.43.0", - "@wordpress/keycodes": "^3.46.0", - "@wordpress/url": "^3.47.0", + "@wordpress/api-fetch": "^6.44.0", + "@wordpress/keycodes": "^3.47.0", + "@wordpress/url": "^3.48.0", "change-case": "^4.1.2", "form-data": "^4.0.0", "get-port": "^5.1.1", @@ -6497,115 +6264,16 @@ "@playwright/test": ">=1" } }, - "node_modules/@wordpress/e2e-tests": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/e2e-tests/-/e2e-tests-7.17.0.tgz", - "integrity": "sha512-4fyY1sy+NbpKSLyOFFc9LNjMY4i5L20H9arbcmFc1f2DBwRAt/QTxW7jOP3BZx3z/ysjFSYAAAiYiLdGzt4zYw==", - "dev": true, - "dependencies": { - "@wordpress/e2e-test-utils": "^10.17.0", - "@wordpress/jest-console": "^7.17.0", - "@wordpress/jest-puppeteer-axe": "^6.17.0", - "@wordpress/scripts": "^26.17.0", - "@wordpress/url": "^3.47.0", - "chalk": "^4.0.0", - "expect-puppeteer": "^4.4.0", - "filenamify": "^4.2.0", - "jest-message-util": "^29.6.2", - "jest-snapshot": "^29.6.2", - "puppeteer-testing-library": "^0.5.0", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "jest": ">=29", - "puppeteer-core": ">=11", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@wordpress/e2e-tests/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/@wordpress/e2e-tests/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/@wordpress/e2e-tests/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/@wordpress/e2e-tests/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/@wordpress/e2e-tests/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@wordpress/e2e-tests/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@wordpress/element": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-5.23.0.tgz", - "integrity": "sha512-6c1EG8UJDzJGX6yWJGIi78bgomWJ6rSkMRR9d0UBis9bm9YFBJDydsD9bNx6XItrMEXR7yykXblfGY2YUK3SAA==", + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-5.24.0.tgz", + "integrity": "sha512-El1E5jlZitrDouvde0dUF2yVRiPsxPnjxB9TU43EhahQ9eT8pwfUaH3I4NT8kUj2LD76WwU8fN7CEmBNBW+ofA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", - "@wordpress/escape-html": "^2.46.0", + "@wordpress/escape-html": "^2.47.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.2.0", @@ -6616,9 +6284,9 @@ } }, "node_modules/@wordpress/env": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-8.12.0.tgz", - "integrity": "sha512-AP4rvv9oEqNtAk1o+V/sDeSDuBnTrbAc1nGp2Q8KMgaxhNSnMB4gn5K6zggG5HF0GPWbR5YaFkID+2FvT0DPIw==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-8.13.0.tgz", + "integrity": "sha512-rtrrBO22DnbLsdBlsGqlMQrjz1dZfbwGnxyKev+gFd1rSfmLs+1F8L89RHOx9vsGPixl5uRwoU/qgYo7Hf1NVQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", @@ -6709,9 +6377,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "2.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-2.46.0.tgz", - "integrity": "sha512-sPjBUMTSqjDF1niqb6NnKim8Ju7zWVlgZoifO3cC+4DGZcRsKF78eTeuEojQJN7h/FHCjpKX3dvnr+ihv7syEQ==", + "version": "2.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-2.47.0.tgz", + "integrity": "sha512-bBGcTE5chneQJ3yETJyT2suyVtEJNfOiMVBV5qm606TyEzIDm18Sw2mPfOagiB1nOwDkAVfpSVD2NeGpit2alA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -6721,16 +6389,16 @@ } }, "node_modules/@wordpress/eslint-plugin": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-17.3.0.tgz", - "integrity": "sha512-u6ZMf8sL4act3bNuX0CTuu9quCBw68BItpb5gpyo7LGmV4+/cic14GVWPBTroA9oz6z5UHjIfjKMqib7NGecWQ==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-17.4.0.tgz", + "integrity": "sha512-CT19Ib1Y0ttVQm/bOtjGP6Ge5eqfEaUSobTqCWreHt1RIoxJXTDmazJ1g0Q5MjqG4dEZ/Q/FI4sdqyiKRySkbQ==", "dev": true, "dependencies": { "@babel/eslint-parser": "^7.16.0", "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", - "@wordpress/babel-preset-default": "^7.30.0", - "@wordpress/prettier-config": "^3.3.0", + "@wordpress/babel-preset-default": "^7.31.0", + "@wordpress/prettier-config": "^3.4.0", "cosmiconfig": "^7.0.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.2", @@ -6763,391 +6431,147 @@ } } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.12.0.tgz", - "integrity": "sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==", + "node_modules/@wordpress/eslint-plugin/node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/type-utils": "6.12.0", - "@typescript-eslint/utils": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "type-fest": "^0.20.2" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/parser": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.12.0.tgz", - "integrity": "sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==", + "node_modules/@wordpress/eslint-plugin/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/typescript-estree": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", - "debug": "^4.3.4" - }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.12.0.tgz", - "integrity": "sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==", + "node_modules/@wordpress/hooks": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.47.0.tgz", + "integrity": "sha512-a0mZ+lSUBrmacJGXDnFTaz1O47sQgTCZi3LrY445WNc7cmiSlscTfeBxrUXaTF0ninzHJnE7evCIeKLbQC3dLQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0" + "@babel/runtime": "^7.16.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=12" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/type-utils": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.12.0.tgz", - "integrity": "sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==", + "node_modules/@wordpress/html-entities": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-3.47.0.tgz", + "integrity": "sha512-3wGxzlTNFRnw80jv5ckREDTwNq8FCU+HqdbhwXZWjiIDv2J8GwH1sgD8VbMzlB1Bi9V/3yqteYtv0V/RpC2VfQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.12.0", - "@typescript-eslint/utils": "6.12.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "@babel/runtime": "^7.16.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=12" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.12.0.tgz", - "integrity": "sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==", + "node_modules/@wordpress/i18n": { + "version": "4.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.47.0.tgz", + "integrity": "sha512-7qOeSChhI8drcnKAbpM2yP2HSWRR0U8xvww3Febd3kGhMKAUp8AMpjyC4rWucak4+Eg1HFfahurCmBt3FxgbYQ==", "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/hooks": "^3.47.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.12.0.tgz", - "integrity": "sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==", + "node_modules/@wordpress/icons": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-9.38.0.tgz", + "integrity": "sha512-K+rSZM1eKuWh+rXeMWNLj4dT0a3RJSzoUUh9UDQZCSdnThyAyZECGEKfHSCfd28/yabxLKaziXrb5/MVBrPjZw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "@babel/runtime": "^7.16.0", + "@wordpress/element": "^5.24.0", + "@wordpress/primitives": "^3.45.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=12" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.12.0.tgz", - "integrity": "sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==", + "node_modules/@wordpress/is-shallow-equal": { + "version": "4.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.47.0.tgz", + "integrity": "sha512-mfrw/GXtCzm5jciuXumabfJhJLzGU0EpGgXU9tDHw6CwDrtUMcM05qrvrXFk4IlE2hYFwuTkWryValMt3FFdoQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/typescript-estree": "6.12.0", - "semver": "^7.5.4" + "@babel/runtime": "^7.16.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "node": ">=12" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.12.0.tgz", - "integrity": "sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==", + "node_modules/@wordpress/jest-console": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-7.18.0.tgz", + "integrity": "sha512-OjPGbU1HgjLVNCLW9ROmdkw/qhpFL6Svlfv1aUVBrq5z1nJ7SrjRMeBSq4LJloOhTasSV9z7w4mhHJkMkfolJg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", - "eslint-visitor-keys": "^3.4.1" + "@babel/runtime": "^7.16.0", + "jest-matcher-utils": "^29.6.2" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "jest": ">=29" } }, - "node_modules/@wordpress/eslint-plugin/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "node_modules/@wordpress/jest-preset-default": { + "version": "11.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-11.18.0.tgz", + "integrity": "sha512-qwcDXfKkdBJnnsQAa0qkBsg94usGQCD914pWNeBg997qy/6zmVYVXpPjXoJXaC/lYbEIRAWGfry1RSiM6ZoC9g==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "@wordpress/jest-console": "^7.18.0", + "babel-jest": "^29.6.2" }, "engines": { - "node": ">=8" + "node": ">=14" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": ">=7", + "jest": ">=29" } }, - "node_modules/@wordpress/eslint-plugin/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==", + "node_modules/@wordpress/keyboard-shortcuts": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-4.24.0.tgz", + "integrity": "sha512-6ZakUi4vfzYnNv0iITlGYWYi94xOYYYuUgvpyPIlc0mDkoNv5LrCyl4UoaKYc4oA73+6QUGzT98nP/Ob8y6/5A==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@wordpress/eslint-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@wordpress/eslint-plugin/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@wordpress/eslint-plugin/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/@wordpress/hooks": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.46.0.tgz", - "integrity": "sha512-TTYNZwMZeATpkWmvAoShP43UONd/WPNTtsy1czMSyiqPzFhzGJbKD75CdJtPp5DqIAiuWQEuDmcxRAPcZ/1Qgw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/html-entities": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-3.46.0.tgz", - "integrity": "sha512-2L3aJtWOLb2XMqgmM3voCIi8Oif1Vx+sc6C4kGwM336Sgx+EqZulFsN7OBt6CuK3PcAk1qaMPu59ANx3OJm60g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/i18n": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.46.0.tgz", - "integrity": "sha512-5/61hd50KkqGgoQpf66DDft6sMTKfeGVdmZOt42GWymylxFSmbZLLnR8YafECQrmia/TdwIco5I4n0hIikYbNQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^3.46.0", - "gettext-parser": "^1.3.1", - "memize": "^2.1.0", - "sprintf-js": "^1.1.1", - "tannin": "^1.2.0" - }, - "bin": { - "pot-to-php": "tools/pot-to-php.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/icons": { - "version": "9.37.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-9.37.0.tgz", - "integrity": "sha512-AoUne0i5U39+FulHR0O6yTKaocEAEl3RNzWgCOmJ8PCEoDtmU5seRm7yd3f6rWC5GXpaMABVB3pQM3TSMLx9fw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/element": "^5.23.0", - "@wordpress/primitives": "^3.44.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/is-shallow-equal": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.46.0.tgz", - "integrity": "sha512-1K5RTTi99ozF9vPKxoVl+RR6mSYy64DKYnijACDN9Sigzbe6OWeL6ky47r09G0JtDnRpzA0itIfFcV8iRNzpvA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/jest-console": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-7.17.0.tgz", - "integrity": "sha512-i1r0fGEZforoB1C8QuSfDDYwMycAJ/MqkEvhqWNLwcJy/JFYGWiKhkzhKfQ7aMUuwtrEJMb+41AOxelT565bDw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "jest-matcher-utils": "^29.6.2" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "jest": ">=29" - } - }, - "node_modules/@wordpress/jest-preset-default": { - "version": "11.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-11.17.0.tgz", - "integrity": "sha512-Z1KAr9ViDLFiVAYsRkyAAwLBzxu6MTv1dAZpHhyZhYfxTNdTOnnHbNGHpsfv5OlT5xHxptkrESLP8klU2/kw4A==", - "dev": true, - "dependencies": { - "@wordpress/jest-console": "^7.17.0", - "babel-jest": "^29.6.2" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "@babel/core": ">=7", - "jest": ">=29" - } - }, - "node_modules/@wordpress/jest-puppeteer-axe": { - "version": "6.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-puppeteer-axe/-/jest-puppeteer-axe-6.17.0.tgz", - "integrity": "sha512-/bvr/zBdn6NY+BnlB/nDR8ugRE63zu5fkslTRLeWCBMYxJYTSxWQDwPeHeNtzbVufKrtb+1MFzsVDJ+rbHM0YQ==", - "dev": true, - "dependencies": { - "@axe-core/puppeteer": "^4.0.0", - "@babel/runtime": "^7.16.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "jest": ">=29", - "puppeteer": ">=11" - }, - "peerDependenciesMeta": { - "puppeteer": { - "optional": true - } - } - }, - "node_modules/@wordpress/keyboard-shortcuts": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-4.23.0.tgz", - "integrity": "sha512-KRc1eJ07pm6Z7gsUQFBy58Msv1JUpLWKVU6c62+t0LA11j5GJ86xuiyOwTvh/pXqXzvduPUTmJe63OKqSxbtTA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/data": "^9.16.0", - "@wordpress/element": "^5.23.0", - "@wordpress/keycodes": "^3.46.0", - "rememo": "^4.0.2" + "@babel/runtime": "^7.16.0", + "@wordpress/data": "^9.17.0", + "@wordpress/element": "^5.24.0", + "@wordpress/keycodes": "^3.47.0", + "rememo": "^4.0.2" }, "engines": { "node": ">=12" @@ -7157,13 +6581,13 @@ } }, "node_modules/@wordpress/keycodes": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-3.46.0.tgz", - "integrity": "sha512-08ubCD321T85BZBUQuco2/vwIC5Pfzbw4CY7E2xR3rGzX3vb7SjDbKIqKeJL/UfYSmZF9GY+KaspSa1ywFtWiA==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-3.47.0.tgz", + "integrity": "sha512-dmYpqCWUoCM290YA5ApES9nqz/0D1JngIlZtel+BvELf8fj/jctdsT5wDB7dVdvZCuyr5SF+1Od00DYbMbb5oA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^4.46.0", + "@wordpress/i18n": "^4.47.0", "change-case": "^4.1.2" }, "engines": { @@ -7171,14 +6595,14 @@ } }, "node_modules/@wordpress/notices": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-4.14.0.tgz", - "integrity": "sha512-KvltcNd+PZB6h6wnYzi/KYn6cAM4I5IBU0Z2IDMQuvsCl4acAdmr/YrUY8Ya+qUaRuhBU7NON+XDQgNt7VIq7g==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-4.15.0.tgz", + "integrity": "sha512-HAaPmxbcuXWi35VV4t3eb03rWeAXdHFBjHpvDjCiyMdqB2QBfZUA80ARBP6dd/CYlJ+Rm3IcV5PT8KHDJBjQew==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^3.46.0", - "@wordpress/data": "^9.16.0" + "@wordpress/a11y": "^3.47.0", + "@wordpress/data": "^9.17.0" }, "engines": { "node": ">=12" @@ -7188,9 +6612,9 @@ } }, "node_modules/@wordpress/npm-package-json-lint-config": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-4.31.0.tgz", - "integrity": "sha512-Y/MxST3sK/En6ZAChlyq5A7qtII9/1MLqk6o75yWPIDn1ew40V7iPBDkFKE3uMEPw1RW8rJ9WSQxNpcN+4k+Zg==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-4.32.0.tgz", + "integrity": "sha512-qyEnU9FoWpaa67pufu9fNmTCikiYhdKc4R01ffO+xX7wyJXMo0Z6EJog6ajU9E2+YL86AmAX+sO1CHuXcsxdbw==", "dev": true, "engines": { "node": ">=14" @@ -7200,12 +6624,12 @@ } }, "node_modules/@wordpress/postcss-plugins-preset": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@wordpress/postcss-plugins-preset/-/postcss-plugins-preset-4.30.0.tgz", - "integrity": "sha512-b/APWKhvocBrs+IHJNe7BOfFmvyRmOZEHEXvwPZy2iGIC95tA5p2/7h3/iSwUGNUcyGObqwd90Htfit9oIdQJA==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@wordpress/postcss-plugins-preset/-/postcss-plugins-preset-4.31.0.tgz", + "integrity": "sha512-B6bHsCKxt25nkvWfIJH3l7kENKS20mpsiRIl5+CEES6kKfBwg4IPx+JyA/RPLFQcIQNtIYFft22p5bgT4VZcEg==", "dev": true, "dependencies": { - "@wordpress/base-styles": "^4.37.0", + "@wordpress/base-styles": "^4.38.0", "autoprefixer": "^10.2.5" }, "engines": { @@ -7216,18 +6640,18 @@ } }, "node_modules/@wordpress/preferences": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-3.23.0.tgz", - "integrity": "sha512-IZnmjbCbte0YALO03SEIfm4ALezTAuXKWZgz/I7DGBe2KgJsvjvllIz6f0dQuLvmi931EUEqLuC5ssB/LnjNHQ==", + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-3.24.0.tgz", + "integrity": "sha512-G2fnT0p2/euiUB/vDofXvDdw9TS1GNs/bRbWiMIa84I22rc/ai46BOdUo1mQdRlAw4O9uaF7v1UfoXS1cbWHVw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^3.46.0", - "@wordpress/components": "^25.12.0", - "@wordpress/data": "^9.16.0", - "@wordpress/element": "^5.23.0", - "@wordpress/i18n": "^4.46.0", - "@wordpress/icons": "^9.37.0", + "@wordpress/a11y": "^3.47.0", + "@wordpress/components": "^25.13.0", + "@wordpress/data": "^9.17.0", + "@wordpress/element": "^5.24.0", + "@wordpress/i18n": "^4.47.0", + "@wordpress/icons": "^9.38.0", "classnames": "^2.3.1" }, "engines": { @@ -7239,9 +6663,9 @@ } }, "node_modules/@wordpress/prettier-config": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-3.3.0.tgz", - "integrity": "sha512-G0HoubSikorLtXs0CZ0TNGbhKImCr+Ztg0HQUKv683r+yiZBOQV1igk7TaHOmIaf6702Bt4E3++IoAQN8Nr5ew==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-3.4.0.tgz", + "integrity": "sha512-6qawlZqqbe6NDY0txzsPZThRFAXzf0a891wI/A4KNWVKUXQwTluXWMtGZx3xlFtvkX+9ZHdoqXbWysGQztiBOQ==", "dev": true, "engines": { "node": ">=14" @@ -7251,13 +6675,13 @@ } }, "node_modules/@wordpress/primitives": { - "version": "3.44.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-3.44.0.tgz", - "integrity": "sha512-bpDHPTecyALcFK40Nz8DFToQGmv9s5kTqeNMCtbgqd7nWej4NTE4vRVrEnzGS/BHrUQPk6UCRSgtRuXpLfuHGA==", + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-3.45.0.tgz", + "integrity": "sha512-8nSRklcrUFIOD/A8gpDrNmf2GTa3x0kuc8EHpra0FBVAwUaacp+HeeP7281tSSIt/yKg3BYhzFnYTB2OQIguGQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^5.23.0", + "@wordpress/element": "^5.24.0", "classnames": "^2.3.1" }, "engines": { @@ -7265,9 +6689,9 @@ } }, "node_modules/@wordpress/priority-queue": { - "version": "2.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-2.46.0.tgz", - "integrity": "sha512-ElNF4ONApHwwkEvP3Ta6Wly2RCljXLZpfyahOziq3rlK8gaeU82qRt13KBE85Djz+90yHSyDlX9YpmJebV9oPw==", + "version": "2.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-2.47.0.tgz", + "integrity": "sha512-ZA6BDYkEC3mY1UrEXYnihdb0GoJooxZ9ADPEDEnqY88EuUT8/eeIDOge7OzgatDa9ivzV8TP3Fs4C/mHg/s6dQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -7278,9 +6702,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-0.28.0.tgz", - "integrity": "sha512-OAwLJfNIkSV2e77T7sXaGWtrbYuzhpusL0ufaR0hux6HfavHDmFuCjyyk3kUdq/GY6bFWDrWIvOTAkmVLYXdYg==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-0.29.0.tgz", + "integrity": "sha512-8t4au9+IXXgJlxxOuYVYi8PKp0uWajNYILNfqCLB65jQEClzGNMQhU6MeJ9+kHN3gdOltMk7UzG28X+FTDlmkQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -7290,9 +6714,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-4.46.0.tgz", - "integrity": "sha512-gvyCIp5zh9Nxj3+H6tD6+DrXal7ER68yuvWgWe6+XRWG0D/MhBog6xe1TCJ6Ec5tFcL30cEEy33YPxCiNnPtjA==", + "version": "4.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-4.47.0.tgz", + "integrity": "sha512-MK9evE2Tn3wVTJhSyAPgIVzMWRd5M9Bjfn4n1in1fbmrYN7qnFYdP4VUJwwYlKRDFpJUxC/4iyREBOryoxKDZw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -7308,20 +6732,20 @@ } }, "node_modules/@wordpress/rich-text": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-6.23.0.tgz", - "integrity": "sha512-NTq0BSN0cnS54BoOKl+3pDrnCM1WNHs/dENRqZaQr+vak0jGJXK8JLJJXJazt2iFniJTZFlDBUEPj/43c2VfwQ==", + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-6.24.0.tgz", + "integrity": "sha512-RkvzK8zvLgpd7i5dlL6zs+Dig1lZNSZf/3sYyjX6RalISXNuxF6Zn8Or7kBcq7EcYmey0LMlVIl5FTZ2l7HSIA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^3.46.0", - "@wordpress/compose": "^6.23.0", - "@wordpress/data": "^9.16.0", - "@wordpress/deprecated": "^3.46.0", - "@wordpress/element": "^5.23.0", - "@wordpress/escape-html": "^2.46.0", - "@wordpress/i18n": "^4.46.0", - "@wordpress/keycodes": "^3.46.0", + "@wordpress/a11y": "^3.47.0", + "@wordpress/compose": "^6.24.0", + "@wordpress/data": "^9.17.0", + "@wordpress/deprecated": "^3.47.0", + "@wordpress/element": "^5.24.0", + "@wordpress/escape-html": "^2.47.0", + "@wordpress/i18n": "^4.47.0", + "@wordpress/keycodes": "^3.47.0", "memize": "^2.1.0", "rememo": "^4.0.2" }, @@ -7333,24 +6757,24 @@ } }, "node_modules/@wordpress/scripts": { - "version": "26.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-26.17.0.tgz", - "integrity": "sha512-DmnZphBSkp9cX5YVAh9PchBh45iSaPFyh9Ria8rlH9zp/O5KQ2eWte4xv84B5FbKzUIqilNdtLTPrvsm0PQiGg==", + "version": "26.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-26.18.0.tgz", + "integrity": "sha512-cL3CKlPbH+JOnkV4MtGFUDys3KNlp6tjwrGBcpXsYOEm55DYtdXNmkRXHIfiM5hxCWiuE0P0dR7o/6F3Nz3TGA==", "dev": true, "dependencies": { "@babel/core": "^7.16.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@svgr/webpack": "^8.0.1", - "@wordpress/babel-preset-default": "^7.30.0", - "@wordpress/browserslist-config": "^5.29.0", - "@wordpress/dependency-extraction-webpack-plugin": "^4.29.0", - "@wordpress/e2e-test-utils-playwright": "^0.14.0", - "@wordpress/eslint-plugin": "^17.3.0", - "@wordpress/jest-preset-default": "^11.17.0", - "@wordpress/npm-package-json-lint-config": "^4.31.0", - "@wordpress/postcss-plugins-preset": "^4.30.0", - "@wordpress/prettier-config": "^3.3.0", - "@wordpress/stylelint-config": "^21.29.0", + "@wordpress/babel-preset-default": "^7.31.0", + "@wordpress/browserslist-config": "^5.30.0", + "@wordpress/dependency-extraction-webpack-plugin": "^4.30.0", + "@wordpress/e2e-test-utils-playwright": "^0.15.0", + "@wordpress/eslint-plugin": "^17.4.0", + "@wordpress/jest-preset-default": "^11.18.0", + "@wordpress/npm-package-json-lint-config": "^4.32.0", + "@wordpress/postcss-plugins-preset": "^4.31.0", + "@wordpress/prettier-config": "^3.4.0", + "@wordpress/stylelint-config": "^21.30.0", "adm-zip": "^0.5.9", "babel-jest": "^29.6.2", "babel-loader": "^8.2.3", @@ -7369,7 +6793,7 @@ "fast-glob": "^3.2.7", "filenamify": "^4.2.0", "jest": "^29.6.2", - "jest-dev-server": "^6.0.2", + "jest-dev-server": "^9.0.1", "jest-environment-jsdom": "^29.6.2", "jest-environment-node": "^29.6.2", "markdownlint-cli": "^0.31.1", @@ -7680,9 +7104,9 @@ } }, "node_modules/@wordpress/shortcode": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-3.46.0.tgz", - "integrity": "sha512-Jq6rI8GC9dOYQUErd3KUruyE+mY6nzsB8Y+B1L3XjY4JLkQbs5oiOzpPa0a3jL3D1POAYDVzBeaCSs7o2POf5w==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-3.47.0.tgz", + "integrity": "sha512-5BqZ2MavyhyiOfJm7RycqxN6bvH2sYHgg2TBYNPuKuvUIN0Ul2k6IVZdH/WEUexHBSp01LKdGVhXfTk4OGCTuw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -7693,9 +7117,9 @@ } }, "node_modules/@wordpress/style-engine": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-1.29.0.tgz", - "integrity": "sha512-W+JgmQS6Kyg5iBQFTIkEAtdajLG1vSOwEggGKl/pABE5vcI9pV3OkQ2GD8dOabwe4t6kwLX+576o0MrBcg+hAg==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-1.30.0.tgz", + "integrity": "sha512-UhU97gG/7R8wJUMi8Xq4UECu2hZPwhM0S0o/YKrhT/jwnpo5rHV81oPpVS63EASDeJmQrR24CQ+wB7dWhUvaXg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -7706,9 +7130,9 @@ } }, "node_modules/@wordpress/stylelint-config": { - "version": "21.29.0", - "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-21.29.0.tgz", - "integrity": "sha512-8VetLM5CTg8iLgodgpY4x132Yf4gPWMMffqfAG8HFwwvVQxm0mjl/dNtj6RBrxemdTi7dHr1jnZvqU+XxQlHXQ==", + "version": "21.30.0", + "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-21.30.0.tgz", + "integrity": "sha512-PlvXzYgjn7OUaVTy2bahSr6oL/eu1OdRWxrZfGVNxF4jRswND/ThqOEHIzxETNGTe0ggZOyY+40St4Swlo1zZQ==", "dev": true, "dependencies": { "stylelint-config-recommended": "^6.0.0", @@ -7722,9 +7146,9 @@ } }, "node_modules/@wordpress/token-list": { - "version": "2.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-2.46.0.tgz", - "integrity": "sha512-GZyzfHyjjG5+V4bF62UPZQFhoMLpX5Dt1Jl/J3jQFmUpbccNlCxRPEtTd9p7N6JeQlPUgQlyUjykQ1aBWU984A==", + "version": "2.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-2.47.0.tgz", + "integrity": "sha512-PsPE2QZtie691Fk7LpOnwJcCnXm6jiLt0eQ5MtR8lxCFofOKfkmI5Oo7GlQjBSQXOdsY0zeDsOODs3gZVCnpmw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -7734,22 +7158,22 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-0.6.0.tgz", - "integrity": "sha512-u/oW1LAx0yANHzFHz/H1Tnopa7r/8q1D/bV2fescjQ947LLOpaImh7hlLn6ryEt8qCj2YSL9Ry2dDE2R/U1gQQ==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-0.7.0.tgz", + "integrity": "sha512-WhMKX/ETGUJr2GkaPgGwFF8gTU/PgikfvE2b2ZDjUglxIPYnujBa9S6w+kQPzwGniGJutHL1DFK+TmAaxoci9A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^4.46.0" + "@wordpress/is-shallow-equal": "^4.47.0" }, "engines": { "node": ">=12" } }, "node_modules/@wordpress/url": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-3.47.0.tgz", - "integrity": "sha512-eDj7eDDYS8/UaUioulM54JkhmYvplvwW8+rbidR0fKZLr9zu3mfM7vrlwpIv9OK2RMenqEvu7Ij2gc5n/YEAcQ==", + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-3.48.0.tgz", + "integrity": "sha512-12bjIBBGcA5X8RPvUURLJZzpB60O5DI3WxQVIBBKPF4Mv8nUmgT4uemGzf5/ble8lqzJVntyEhEWKPOxEbUbJg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -7760,18 +7184,18 @@ } }, "node_modules/@wordpress/warning": { - "version": "2.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-2.46.0.tgz", - "integrity": "sha512-oyUNmDz64nF8vnS9LaobXMIx6K5w+XhAtvo3Cjv3kCVIuWFwpxoeMus3pUo1A7v2H9zcW+E87zwEuqsLPYjNfQ==", + "version": "2.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-2.47.0.tgz", + "integrity": "sha512-lmpLNI8Si7HrSY0LBBtp7Z6NzAkh1y7yeJI0LZw17EsJ0MM5FSXqXJRrNY7L4tM8G/vv3OacUw1mRAZX7bzBRQ==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/@wordpress/wordcount": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-3.46.0.tgz", - "integrity": "sha512-R9u3WTSQoaVtZkk6oDlW2hhpNwCxZW6CKQmDQhlj+15aDTHtf58JEPBNstwXSovQlrjB1RpyhBa37nWkC8Bsag==", + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-3.47.0.tgz", + "integrity": "sha512-s+zDLgdU4YuyguBOJ0PLEJLr5g/vFgYb0c2HPhh6eRCcyPAhyMPV6pDD9ME8cTwddTCxnVtucrx9c1sFn9n00g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -8340,21 +7764,23 @@ } }, "node_modules/axe-core": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.8.2.tgz", - "integrity": "sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/axios": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", - "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", "dev": true, "dependencies": { - "follow-redirects": "^1.14.7" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/axobject-query": { @@ -8666,9 +8092,9 @@ "dev": true }, "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" @@ -9360,19 +8786,6 @@ "node": ">=6.0" } }, - "node_modules/chromium-bidi": { - "version": "0.4.33", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.33.tgz", - "integrity": "sha512-IxoFM5WGQOIAd95qrSXzJUv4eXIrh+RvU3rwwqIiwYuvfE7U/Llj4fejbsJnjJMUYCuGtVQsY2gv7oGl4aTNSQ==", - "dev": true, - "dependencies": { - "mitt": "3.0.1", - "urlpattern-polyfill": "9.0.0" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -9440,6 +8853,106 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/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/cli-truncate/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", @@ -11044,12 +10557,6 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "dev": true }, - "node_modules/devtools-protocol": { - "version": "0.0.1203626", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1203626.tgz", - "integrity": "sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==", - "dev": true - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -11245,6 +10752,12 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -11779,30 +11292,163 @@ } } }, - "node_modules/eslint-plugin-jsdoc": { - "version": "46.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.9.0.tgz", - "integrity": "sha512-UQuEtbqLNkPf5Nr/6PPRCtr9xypXY+g8y/Q7gPa0YK7eDhh0y2lWprXRnaYbW7ACgIUvpDKy9X2bZqxtGzBG9Q==", + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.41.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.5.0", - "is-builtin-module": "^3.2.1", - "semver": "^7.5.4", - "spdx-expression-parse": "^3.0.1" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { - "node": ">=16" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/lru-cache": { + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/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/eslint-plugin-jest/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jest/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/eslint-plugin-jsdoc": { + "version": "46.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.9.0.tgz", + "integrity": "sha512-UQuEtbqLNkPf5Nr/6PPRCtr9xypXY+g8y/Q7gPa0YK7eDhh0y2lWprXRnaYbW7ACgIUvpDKy9X2bZqxtGzBG9Q==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.41.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "is-builtin-module": "^3.2.1", + "semver": "^7.5.4", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/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==", @@ -11865,15 +11511,6 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-plugin-playwright": { "version": "0.15.3", "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.15.3.tgz", @@ -13045,9 +12682,9 @@ } }, "node_modules/framer-motion": { - "version": "10.16.5", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.5.tgz", - "integrity": "sha512-GEzVjOYP2MIpV9bT/GbhcsBNoImG3/2X3O/xVNWmktkv9MdJ7P/44zELm/7Fjb+O3v39SmKFnoDQB32giThzpg==", + "version": "10.16.12", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.16.12.tgz", + "integrity": "sha512-w7Yzx0OzQ5Uh6uNkxaX+4TuAPuOKz3haSbjmHpdrqDpGuCJCpq6YP9Dy7JJWdZ6mJjndrg3Ao3vUwDajKNikCA==", "dev": true, "dependencies": { "tslib": "^2.4.0" @@ -13888,6 +13525,21 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -15342,18 +14994,21 @@ } }, "node_modules/jest-dev-server": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jest-dev-server/-/jest-dev-server-6.2.0.tgz", - "integrity": "sha512-ZWh8CuvxwjhYfvw4tGeftziqIvw/26R6AG3OTgNTQeXul8aZz48RQjDpnlDwnWX53jxJJl9fcigqIdSU5lYZuw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/jest-dev-server/-/jest-dev-server-9.0.1.tgz", + "integrity": "sha512-eqpJKSvVl4M0ojHZUPNbka8yEzLNbIMiINXDsuMF3lYfIdRO2iPqy+ASR4wBQ6nUyR3OT24oKPWhpsfLhgAVyg==", "dev": true, "dependencies": { "chalk": "^4.1.2", "cwd": "^0.10.0", "find-process": "^1.4.7", "prompts": "^2.4.2", - "spawnd": "^6.2.0", + "spawnd": "^9.0.1", "tree-kill": "^1.2.2", - "wait-on": "^6.0.1" + "wait-on": "^7.0.1" + }, + "engines": { + "node": ">=16" } }, "node_modules/jest-dev-server/node_modules/ansi-styles": { @@ -15636,99 +15291,69 @@ } } }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", - "jest-mock": "^27.5.1" + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "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, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@sinonjs/commons": { - "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" - } - }, - "node_modules/jest-environment-node/node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/jest-environment-node/node_modules/@types/yargs": { - "version": "16.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.8.tgz", - "integrity": "sha512-1GwLEkmFafeb/HbE6pC7tFlgYSQ4Iqh2qlWCq8xN+Qfaiaxr2PcLfuhfRFRYqI6XJyeFoLYyKnhFbNsst9FMtQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node/node_modules/ansi-styles": { + "node_modules/jest-matcher-utils/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==", @@ -15743,7 +15368,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-environment-node/node_modules/chalk": { + "node_modules/jest-matcher-utils/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -15759,7 +15384,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-environment-node/node_modules/color-convert": { + "node_modules/jest-matcher-utils/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==", @@ -15771,13 +15396,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-environment-node/node_modules/color-name": { + "node_modules/jest-matcher-utils/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/jest-environment-node/node_modules/has-flag": { + "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==", @@ -15786,114 +15411,45 @@ "node": ">=8" } }, - "node_modules/jest-environment-node/node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "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, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "node_modules/jest-message-util/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": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-environment-node/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-puppeteer": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-puppeteer/-/jest-environment-puppeteer-6.2.0.tgz", - "integrity": "sha512-a/oSu6dO9D+XoDDe3ZY/0Sk79Jl2FcJl7Q0D+3x22l1eWNOYe4ikXnPGhtmNZ3mJIpuAVIX6LytA8EraOk/aqQ==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "cwd": "^0.10.0", - "jest-dev-server": "^6.2.0", - "jest-environment-node": "^27.5.1", - "merge-deep": "^3.0.3" - } - }, - "node_modules/jest-environment-puppeteer/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" + "color-convert": "^2.0.1" }, "engines": { "node": ">=8" @@ -15902,7 +15458,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-environment-puppeteer/node_modules/chalk": { + "node_modules/jest-message-util/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -15918,7 +15474,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-environment-puppeteer/node_modules/color-convert": { + "node_modules/jest-message-util/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==", @@ -15930,13 +15486,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-environment-puppeteer/node_modules/color-name": { + "node_modules/jest-message-util/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/jest-environment-puppeteer/node_modules/has-flag": { + "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==", @@ -15945,7 +15501,7 @@ "node": ">=8" } }, - "node_modules/jest-environment-puppeteer/node_modules/supports-color": { + "node_modules/jest-message-util/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==", @@ -15957,69 +15513,80 @@ "node": ">=8" } }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { + "node_modules/jest-mock": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/jest-leak-detector": { + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils": { + "node_modules/jest-resolve-dependencies": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "node_modules/jest-resolve/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==", @@ -16034,7 +15601,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-matcher-utils/node_modules/chalk": { + "node_modules/jest-resolve/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -16050,7 +15617,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { + "node_modules/jest-resolve/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==", @@ -16062,13 +15629,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/color-name": { + "node_modules/jest-resolve/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/jest-matcher-utils/node_modules/has-flag": { + "node_modules/jest-resolve/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==", @@ -16077,7 +15644,7 @@ "node": ">=8" } }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { + "node_modules/jest-resolve/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==", @@ -16089,27 +15656,39 @@ "node": ">=8" } }, - "node_modules/jest-message-util": { + "node_modules/jest-runner": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", + "@types/node": "*", "chalk": "^4.0.0", + "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { + "node_modules/jest-runner/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==", @@ -16124,7 +15703,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-message-util/node_modules/chalk": { + "node_modules/jest-runner/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -16140,7 +15719,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-message-util/node_modules/color-convert": { + "node_modules/jest-runner/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==", @@ -16152,13 +15731,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-message-util/node_modules/color-name": { + "node_modules/jest-runner/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/jest-message-util/node_modules/has-flag": { + "node_modules/jest-runner/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==", @@ -16167,7 +15746,24 @@ "node": ">=8" } }, - "node_modules/jest-message-util/node_modules/supports-color": { + "node_modules/jest-runner/node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/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==", @@ -16179,114 +15775,55 @@ "node": ">=8" } }, - "node_modules/jest-mock": { + "node_modules/jest-runtime": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.7.0" + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "node_modules/jest-runtime/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, - "engines": { - "node": ">=6" + "dependencies": { + "color-convert": "^2.0.1" }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-puppeteer": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jest-puppeteer/-/jest-puppeteer-6.2.0.tgz", - "integrity": "sha512-4Ynkgcf9FkHlTNEpdsojGLb3KtsToWqjO6SCigxb9Qj3HzIqhzJzNbDJ/XhiciNDpqDe6KHW9sZ6fjHphNLr6g==", - "dev": true, - "dependencies": { - "expect-puppeteer": "^6.1.1", - "jest-environment-puppeteer": "^6.2.0" - }, - "peerDependencies": { - "puppeteer": ">= 1.5.0" - } - }, - "node_modules/jest-puppeteer/node_modules/expect-puppeteer": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/expect-puppeteer/-/expect-puppeteer-6.1.1.tgz", - "integrity": "sha512-cnQF96qdoEcOD63j5NQMc0RtW9WRMW/WHKXEKsuDQ2tszhVH3qC7zkXXS4D0LTt9qCB3DEExioqylsQXvqPrUw==", - "dev": true - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve/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" + "engines": { + "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-resolve/node_modules/chalk": { + "node_modules/jest-runtime/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -16302,7 +15839,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-resolve/node_modules/color-convert": { + "node_modules/jest-runtime/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==", @@ -16314,13 +15851,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-resolve/node_modules/color-name": { + "node_modules/jest-runtime/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/jest-resolve/node_modules/has-flag": { + "node_modules/jest-runtime/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==", @@ -16329,7 +15866,7 @@ "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/supports-color": { + "node_modules/jest-runtime/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==", @@ -16341,39 +15878,38 @@ "node": ">=8" } }, - "node_modules/jest-runner": { + "node_modules/jest-snapshot": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", - "@types/node": "*", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "emittery": "^0.13.1", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { + "node_modules/jest-snapshot/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==", @@ -16388,7 +15924,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runner/node_modules/chalk": { + "node_modules/jest-snapshot/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -16404,7 +15940,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-runner/node_modules/color-convert": { + "node_modules/jest-snapshot/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==", @@ -16416,13 +15952,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-runner/node_modules/color-name": { + "node_modules/jest-snapshot/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/jest-runner/node_modules/has-flag": { + "node_modules/jest-snapshot/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==", @@ -16431,24 +15967,34 @@ "node": ">=8" } }, - "node_modules/jest-runner/node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "node_modules/jest-snapshot/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": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "yallist": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/jest-runner/node_modules/supports-color": { + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/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==", @@ -16460,40 +16006,30 @@ "node": ">=8" } }, - "node_modules/jest-runtime": { + "node_modules/jest-snapshot/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/jest-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", + "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" + "picomatch": "^2.2.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/ansi-styles": { + "node_modules/jest-util/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==", @@ -16508,7 +16044,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-runtime/node_modules/chalk": { + "node_modules/jest-util/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -16524,7 +16060,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-runtime/node_modules/color-convert": { + "node_modules/jest-util/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==", @@ -16536,13 +16072,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-runtime/node_modules/color-name": { + "node_modules/jest-util/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/jest-runtime/node_modules/has-flag": { + "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==", @@ -16551,7 +16087,7 @@ "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/supports-color": { + "node_modules/jest-util/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==", @@ -16563,38 +16099,24 @@ "node": ">=8" } }, - "node_modules/jest-snapshot": { + "node_modules/jest-validate": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" + "leven": "^3.1.0", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { + "node_modules/jest-validate/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==", @@ -16609,7 +16131,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-snapshot/node_modules/chalk": { + "node_modules/jest-validate/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -16625,7 +16147,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-snapshot/node_modules/color-convert": { + "node_modules/jest-validate/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==", @@ -16637,13 +16159,13 @@ "node": ">=7.0.0" } }, - "node_modules/jest-snapshot/node_modules/color-name": { + "node_modules/jest-validate/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/jest-snapshot/node_modules/has-flag": { + "node_modules/jest-validate/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==", @@ -16652,223 +16174,16 @@ "node": ">=8" } }, - "node_modules/jest-snapshot/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==", + "node_modules/jest-validate/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": { - "yallist": "^4.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/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/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/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/jest-util/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/jest-util/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/jest-util/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/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/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/jest-validate/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/jest-validate/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/jest-validate/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/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": ">=8" } }, "node_modules/jest-watcher": { @@ -17690,42 +17005,379 @@ "uc.micro": "^1.0.1" } }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "node_modules/lint-staged": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.1.0.tgz", + "integrity": "sha512-ZPKXWHVlL7uwVpy8OZ7YQjYDAuO5X4kMh0XgZvPNxLcCCngd0PO5jKQyy3+s4TL2EnHoIXIzP1422f/l3nZKMw==", "dev": true, + "dependencies": { + "chalk": "5.3.0", + "commander": "11.1.0", + "debug": "4.3.4", + "execa": "8.0.1", + "lilconfig": "2.1.0", + "listr2": "7.0.2", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.4" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, "engines": { - "node": ">=6.11.5" + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" } }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/lint-staged/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=8.9.0" + "node": ">= 8" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=16.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/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/lint-staged/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/listr2": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", + "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", + "dev": true, + "dependencies": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", + "rfdc": "^1.3.0", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/listr2/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/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -17829,25 +17481,203 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/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==", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/lookup-closest-locale": { @@ -18411,12 +18241,6 @@ "node": ">=0.10.0" } }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true - }, "node_modules/mixin-object": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", @@ -18542,12 +18366,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -19652,6 +19470,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -20607,34 +20437,6 @@ "node": ">= 0.10" } }, - "node_modules/proxy-agent": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", - "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/proxy-compare": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.3.0.tgz", @@ -20690,237 +20492,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "21.5.2", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.5.2.tgz", - "integrity": "sha512-BaAGJOq8Fl6/cck6obmwaNLksuY0Bg/lIahCLhJPGXBFUD2mCffypa4A592MaWnDcye7eaHmSK9yot0pxctY8A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@puppeteer/browsers": "1.8.0", - "cosmiconfig": "8.3.6", - "puppeteer-core": "21.5.2" - }, - "engines": { - "node": ">=16.13.2" - } - }, - "node_modules/puppeteer-core": { - "version": "21.5.2", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.5.2.tgz", - "integrity": "sha512-v4T0cWnujSKs+iEfmb8ccd7u4/x8oblEyKqplqKnJ582Kw8PewYAWvkH4qUWhitN3O2q9RF7dzkvjyK5HbzjLA==", - "dev": true, - "dependencies": { - "@puppeteer/browsers": "1.8.0", - "chromium-bidi": "0.4.33", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1203626", - "ws": "8.14.2" - }, - "engines": { - "node": ">=16.13.2" - } - }, - "node_modules/puppeteer-testing-library": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/puppeteer-testing-library/-/puppeteer-testing-library-0.5.0.tgz", - "integrity": "sha512-x72CJwpbdJaGEjBEpUHqeNVdDu36Hoqt6yodnyL/msNN7IoioKS+3ZmwLw/DIiDZJujUAtq3qltbIehA+uGWHQ==", - "dev": true, - "dependencies": { - "jest-diff": "^26.6.2" - }, - "peerDependencies": { - "puppeteer": "*" - } - }, - "node_modules/puppeteer-testing-library/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/puppeteer-testing-library/node_modules/@types/yargs": { - "version": "15.0.18", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.18.tgz", - "integrity": "sha512-DDi2KmvAnNsT/EvU8jp1UR7pOJojBtJ3GLZ/uw1MUq4VbbESppPWoHUY4h0OB4BbEbGJiyEsmUcuZDZtoR+ZwQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/puppeteer-testing-library/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/puppeteer-testing-library/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/puppeteer-testing-library/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/puppeteer-testing-library/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/puppeteer-testing-library/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/puppeteer-testing-library/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/puppeteer-testing-library/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/puppeteer-testing-library/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/puppeteer-testing-library/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/puppeteer-testing-library/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/puppeteer/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/puppeteer/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/puppeteer/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -21760,6 +21331,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -22793,14 +22370,28 @@ } }, "node_modules/spawnd": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-6.2.0.tgz", - "integrity": "sha512-qX/I4lQy4KgVEcNle0kuc4FxFWHISzBhZW1YemPfwmrmQjyZmfTK/OhBKkhrD2ooAaFZEm1maEBLE6/6enwt+g==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-9.0.1.tgz", + "integrity": "sha512-vaMk8E9CpbjTYToBxLXowDeArGf1+yI7A6PU6Nr57b2g8BVY8nRi5vTBj3bMF8UkCrMdTMyf/Lh+lrcrW2z7pw==", "dev": true, "dependencies": { - "exit": "^0.1.2", - "signal-exit": "^3.0.7", + "signal-exit": "^4.1.0", "tree-kill": "^1.2.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/spawnd/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/spdx-correct": { @@ -22960,6 +22551,15 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -23407,13 +23007,13 @@ "dev": true }, "node_modules/synckit": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", - "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.6.tgz", + "integrity": "sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA==", "dev": true, "dependencies": { - "@pkgr/utils": "^2.3.1", - "tslib": "^2.5.0" + "@pkgr/utils": "^2.4.2", + "tslib": "^2.6.2" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -24234,12 +23834,6 @@ "requires-port": "^1.0.0" } }, - "node_modules/urlpattern-polyfill": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", - "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==", - "dev": true - }, "node_modules/use-callback-ref": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", @@ -24461,22 +24055,22 @@ } }, "node_modules/wait-on": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", - "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", + "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==", "dev": true, "dependencies": { - "axios": "^0.25.0", - "joi": "^17.6.0", + "axios": "^1.6.1", + "joi": "^17.11.0", "lodash": "^4.17.21", - "minimist": "^1.2.5", - "rxjs": "^7.5.4" + "minimist": "^1.2.8", + "rxjs": "^7.8.1" }, "bin": { "wait-on": "bin/wait-on" }, "engines": { - "node": ">=10.0.0" + "node": ">=12.0.0" } }, "node_modules/wait-on/node_modules/rxjs": { diff --git a/package.json b/package.json index e23ee3f..5cb979e 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { - "name": "@wp-blocks/search", - "description": "An advanced WordPress search block", + "name": "@wp-blocks/indexed-search", + "description": "An advanced WordPress indexed search plugin", "private": true, "type": "module", "contributors": [ "Erik Golinelli (https://codekraft.it/)", "John Hooks (https://johnhooks.io/)" ], - "homepage": "https://github.com/wp-blocks/search#readme", + "homepage": "https://github.com/wp-blocks/indexed-search#readme", "repository": { "type": "git", - "url": "https://github.com/wp-blocks/search.git" + "url": "https://github.com/wp-blocks/indexed-search.git" }, - "bugs": "https://github.com/wp-blocks/search/issues", + "bugs": "https://github.com/wp-blocks/indexed-search/issues", "license": "GPL-2.0-or-later", "scripts": { "packages-update": "wp-scripts packages-update", @@ -20,45 +20,43 @@ "start": "wp-scripts start", "format": "wp-scripts format ./client/src", "lint:css": "wp-scripts lint-style", - "lint:js": "eslint --ext .js,.jsx,.ts,.tsx .", - "wp-env:start": "wp-env start", - "wp-env:stop": "wp-env stop", - "wp-env:destroy": "wp-env destroy", + "lint:js": "eslint --ext .js,.jsx,.cjs,.mjs,.ts,.tsx .", + "check": "tsc -b", "test": "jest --silent=false --coverage", - "plugin-zip": "wp-scripts plugin-zip" + "prepare": "husky install" }, "devDependencies": { - "@babel/core": "^7.21.0", - "@babel/preset-typescript": "^7.21.0", - "@jest/globals": "^29.4.3", - "@types/babel__core": "^7.20.0", - "@types/expect-puppeteer": "^5.0.3", - "@types/jest": "^29.4.0", - "@types/jest-environment-puppeteer": "^5.0.3", - "@types/node": "^18.14.1", - "@types/puppeteer": "^7.0.4", - "@types/wordpress__block-editor": "^11.0.1", - "@types/wordpress__blocks": "^12.0.3", - "@types/wordpress__components": "^23.0.1", - "@types/wordpress__compose": "^6.0.1", - "@typescript-eslint/eslint-plugin": "^5.53.0", - "@typescript-eslint/parser": "^5.53.0", - "@wordpress/babel-plugin-makepot": "^5.30.0", - "@wordpress/block-editor": "^12.14.0", - "@wordpress/blocks": "^12.23.0", - "@wordpress/e2e-test-utils": "^10.17.0", - "@wordpress/e2e-tests": "^7.17.0", - "@wordpress/env": "^8.12.0", - "@wordpress/jest-preset-default": "^11.17.0", - "@wordpress/prettier-config": "^3.3.0", - "@wordpress/scripts": "^26.17.0", - "@wordpress/stylelint-config": "^21.29.0", + "@babel/core": "^7.23.5", + "@babel/preset-typescript": "^7.23.3", + "@jest/globals": "^29.7.0", + "@types/babel__core": "^7.20.5", + "@types/jest": "^29.5.10", + "@types/node": "^18.19.1", + "@types/wordpress__block-editor": "^11.5.7", + "@types/wordpress__blocks": "^12.5.11", + "@types/wordpress__components": "^23.0.8", + "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/parser": "^6.13.1", + "@wordpress/babel-plugin-makepot": "^5.31.0", + "@wordpress/block-editor": "^12.15.0", + "@wordpress/blocks": "^12.24.0", + "@wordpress/components": "^25.13.0", + "@wordpress/e2e-test-utils-playwright": "^0.15.0", + "@wordpress/env": "^8.13.0", + "@wordpress/jest-preset-default": "^11.18.0", + "@wordpress/prettier-config": "^3.4.0", + "@wordpress/scripts": "^26.18.0", + "@wordpress/stylelint-config": "^21.30.0", "@wp-blocks/tsconfig": "^0.1.0", - "babel-jest": "^29.4.3", - "eslint-import-resolver-typescript": "^3.5.3", - "eslint-plugin-import": "^2.27.5", - "jest-puppeteer": "^6.2.0", + "babel-jest": "^29.7.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.0", + "husky": "^8.0.3", + "lint-staged": "^15.1.0", "prettier": "^3.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "stylelint": "^14.16.1", "typescript": "^5.3.2" }, "browserslist": [ @@ -68,6 +66,9 @@ "extends": [ "@wordpress/stylelint-config", "@wordpress/stylelint-config/scss" - ] + ], + "rules": { + "indentation": 2 + } } } diff --git a/phpcs.xml b/phpcs.xml index 6546860..4a39672 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -8,30 +8,46 @@ */vendor/* - - + + - server/src/* - server/tests/* + src/* + tests/* + - server/src/*] - server/tests/* + src/*] + tests/* - server/tests/ + tests/ - server/src/* - server/tests/* + src/* + tests/* - server/src/* + src/* tests/* + indexed-search.php + + + + src/* + tests/* + indexed-search.php + + + + src/Tokenizer/WP_HTML_Tag_Processor.php + + + + src/Tokenizer/WP_HTML_Tag_Processor.php diff --git a/phpstan.neon b/phpstan.neon.dist similarity index 58% rename from phpstan.neon rename to phpstan.neon.dist index 2c1a177..41ae88d 100644 --- a/phpstan.neon +++ b/phpstan.neon.dist @@ -1,12 +1,19 @@ parameters: - level: 5 + level: max + bootstrapFiles: + - indexed-search.php paths: - - server/src - - server/tests + - src scanFiles: - vendor/wordpress/wordpress/src/wp-includes/compat.php - vendor/php-stubs/wordpress-tests-stubs/wordpress-tests-stubs.php - vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php - vendor/php-stubs/wp-cli-stubs/wp-cli-commands-stubs.php - vendor/php-stubs/wp-cli-stubs/wp-cli-i18n-stubs.php - + scanDirectories: + - tests + - vendor-prod + excludePaths: + - src/Compat/WP_HTML_Tag_Processor.php + - src/Stemmer/* + - tests/*/_wordpress/* diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 9d11e51..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - ./server/tests/Unit - ./server.tests/Unit - - - ./server/tests/Feature - ./server/tests/Feature - - - - - ./server/tests/ - ./tmp/ - - - - - - diff --git a/readme.txt b/readme.txt index 568b711..b2c80e1 100644 --- a/readme.txt +++ b/readme.txt @@ -1,15 +1,15 @@ -=== WP Blocks Search === +=== Indexed Search === Contributors: codekraft, bitmachina Tags: search, block -Requires at least: 6.0 +Requires at least: 6.2 Requires PHP: 7.4 Tested up to: 6.4 Stable tag: 0.1.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html -An advanced WordPress search block. +An advanced WordPress indexed search plugin. == Description == -A super cool search block, using indexing to make the search of post content speedy! +A super cool search plugin which uses indexing to make the search of post content speedy! diff --git a/search.php b/search.php deleted file mode 100644 index dee32b0..0000000 --- a/search.php +++ /dev/null @@ -1,39 +0,0 @@ -'; -} diff --git a/server/src/rest.php b/server/src/rest.php deleted file mode 100644 index c05ff57..0000000 --- a/server/src/rest.php +++ /dev/null @@ -1,68 +0,0 @@ - 'POST', - 'callback' => 's_live_search', - 'permission_callback' => '__return_true', - ) - ); -} - -/** - * Generates search results for a live search query. - * - * @param WP_REST_Request $request The REST request object containing the search query. - * @throws Exception If an error occurs during the search process. - * @return WP_REST_Response The search results in JSON format. - */ -function s_live_search( WP_REST_Request $request ) { - $query_string = sanitize_text_field( $request->get_param( 'query' ) ); - - // Generate a unique key for the transient based on the search parameters - $cache_key = 'custom_search_' . md5( $query_string ); - - // Try to retrieve the search results from the transient cache - $results = get_transient( $cache_key ); - - if ( false === $results ) { - - // Perform your search logic and fetch data - $args = array( - 'post_type' => array( 'product', 'post' ), - 's' => $query_string, - 'posts_per_page' => 4, - ); - $query = new WP_Query( $args ); - - if ( $query->have_posts() ) { - ob_start(); - while ( $query->have_posts() ) { - $query->the_post(); - - global $post; - - echo $post->ID; - - echo '
' . get_the_title() . '
'; - - } - $results = ob_get_clean(); - wp_reset_postdata(); - } else { - $results = ''; - } - } - - // Save the search results to the transient cache for 1 minute (60 seconds) - set_transient( $cache_key, $results, 60 ); - - // Return the results as JSON - return rest_ensure_response($results ); -} diff --git a/server/src/variation.php b/server/src/variation.php deleted file mode 100644 index 86aa720..0000000 --- a/server/src/variation.php +++ /dev/null @@ -1,168 +0,0 @@ -`. Support these by defaulting an undefined label and - // buttonText to `__( 'Search' )`. - $attributes = wp_parse_args( - $attributes, - array( - 'label' => __( 'Search', 'search-block' ), - 'buttonText' => __( 'Search', 'search-block' ), - ) - ); - - $input_id = wp_unique_id( 'wp-block-search__input-' ); - $classnames = classnames_for_block_core_search( $attributes ); - $show_label = ( ! empty( $attributes['showLabel'] ) ) ? true : false; - $use_icon_button = ( ! empty( $attributes['buttonUseIcon'] ) ) ? true : false; - $show_input = ( ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'] ) ? false : true; - $show_button = ( ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'] ) ? false : true; - $query_params = ( ! empty( $attributes['query'] ) ) ? $attributes['query'] : array(); - $input_markup = ''; - $button_markup = ''; - $query_params_markup = ''; - $inline_styles = styles_for_block_core_search( $attributes ); - $color_classes = get_color_classes_for_block_core_search( $attributes ); - $typography_classes = get_typography_classes_for_block_core_search( $attributes ); - $is_button_inside = ! empty( $attributes['buttonPosition'] ) && - 'button-inside' === $attributes['buttonPosition']; - // Border color classes need to be applied to the elements that have a border color. - $border_color_classes = get_border_color_classes_for_block_core_search( $attributes ); - - $label_inner_html = empty( $attributes['label'] ) ? __( 'Search', 'search-block' ) : wp_kses_post( $attributes['label'] ); - - $label_markup = sprintf( - '', - esc_attr( $input_id ), - $label_inner_html - ); - - if ( $show_label && ! empty( $attributes['label'] ) ) { - $label_classes = array( 'wp-block-search__label' ); - if ( ! empty( $typography_classes ) ) { - $label_classes[] = $typography_classes; - } - $label_markup = sprintf( - '', - esc_attr( $input_id ), - esc_attr( implode( ' ', $label_classes ) ), - $inline_styles['label'], - $label_inner_html - ); - } - - if ( $show_input ) { - $input_classes = array( 'wp-block-search__input' ); - if ( ! $is_button_inside && ! empty( $border_color_classes ) ) { - $input_classes[] = $border_color_classes; - } - if ( ! empty( $typography_classes ) ) { - $input_classes[] = $typography_classes; - } - $input_markup = sprintf( - '', - $input_id, - esc_attr( implode( ' ', $input_classes ) ), - get_search_query(), - esc_attr( $attributes['placeholder'] ), - $inline_styles['input'] - ); - } - - if ( count( $query_params ) > 0 ) { - foreach ( $query_params as $param => $value ) { - $query_params_markup .= sprintf( - '', - esc_attr( $param ), - esc_attr( $value ) - ); - } - } - - if ( $show_button ) { - $button_classes = array( 'wp-block-search__button' ); - $button_internal_markup = ''; - if ( ! empty( $color_classes ) ) { - $button_classes[] = $color_classes; - } - if ( ! empty( $typography_classes ) ) { - $button_classes[] = $typography_classes; - } - $aria_label = ''; - - if ( ! $is_button_inside && ! empty( $border_color_classes ) ) { - $button_classes[] = $border_color_classes; - } - if ( ! $use_icon_button ) { - if ( ! empty( $attributes['buttonText'] ) ) { - $button_internal_markup = wp_kses_post( $attributes['buttonText'] ); - } - } else { - $aria_label = sprintf( 'aria-label="%s"', esc_attr( wp_strip_all_tags( $attributes['buttonText'] ) ) ); - $button_classes[] = 'has-icon'; - - $button_internal_markup = - ' - - '; - } - - // Include the button element class. - $button_classes[] = wp_theme_get_element_class_name( 'button' ); - $button_markup = sprintf( - '', - esc_attr( implode( ' ', $button_classes ) ), - $inline_styles['button'], - $aria_label, - $button_internal_markup - ); - } - - $field_markup_classes = $is_button_inside ? $border_color_classes : ''; - $field_markup = sprintf( - '
%s
', - esc_attr( $field_markup_classes ), - $inline_styles['wrapper'], - $input_markup . $query_params_markup . $button_markup - ); - $wrapper_attributes = get_block_wrapper_attributes( - array( 'class' => $classnames ) - ); - - return sprintf( - '
%s
', - esc_url( home_url( '/' ) ), - $wrapper_attributes, - $label_markup . $field_markup - ); - }; - - // Get the existing block type - $cloned_block = WP_Block_Type_Registry::get_instance()->get_registered( 'core/search' ); - - // Add the variation attributes - $cloned_block->attributes = array_merge( $cloned_block->attributes, $variation_attributes ); - - $cloned_block->name = 'search-block'; - $cloned_block->title = __( 'Live Search', 'search-block' ); - $cloned_block->category = 'wp-blocks'; - - // Add the variation rendering callback - $cloned_block->render_callback = $variation_render_callback; - - $namespace = 'wp-blocks'; - $block_title = 'search-block'; - - // Register the new block type. - register_block_type( $namespace . '/' . $block_title, $cloned_block ); -} - -add_action( 'init', 'register_search_block_variation' ); diff --git a/src/Compat/WP_HTML_Tag_Processor.php b/src/Compat/WP_HTML_Tag_Processor.php new file mode 100644 index 0000000..88496aa --- /dev/null +++ b/src/Compat/WP_HTML_Tag_Processor.php @@ -0,0 +1,2594 @@ + "c" not " c". + * This would increase the size of the changes for some operations but leave more + * natural-looking output HTML. + * - Decode HTML character references within class names when matching. E.g. match having + * class `1<"2` needs to recognize `class="1<"2"`. Currently the Tag Processor + * will fail to find the right tag if the class name is encoded as such. + * - Properly decode HTML character references in `get_attribute()`. PHP's + * `html_entity_decode()` is wrong in a couple ways: it doesn't account for the + * no-ambiguous-ampersand rule, and it improperly handles the way semicolons may + * or may not terminate a character reference. + * + * @package WordPress + * @subpackage HTML-API + * + * @since 6.2.0 + */ + +/** + * Core class used to modify attributes in an HTML document for tags matching a query. + * + * ## Usage + * + * Use of this class requires three steps: + * + * 1. Create a new class instance with your input HTML document. + * 2. Find the tag(s) you are looking for. + * 3. Request changes to the attributes in those tag(s). + * + * Example: + * + * $tags = new WP_HTML_Tag_Processor( $html ); + * if ( $tags->next_tag( 'option' ) ) { + * $tags->set_attribute( 'selected', true ); + * } + * + * ### Finding tags + * + * The `next_tag()` function moves the internal cursor through + * your input HTML document until it finds a tag meeting any of + * the supplied restrictions in the optional query argument. If + * no argument is provided then it will find the next HTML tag, + * regardless of what kind it is. + * + * If you want to _find whatever the next tag is_: + * + * $tags->next_tag(); + * + * | Goal | Query | + * |-----------------------------------------------------------|---------------------------------------------------------------------------------| + * | Find any tag. | `$tags->next_tag();` | + * | Find next image tag. | `$tags->next_tag( array( 'tag_name' => 'img' ) );` | + * | Find next image tag (without passing the array). | `$tags->next_tag( 'img' );` | + * | Find next tag containing the `fullwidth` CSS class. | `$tags->next_tag( array( 'class_name' => 'fullwidth' ) );` | + * | Find next image tag containing the `fullwidth` CSS class. | `$tags->next_tag( array( 'tag_name' => 'img', 'class_name' => 'fullwidth' ) );` | + * + * If a tag was found meeting your criteria then `next_tag()` + * will return `true` and you can proceed to modify it. If it + * returns `false`, however, it failed to find the tag and + * moved the cursor to the end of the file. + * + * Once the cursor reaches the end of the file the processor + * is done and if you want to reach an earlier tag you will + * need to recreate the processor and start over, as it's + * unable to back up or move in reverse. + * + * See the section on bookmarks for an exception to this + * no-backing-up rule. + * + * #### Custom queries + * + * Sometimes it's necessary to further inspect an HTML tag than + * the query syntax here permits. In these cases one may further + * inspect the search results using the read-only functions + * provided by the processor or external state or variables. + * + * Example: + * + * // Paint up to the first five DIV or SPAN tags marked with the "jazzy" style. + * $remaining_count = 5; + * while ( $remaining_count > 0 && $tags->next_tag() ) { + * if ( + * ( 'DIV' === $tags->get_tag() || 'SPAN' === $tags->get_tag() ) && + * 'jazzy' === $tags->get_attribute( 'data-style' ) + * ) { + * $tags->add_class( 'theme-style-everest-jazz' ); + * $remaining_count--; + * } + * } + * + * `get_attribute()` will return `null` if the attribute wasn't present + * on the tag when it was called. It may return `""` (the empty string) + * in cases where the attribute was present but its value was empty. + * For boolean attributes, those whose name is present but no value is + * given, it will return `true` (the only way to set `false` for an + * attribute is to remove it). + * + * ### Modifying HTML attributes for a found tag + * + * Once you've found the start of an opening tag you can modify + * any number of the attributes on that tag. You can set a new + * value for an attribute, remove the entire attribute, or do + * nothing and move on to the next opening tag. + * + * Example: + * + * if ( $tags->next_tag( array( 'class_name' => 'wp-group-block' ) ) ) { + * $tags->set_attribute( 'title', 'This groups the contained content.' ); + * $tags->remove_attribute( 'data-test-id' ); + * } + * + * If `set_attribute()` is called for an existing attribute it will + * overwrite the existing value. Similarly, calling `remove_attribute()` + * for a non-existing attribute has no effect on the document. Both + * of these methods are safe to call without knowing if a given attribute + * exists beforehand. + * + * ### Modifying CSS classes for a found tag + * + * The tag processor treats the `class` attribute as a special case. + * Because it's a common operation to add or remove CSS classes, this + * interface adds helper methods to make that easier. + * + * As with attribute values, adding or removing CSS classes is a safe + * operation that doesn't require checking if the attribute or class + * exists before making changes. If removing the only class then the + * entire `class` attribute will be removed. + * + * Example: + * + * // from `Yippee!` + * // to `Yippee!` + * $tags->add_class( 'is-active' ); + * + * // from `Yippee!` + * // to `Yippee!` + * $tags->add_class( 'is-active' ); + * + * // from `Yippee!` + * // to `Yippee!` + * $tags->add_class( 'is-active' ); + * + * // from `` + * // to ` + * $tags->remove_class( 'rugby' ); + * + * // from `` + * // to ` + * $tags->remove_class( 'rugby' ); + * + * // from `` + * // to ` + * $tags->remove_class( 'rugby' ); + * + * When class changes are enqueued but a direct change to `class` is made via + * `set_attribute` then the changes to `set_attribute` (or `remove_attribute`) + * will take precedence over those made through `add_class` and `remove_class`. + * + * ### Bookmarks + * + * While scanning through the input HTMl document it's possible to set + * a named bookmark when a particular tag is found. Later on, after + * continuing to scan other tags, it's possible to `seek` to one of + * the set bookmarks and then proceed again from that point forward. + * + * Because bookmarks create processing overhead one should avoid + * creating too many of them. As a rule, create only bookmarks + * of known string literal names; avoid creating "mark_{$index}" + * and so on. It's fine from a performance standpoint to create a + * bookmark and update it frequently, such as within a loop. + * + * $total_todos = 0; + * while ( $p->next_tag( array( 'tag_name' => 'UL', 'class_name' => 'todo' ) ) ) { + * $p->set_bookmark( 'list-start' ); + * while ( $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) { + * if ( 'UL' === $p->get_tag() && $p->is_tag_closer() ) { + * $p->set_bookmark( 'list-end' ); + * $p->seek( 'list-start' ); + * $p->set_attribute( 'data-contained-todos', (string) $total_todos ); + * $total_todos = 0; + * $p->seek( 'list-end' ); + * break; + * } + * + * if ( 'LI' === $p->get_tag() && ! $p->is_tag_closer() ) { + * $total_todos++; + * } + * } + * } + * + * ## Design and limitations + * + * The Tag Processor is designed to linearly scan HTML documents and tokenize + * HTML tags and their attributes. It's designed to do this as efficiently as + * possible without compromising parsing integrity. Therefore it will be + * slower than some methods of modifying HTML, such as those incorporating + * over-simplified PCRE patterns, but will not introduce the defects and + * failures that those methods bring in, which lead to broken page renders + * and often to security vulnerabilities. On the other hand, it will be faster + * than full-blown HTML parsers such as DOMDocument and use considerably + * less memory. It requires a negligible memory overhead, enough to consider + * it a zero-overhead system. + * + * The performance characteristics are maintained by avoiding tree construction + * and semantic cleanups which are specified in HTML5. Because of this, for + * example, it's not possible for the Tag Processor to associate any given + * opening tag with its corresponding closing tag, or to return the inner markup + * inside an element. Systems may be built on top of the Tag Processor to do + * this, but the Tag Processor is and should be constrained so it can remain an + * efficient, low-level, and reliable HTML scanner. + * + * The Tag Processor's design incorporates a "garbage-in-garbage-out" philosophy. + * HTML5 specifies that certain invalid content be transformed into different forms + * for display, such as removing null bytes from an input document and replacing + * invalid characters with the Unicode replacement character `U+FFFD` (visually "�"). + * Where errors or transformations exist within the HTML5 specification, the Tag Processor + * leaves those invalid inputs untouched, passing them through to the final browser + * to handle. While this implies that certain operations will be non-spec-compliant, + * such as reading the value of an attribute with invalid content, it also preserves a + * simplicity and efficiency for handling those error cases. + * + * Most operations within the Tag Processor are designed to minimize the difference + * between an input and output document for any given change. For example, the + * `add_class` and `remove_class` methods preserve whitespace and the class ordering + * within the `class` attribute; and when encountering tags with duplicated attributes, + * the Tag Processor will leave those invalid duplicate attributes where they are but + * update the proper attribute which the browser will read for parsing its value. An + * exception to this rule is that all attribute updates store their values as + * double-quoted strings, meaning that attributes on input with single-quoted or + * unquoted values will appear in the output with double-quotes. + * + * @since 6.2.0 + * @since 6.2.1 Fix: Support for various invalid comments; attribute updates are case-insensitive. + * @since 6.3.2 Fix: Skip HTML-like content inside rawtext elements such as STYLE. + */ +class WP_HTML_Tag_Processor +{ + /** + * The maximum number of bookmarks allowed to exist at + * any given time. + * + * @since 6.2.0 + * + * @var int + * + * @see WP_HTML_Tag_Processor::set_bookmark() + */ + public const MAX_BOOKMARKS = 10; + + /** + * Maximum number of times seek() can be called. + * Prevents accidental infinite loops. + * + * @since 6.2.0 + * + * @var int + * + * @see WP_HTML_Tag_Processor::seek() + */ + public const MAX_SEEK_OPS = 1000; + + /** + * The HTML document to parse. + * + * @since 6.2.0 + * + * @var string + */ + protected $html; + + /** + * The last query passed to next_tag(). + * + * @since 6.2.0 + * + * @var array|null + */ + private $last_query; + + /** + * The tag name this processor currently scans for. + * + * @since 6.2.0 + * + * @var string|null + */ + private $sought_tag_name; + + /** + * The CSS class name this processor currently scans for. + * + * @since 6.2.0 + * + * @var string|null + */ + private $sought_class_name; + + /** + * The match offset this processor currently scans for. + * + * @since 6.2.0 + * + * @var int|null + */ + private $sought_match_offset; + + /** + * Whether to visit tag closers, e.g. , when walking an input document. + * + * @since 6.2.0 + * + * @var bool + */ + private $stop_on_tag_closers; + + /** + * How many bytes from the original HTML document have been read and parsed. + * + * This value points to the latest byte offset in the input document which + * has been already parsed. It is the internal cursor for the Tag Processor + * and updates while scanning through the HTML tokens. + * + * @since 6.2.0 + * + * @var int + */ + private $bytes_already_parsed = 0; + + /** + * Byte offset in input document where current token starts. + * + * Example: + * + *
... + * 01234 + * - token starts at 0 + * + * @since 6.5.0 + * + * @var int|null + */ + private $token_starts_at; + + /** + * Byte length of current token. + * + * Example: + * + *
... + * 012345678901234 + * - token length is 14 - 0 = 14 + * + * a is a token. + * 0123456789 123456789 123456789 + * - token length is 17 - 2 = 15 + * + * @since 6.5.0 + * + * @var int|null + */ + private $token_length; + + /** + * Byte offset in input document where current tag name starts. + * + * Example: + * + *
... + * 01234 + * - tag name starts at 1 + * + * @since 6.2.0 + * + * @var int|null + */ + private $tag_name_starts_at; + + /** + * Byte length of current tag name. + * + * Example: + * + *
... + * 01234 + * --- tag name length is 3 + * + * @since 6.2.0 + * + * @var int|null + */ + private $tag_name_length; + + /** + * Whether the current tag is an opening tag, e.g.
, or a closing tag, e.g.
. + * + * @var bool + */ + private $is_closing_tag; + + /** + * Lazily-built index of attributes found within an HTML tag, keyed by the attribute name. + * + * Example: + * + * // Supposing the parser is working through this content + * // and stops after recognizing the `id` attribute. + * //
+ * // ^ parsing will continue from this point. + * $this->attributes = array( + * 'id' => new WP_HTML_Attribute_Token( 'id', 9, 6, 5, 11, false ) + * ); + * + * // When picking up parsing again, or when asking to find the + * // `class` attribute we will continue and add to this array. + * $this->attributes = array( + * 'id' => new WP_HTML_Attribute_Token( 'id', 9, 6, 5, 11, false ), + * 'class' => new WP_HTML_Attribute_Token( 'class', 23, 7, 17, 13, false ) + * ); + * + * // Note that only the `class` attribute value is stored in the index. + * // That's because it is the only value used by this class at the moment. + * + * @since 6.2.0 + * + * @var WP_HTML_Attribute_Token[] + */ + private $attributes = []; + + /** + * Tracks spans of duplicate attributes on a given tag, used for removing + * all copies of an attribute when calling `remove_attribute()`. + * + * @since 6.3.2 + * + * @var (WP_HTML_Span[])[]|null + */ + private $duplicate_attributes; + + /** + * Which class names to add or remove from a tag. + * + * These are tracked separately from attribute updates because they are + * semantically distinct, whereas this interface exists for the common + * case of adding and removing class names while other attributes are + * generally modified as with DOM `setAttribute` calls. + * + * When modifying an HTML document these will eventually be collapsed + * into a single `set_attribute( 'class', $changes )` call. + * + * Example: + * + * // Add the `wp-block-group` class, remove the `wp-group` class. + * $classname_updates = array( + * // Indexed by a comparable class name. + * 'wp-block-group' => WP_HTML_Tag_Processor::ADD_CLASS, + * 'wp-group' => WP_HTML_Tag_Processor::REMOVE_CLASS + * ); + * + * @since 6.2.0 + * + * @var bool[] + */ + private $classname_updates = []; + + /** + * Tracks a semantic location in the original HTML which + * shifts with updates as they are applied to the document. + * + * @since 6.2.0 + * + * @var WP_HTML_Span[] + */ + protected $bookmarks = []; + + public const ADD_CLASS = true; + + public const REMOVE_CLASS = false; + + public const SKIP_CLASS = null; + + /** + * Lexical replacements to apply to input HTML document. + * + * "Lexical" in this class refers to the part of this class which + * operates on pure text _as text_ and not as HTML. There's a line + * between the public interface, with HTML-semantic methods like + * `set_attribute` and `add_class`, and an internal state that tracks + * text offsets in the input document. + * + * When higher-level HTML methods are called, those have to transform their + * operations (such as setting an attribute's value) into text diffing + * operations (such as replacing the sub-string from indices A to B with + * some given new string). These text-diffing operations are the lexical + * updates. + * + * As new higher-level methods are added they need to collapse their + * operations into these lower-level lexical updates since that's the + * Tag Processor's internal language of change. Any code which creates + * these lexical updates must ensure that they do not cross HTML syntax + * boundaries, however, so these should never be exposed outside of this + * class or any classes which intentionally expand its functionality. + * + * These are enqueued while editing the document instead of being immediately + * applied to avoid processing overhead, string allocations, and string + * copies when applying many updates to a single document. + * + * Example: + * + * // Replace an attribute stored with a new value, indices + * // sourced from the lazily-parsed HTML recognizer. + * $start = $attributes['src']->start; + * $length = $attributes['src']->length; + * $modifications[] = new WP_HTML_Text_Replacement( $start, $length, $new_value ); + * + * // Correspondingly, something like this will appear in this array. + * $lexical_updates = array( + * WP_HTML_Text_Replacement( 14, 28, 'https://my-site.my-domain/wp-content/uploads/2014/08/kittens.jpg' ) + * ); + * + * @since 6.2.0 + * + * @var WP_HTML_Text_Replacement[] + */ + protected $lexical_updates = []; + + /** + * Tracks and limits `seek()` calls to prevent accidental infinite loops. + * + * @since 6.2.0 + * + * @var int + * + * @see WP_HTML_Tag_Processor::seek() + */ + protected $seek_count = 0; + + /** + * Constructor. + * + * @since 6.2.0 + * + * @param string $html HTML to process. + */ + public function __construct($html) + { + $this->html = $html; + } + + /** + * Finds the next tag matching the $query. + * + * @since 6.2.0 + * + * @param array|string|null $query { + * Optional. Which tag name to find, having which class, etc. Default is to find any tag. + * + * @type string|null $tag_name Which tag to find, or `null` for "any tag." + * @type int|null $match_offset Find the Nth tag matching all search criteria. + * 1 for "first" tag, 3 for "third," etc. + * Defaults to first tag. + * @type string|null $class_name Tag must contain this whole class name to match. + * @type string|null $tag_closers "visit" or "skip": whether to stop on tag closers, e.g.
. + * } + * + * @return bool Whether a tag was matched. + */ + public function next_tag($query = null) + { + $this->parse_query($query); + $already_found = 0; + + do { + if ($this->bytes_already_parsed >= strlen($this->html)) { + return false; + } + + // Find the next tag if it exists. + if (false === $this->parse_next_tag()) { + $this->bytes_already_parsed = strlen($this->html); + + return false; + } + + // Parse all of its attributes. + while ($this->parse_next_attribute()) { + continue; + } + + // Ensure that the tag closes before the end of the document. + if ($this->bytes_already_parsed >= strlen($this->html)) { + return false; + } + + $tag_ends_at = strpos($this->html, '>', $this->bytes_already_parsed); + if (false === $tag_ends_at) { + return false; + } + $this->token_length = $tag_ends_at - $this->token_starts_at; + $this->bytes_already_parsed = $tag_ends_at; + + // Finally, check if the parsed tag and its attributes match the search query. + if ($this->matches()) { + ++$already_found; + } + + /* + * For non-DATA sections which might contain text that looks like HTML tags but + * isn't, scan with the appropriate alternative mode. Looking at the first letter + * of the tag name as a pre-check avoids a string allocation when it's not needed. + */ + $t = $this->html[$this->tag_name_starts_at]; + if ( + !$this->is_closing_tag && + ( + 'i' === $t || 'I' === $t || + 'n' === $t || 'N' === $t || + 's' === $t || 'S' === $t || + 't' === $t || 'T' === $t + )) { + $tag_name = $this->get_tag(); + + if ('SCRIPT' === $tag_name && !$this->skip_script_data()) { + $this->bytes_already_parsed = strlen($this->html); + return false; + } elseif ( + ('TEXTAREA' === $tag_name || 'TITLE' === $tag_name) && + !$this->skip_rcdata($tag_name) + ) { + $this->bytes_already_parsed = strlen($this->html); + return false; + } elseif ( + ( + 'IFRAME' === $tag_name || + 'NOEMBED' === $tag_name || + 'NOFRAMES' === $tag_name || + 'NOSCRIPT' === $tag_name || + 'STYLE' === $tag_name + ) && + !$this->skip_rawtext($tag_name) + ) { + /* + * "XMP" should be here too but its rules are more complicated and require the + * complexity of the HTML Processor (it needs to close out any open P element, + * meaning it can't be skipped here or else the HTML Processor will lose its + * place). For now, it can be ignored as it's a rare HTML tag in practice and + * any normative HTML should be using PRE instead. + */ + $this->bytes_already_parsed = strlen($this->html); + return false; + } + } + } while ($already_found < $this->sought_match_offset); + + return true; + } + + /** + * Generator for a foreach loop to step through each class name for the matched tag. + * + * This generator function is designed to be used inside a "foreach" loop. + * + * Example: + * + * $p = new WP_HTML_Tag_Processor( "
" ); + * $p->next_tag(); + * foreach ( $p->class_list() as $class_name ) { + * echo "{$class_name} "; + * } + * // Outputs: "free lang-en " + * + * @since 6.4.0 + */ + public function class_list() + { + /** + * @var string $class contains the string value of the class attribute, with character references decoded. + */ + $class = $this->get_attribute('class'); + + if (!is_string($class)) { + return; + } + + $seen = []; + + $at = 0; + while ($at < strlen($class)) { + // Skip past any initial boundary characters. + $at += strspn($class, " \t\f\r\n", $at); + if ($at >= strlen($class)) { + return; + } + + // Find the byte length until the next boundary. + $length = strcspn($class, " \t\f\r\n", $at); + if (0 === $length) { + return; + } + + /* + * CSS class names are case-insensitive in the ASCII range. + * + * @see https://www.w3.org/TR/CSS2/syndata.html#x1 + */ + $name = strtolower(substr($class, $at, $length)); + $at += $length; + + /* + * It's expected that the number of class names for a given tag is relatively small. + * Given this, it is probably faster overall to scan an array for a value rather + * than to use the class name as a key and check if it's a key of $seen. + */ + if (in_array($name, $seen, true)) { + continue; + } + + $seen[] = $name; + yield $name; + } + } + + /** + * Returns if a matched tag contains the given ASCII case-insensitive class name. + * + * @since 6.4.0 + * + * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive. + * + * @return bool|null Whether the matched tag contains the given class name, or null if not matched. + */ + public function has_class($wanted_class) + { + if (!$this->tag_name_starts_at) { + return null; + } + + $wanted_class = strtolower($wanted_class); + + foreach ($this->class_list() as $class_name) { + if ($class_name === $wanted_class) { + return true; + } + } + + return false; + } + + /** + * Sets a bookmark in the HTML document. + * + * Bookmarks represent specific places or tokens in the HTML + * document, such as a tag opener or closer. When applying + * edits to a document, such as setting an attribute, the + * text offsets of that token may shift; the bookmark is + * kept updated with those shifts and remains stable unless + * the entire span of text in which the token sits is removed. + * + * Release bookmarks when they are no longer needed. + * + * Example: + * + *

Surprising fact you may not know!

+ * ^ ^ + * \-|-- this `H2` opener bookmark tracks the token + * + *

Surprising fact you may no… + * ^ ^ + * \-|-- it shifts with edits + * + * Bookmarks provide the ability to seek to a previously-scanned + * place in the HTML document. This avoids the need to re-scan + * the entire document. + * + * Example: + * + *
  • One
  • Two
  • Three
+ * ^^^^ + * want to note this last item + * + * $p = new WP_HTML_Tag_Processor( $html ); + * $in_list = false; + * while ( $p->next_tag( array( 'tag_closers' => $in_list ? 'visit' : 'skip' ) ) ) { + * if ( 'UL' === $p->get_tag() ) { + * if ( $p->is_tag_closer() ) { + * $in_list = false; + * $p->set_bookmark( 'resume' ); + * if ( $p->seek( 'last-li' ) ) { + * $p->add_class( 'last-li' ); + * } + * $p->seek( 'resume' ); + * $p->release_bookmark( 'last-li' ); + * $p->release_bookmark( 'resume' ); + * } else { + * $in_list = true; + * } + * } + * + * if ( 'LI' === $p->get_tag() ) { + * $p->set_bookmark( 'last-li' ); + * } + * } + * + * Bookmarks intentionally hide the internal string offsets + * to which they refer. They are maintained internally as + * updates are applied to the HTML document and therefore + * retain their "position" - the location to which they + * originally pointed. The inability to use bookmarks with + * functions like `substr` is therefore intentional to guard + * against accidentally breaking the HTML. + * + * Because bookmarks allocate memory and require processing + * for every applied update, they are limited and require + * a name. They should not be created with programmatically-made + * names, such as "li_{$index}" with some loop. As a general + * rule they should only be created with string-literal names + * like "start-of-section" or "last-paragraph". + * + * Bookmarks are a powerful tool to enable complicated behavior. + * Consider double-checking that you need this tool if you are + * reaching for it, as inappropriate use could lead to broken + * HTML structure or unwanted processing overhead. + * + * @since 6.2.0 + * + * @param string $name Identifies this particular bookmark. + * + * @return bool Whether the bookmark was successfully created. + */ + public function set_bookmark($name) + { + if (null === $this->tag_name_starts_at) { + return false; + } + + if (!array_key_exists($name, $this->bookmarks) && count($this->bookmarks) >= static::MAX_BOOKMARKS) { + _doing_it_wrong( + __METHOD__, + __('Too many bookmarks: cannot create any more.'), + '6.2.0' + ); + return false; + } + + $this->bookmarks[$name] = new WP_HTML_Span($this->token_starts_at, $this->token_length); + + return true; + } + + /** + * Removes a bookmark that is no longer needed. + * + * Releasing a bookmark frees up the small + * performance overhead it requires. + * + * @param string $name Name of the bookmark to remove. + * + * @return bool Whether the bookmark already existed before removal. + */ + public function release_bookmark($name) + { + if (!array_key_exists($name, $this->bookmarks)) { + return false; + } + + unset($this->bookmarks[$name]); + + return true; + } + + /** + * Skips contents of generic rawtext elements. + * + * @since 6.3.2 + * @see https://html.spec.whatwg.org/#generic-raw-text-element-parsing-algorithm + * + * @param string $tag_name The uppercase tag name which will close the RAWTEXT region. + * + * @return bool Whether an end to the RAWTEXT region was found before the end of the document. + */ + private function skip_rawtext($tag_name) + { + /* + * These two functions distinguish themselves on whether character references are + * decoded, and since functionality to read the inner markup isn't supported, it's + * not necessary to implement these two functions separately. + */ + return $this->skip_rcdata($tag_name); + } + + /** + * Skips contents of RCDATA elements, namely title and textarea tags. + * + * @since 6.2.0 + * @see https://html.spec.whatwg.org/multipage/parsing.html#rcdata-state + * + * @param string $tag_name The uppercase tag name which will close the RCDATA region. + * + * @return bool Whether an end to the RCDATA region was found before the end of the document. + */ + private function skip_rcdata($tag_name) + { + $html = $this->html; + $doc_length = strlen($html); + $tag_length = strlen($tag_name); + + $at = $this->bytes_already_parsed; + + while (false !== $at && $at < $doc_length) { + $at = strpos($this->html, '= $doc_length) { + $this->bytes_already_parsed = $doc_length; + return false; + } + + $closer_potentially_starts_at = $at; + $at += 2; + + /* + * Find a case-insensitive match to the tag name. + * + * Because tag names are limited to US-ASCII there is no + * need to perform any kind of Unicode normalization when + * comparing; any character which could be impacted by such + * normalization could not be part of a tag name. + */ + for ($i = 0; $i < $tag_length; $i++) { + $tag_char = $tag_name[$i]; + $html_char = $html[$at + $i]; + + if ($html_char !== $tag_char && strtoupper($html_char) !== $tag_char) { + $at += $i; + continue 2; + } + } + + $at += $tag_length; + $this->bytes_already_parsed = $at; + + /* + * Ensure that the tag name terminates to avoid matching on + * substrings of a longer tag name. For example, the sequence + * "' !== $c) { + continue; + } + + while ($this->parse_next_attribute()) { + continue; + } + $at = $this->bytes_already_parsed; + if ($at >= strlen($this->html)) { + return false; + } + + if ('>' === $html[$at] || '/' === $html[$at]) { + $this->bytes_already_parsed = $closer_potentially_starts_at; + return true; + } + } + + return false; + } + + /** + * Skips contents of script tags. + * + * @since 6.2.0 + * + * @return bool Whether the script tag was closed before the end of the document. + */ + private function skip_script_data() + { + $state = 'unescaped'; + $html = $this->html; + $doc_length = strlen($html); + $at = $this->bytes_already_parsed; + + while (false !== $at && $at < $doc_length) { + $at += strcspn($html, '-<', $at); + + /* + * For all script states a "-->" transitions + * back into the normal unescaped script mode, + * even if that's the current state. + */ + if ( + $at + 2 < $doc_length && + '-' === $html[$at] && + '-' === $html[$at + 1] && + '>' === $html[$at + 2] + ) { + $at += 3; + $state = 'unescaped'; + continue; + } + + // Everything of interest past here starts with "<". + if ($at + 1 >= $doc_length || '<' !== $html[$at++]) { + continue; + } + + /* + * Unlike with "-->", the " + * https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state + */ + if ( + strlen($html) > $at + 3 && + '-' === $html[$at + 2] && + '-' === $html[$at + 3] + ) { + $closer_at = $at + 4; + // If it's not possible to close the comment then there is nothing more to scan. + if (strlen($html) <= $closer_at) { + return false; + } + + // Abruptly-closed empty comments are a sequence of dashes followed by `>`. + $span_of_dashes = strspn($html, '-', $closer_at); + if ('>' === $html[$closer_at + $span_of_dashes]) { + $at = $closer_at + $span_of_dashes + 1; + continue; + } + + /* + * Comments may be closed by either a --> or an invalid --!>. + * The first occurrence closes the comment. + * + * See https://html.spec.whatwg.org/#parse-error-incorrectly-closed-comment + */ + --$closer_at; // Pre-increment inside condition below reduces risk of accidental infinite looping. + while (++$closer_at < strlen($html)) { + $closer_at = strpos($html, '--', $closer_at); + if (false === $closer_at) { + return false; + } + + if ($closer_at + 2 < strlen($html) && '>' === $html[$closer_at + 2]) { + $at = $closer_at + 3; + continue 2; + } + + if ($closer_at + 3 < strlen($html) && '!' === $html[$closer_at + 2] && '>' === $html[$closer_at + 3]) { + $at = $closer_at + 4; + continue 2; + } + } + } + + /* + * + * The CDATA is case-sensitive. + * https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state + */ + if ( + strlen($html) > $at + 8 && + '[' === $html[$at + 2] && + 'C' === $html[$at + 3] && + 'D' === $html[$at + 4] && + 'A' === $html[$at + 5] && + 'T' === $html[$at + 6] && + 'A' === $html[$at + 7] && + '[' === $html[$at + 8] + ) { + $closer_at = strpos($html, ']]>', $at + 9); + if (false === $closer_at) { + return false; + } + + $at = $closer_at + 3; + continue; + } + + /* + * + * These are ASCII-case-insensitive. + * https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state + */ + if ( + strlen($html) > $at + 8 && + ('D' === $html[$at + 2] || 'd' === $html[$at + 2]) && + ('O' === $html[$at + 3] || 'o' === $html[$at + 3]) && + ('C' === $html[$at + 4] || 'c' === $html[$at + 4]) && + ('T' === $html[$at + 5] || 't' === $html[$at + 5]) && + ('Y' === $html[$at + 6] || 'y' === $html[$at + 6]) && + ('P' === $html[$at + 7] || 'p' === $html[$at + 7]) && + ('E' === $html[$at + 8] || 'e' === $html[$at + 8]) + ) { + $closer_at = strpos($html, '>', $at + 9); + if (false === $closer_at) { + return false; + } + + $at = $closer_at + 1; + continue; + } + + /* + * Anything else here is an incorrectly-opened comment and transitions + * to the bogus comment state - skip to the nearest >. + */ + $at = strpos($html, '>', $at + 1); + continue; + } + + /* + * is a missing end tag name, which is ignored. + * + * See https://html.spec.whatwg.org/#parse-error-missing-end-tag-name + */ + if ('>' === $html[$at + 1]) { + ++$at; + continue; + } + + /* + * + * See https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state + */ + if ('?' === $html[$at + 1]) { + $closer_at = strpos($html, '>', $at + 2); + if (false === $closer_at) { + return false; + } + + $at = $closer_at + 1; + continue; + } + + /* + * If a non-alpha starts the tag name in a tag closer it's a comment. + * Find the first `>`, which closes the comment. + * + * See https://html.spec.whatwg.org/#parse-error-invalid-first-character-of-tag-name + */ + if ($this->is_closing_tag) { + $closer_at = strpos($html, '>', $at + 3); + if (false === $closer_at) { + return false; + } + + $at = $closer_at + 1; + continue; + } + + ++$at; + } + + return false; + } + + /** + * Parses the next attribute. + * + * @since 6.2.0 + * + * @return bool Whether an attribute was found before the end of the document. + */ + private function parse_next_attribute() + { + // Skip whitespace and slashes. + $this->bytes_already_parsed += strspn($this->html, " \t\f\r\n/", $this->bytes_already_parsed); + if ($this->bytes_already_parsed >= strlen($this->html)) { + return false; + } + + /* + * Treat the equal sign as a part of the attribute + * name if it is the first encountered byte. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state + */ + $name_length = '=' === $this->html[$this->bytes_already_parsed] + ? 1 + strcspn($this->html, "=/> \t\f\r\n", $this->bytes_already_parsed + 1) + : strcspn($this->html, "=/> \t\f\r\n", $this->bytes_already_parsed); + + // No attribute, just tag closer. + if (0 === $name_length || $this->bytes_already_parsed + $name_length >= strlen($this->html)) { + return false; + } + + $attribute_start = $this->bytes_already_parsed; + $attribute_name = substr($this->html, $attribute_start, $name_length); + $this->bytes_already_parsed += $name_length; + if ($this->bytes_already_parsed >= strlen($this->html)) { + return false; + } + + $this->skip_whitespace(); + if ($this->bytes_already_parsed >= strlen($this->html)) { + return false; + } + + $has_value = '=' === $this->html[$this->bytes_already_parsed]; + if ($has_value) { + ++$this->bytes_already_parsed; + $this->skip_whitespace(); + if ($this->bytes_already_parsed >= strlen($this->html)) { + return false; + } + + switch ($this->html[$this->bytes_already_parsed]) { + case "'": + case '"': + $quote = $this->html[$this->bytes_already_parsed]; + $value_start = $this->bytes_already_parsed + 1; + $value_length = strcspn($this->html, $quote, $value_start); + $attribute_end = $value_start + $value_length + 1; + $this->bytes_already_parsed = $attribute_end; + break; + default: + $value_start = $this->bytes_already_parsed; + $value_length = strcspn($this->html, "> \t\f\r\n", $value_start); + $attribute_end = $value_start + $value_length; + $this->bytes_already_parsed = $attribute_end; + } + } else { + $value_start = $this->bytes_already_parsed; + $value_length = 0; + $attribute_end = $attribute_start + $name_length; + } + + if ($attribute_end >= strlen($this->html)) { + return false; + } + + if ($this->is_closing_tag) { + return true; + } + + /* + * > There must never be two or more attributes on + * > the same start tag whose names are an ASCII + * > case-insensitive match for each other. + * - HTML 5 spec + * + * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive + */ + $comparable_name = strtolower($attribute_name); + + // If an attribute is listed many times, only use the first declaration and ignore the rest. + if (!array_key_exists($comparable_name, $this->attributes)) { + $this->attributes[$comparable_name] = new WP_HTML_Attribute_Token( + $attribute_name, + $value_start, + $value_length, + $attribute_start, + $attribute_end - $attribute_start, + !$has_value + ); + + return true; + } + + /* + * Track the duplicate attributes so if we remove it, all disappear together. + * + * While `$this->duplicated_attributes` could always be stored as an `array()`, + * which would simplify the logic here, storing a `null` and only allocating + * an array when encountering duplicates avoids needless allocations in the + * normative case of parsing tags with no duplicate attributes. + */ + $duplicate_span = new WP_HTML_Span($attribute_start, $attribute_end - $attribute_start); + if (null === $this->duplicate_attributes) { + $this->duplicate_attributes = [$comparable_name => [$duplicate_span]]; + } elseif (!array_key_exists($comparable_name, $this->duplicate_attributes)) { + $this->duplicate_attributes[$comparable_name] = [$duplicate_span]; + } else { + $this->duplicate_attributes[$comparable_name][] = $duplicate_span; + } + + return true; + } + + /** + * Move the internal cursor past any immediate successive whitespace. + * + * @since 6.2.0 + */ + private function skip_whitespace() + { + $this->bytes_already_parsed += strspn($this->html, " \t\f\r\n", $this->bytes_already_parsed); + } + + /** + * Applies attribute updates and cleans up once a tag is fully parsed. + * + * @since 6.2.0 + */ + private function after_tag() + { + $this->get_updated_html(); + $this->token_starts_at = null; + $this->token_length = null; + $this->tag_name_starts_at = null; + $this->tag_name_length = null; + $this->is_closing_tag = null; + $this->attributes = []; + $this->duplicate_attributes = null; + } + + /** + * Converts class name updates into tag attributes updates + * (they are accumulated in different data formats for performance). + * + * @since 6.2.0 + * @see WP_HTML_Tag_Processor::$lexical_updates + * @see WP_HTML_Tag_Processor::$classname_updates + */ + private function class_name_updates_to_attributes_updates() + { + if (count($this->classname_updates) === 0) { + return; + } + + $existing_class = $this->get_enqueued_attribute_value('class'); + if (null === $existing_class || true === $existing_class) { + $existing_class = ''; + } + + if (false === $existing_class && isset($this->attributes['class'])) { + $existing_class = substr( + $this->html, + $this->attributes['class']->value_starts_at, + $this->attributes['class']->value_length + ); + } + + if (false === $existing_class) { + $existing_class = ''; + } + + /** + * Updated "class" attribute value. + * + * This is incrementally built while scanning through the existing class + * attribute, skipping removed classes on the way, and then appending + * added classes at the end. Only when finished processing will the + * value contain the final new value. + * + * @var string $class + */ + $class = ''; + + /** + * Tracks the cursor position in the existing + * class attribute value while parsing. + * + * @var int $at + */ + $at = 0; + + /** + * Indicates if there's any need to modify the existing class attribute. + * + * If a call to `add_class()` and `remove_class()` wouldn't impact + * the `class` attribute value then there's no need to rebuild it. + * For example, when adding a class that's already present or + * removing one that isn't. + * + * This flag enables a performance optimization when none of the enqueued + * class updates would impact the `class` attribute; namely, that the + * processor can continue without modifying the input document, as if + * none of the `add_class()` or `remove_class()` calls had been made. + * + * This flag is set upon the first change that requires a string update. + * + * @var bool $modified + */ + $modified = false; + + // Remove unwanted classes by only copying the new ones. + $existing_class_length = strlen($existing_class); + while ($at < $existing_class_length) { + // Skip to the first non-whitespace character. + $ws_at = $at; + $ws_length = strspn($existing_class, " \t\f\r\n", $ws_at); + $at += $ws_length; + + // Capture the class name – it's everything until the next whitespace. + $name_length = strcspn($existing_class, " \t\f\r\n", $at); + if (0 === $name_length) { + // If no more class names are found then that's the end. + break; + } + + $name = substr($existing_class, $at, $name_length); + $at += $name_length; + + // If this class is marked for removal, start processing the next one. + $remove_class = ( + isset($this->classname_updates[$name]) && + self::REMOVE_CLASS === $this->classname_updates[$name] + ); + + // If a class has already been seen then skip it; it should not be added twice. + if (!$remove_class) { + $this->classname_updates[$name] = self::SKIP_CLASS; + } + + if ($remove_class) { + $modified = true; + continue; + } + + /* + * Otherwise, append it to the new "class" attribute value. + * + * There are options for handling whitespace between tags. + * Preserving the existing whitespace produces fewer changes + * to the HTML content and should clarify the before/after + * content when debugging the modified output. + * + * This approach contrasts normalizing the inter-class + * whitespace to a single space, which might appear cleaner + * in the output HTML but produce a noisier change. + */ + $class .= substr($existing_class, $ws_at, $ws_length); + $class .= $name; + } + + // Add new classes by appending those which haven't already been seen. + foreach ($this->classname_updates as $name => $operation) { + if (self::ADD_CLASS === $operation) { + $modified = true; + + $class .= strlen($class) > 0 ? ' ' : ''; + $class .= $name; + } + } + + $this->classname_updates = []; + if (!$modified) { + return; + } + + if (strlen($class) > 0) { + $this->set_attribute('class', $class); + } else { + $this->remove_attribute('class'); + } + } + + /** + * Applies attribute updates to HTML document. + * + * @since 6.2.0 + * @since 6.2.1 Accumulates shift for internal cursor and passed pointer. + * @since 6.3.0 Invalidate any bookmarks whose targets are overwritten. + * + * @param int $shift_this_point Accumulate and return shift for this position. + * + * @return int How many bytes the given pointer moved in response to the updates. + */ + private function apply_attributes_updates($shift_this_point = 0) + { + if (!count($this->lexical_updates)) { + return 0; + } + + $accumulated_shift_for_given_point = 0; + + /* + * Attribute updates can be enqueued in any order but updates + * to the document must occur in lexical order; that is, each + * replacement must be made before all others which follow it + * at later string indices in the input document. + * + * Sorting avoid making out-of-order replacements which + * can lead to mangled output, partially-duplicated + * attributes, and overwritten attributes. + */ + usort($this->lexical_updates, [self::class, 'sort_start_ascending']); + + $bytes_already_copied = 0; + $output_buffer = ''; + foreach ($this->lexical_updates as $diff) { + $shift = strlen($diff->text) - $diff->length; + + // Adjust the cursor position by however much an update affects it. + if ($diff->start <= $this->bytes_already_parsed) { + $this->bytes_already_parsed += $shift; + } + + // Accumulate shift of the given pointer within this function call. + if ($diff->start <= $shift_this_point) { + $accumulated_shift_for_given_point += $shift; + } + + $output_buffer .= substr($this->html, $bytes_already_copied, $diff->start - $bytes_already_copied); + $output_buffer .= $diff->text; + $bytes_already_copied = $diff->start + $diff->length; + } + + $this->html = $output_buffer . substr($this->html, $bytes_already_copied); + + /* + * Adjust bookmark locations to account for how the text + * replacements adjust offsets in the input document. + */ + foreach ($this->bookmarks as $bookmark_name => $bookmark) { + $bookmark_end = $bookmark->start + $bookmark->length; + + /* + * Each lexical update which appears before the bookmark's endpoints + * might shift the offsets for those endpoints. Loop through each change + * and accumulate the total shift for each bookmark, then apply that + * shift after tallying the full delta. + */ + $head_delta = 0; + $tail_delta = 0; + + foreach ($this->lexical_updates as $diff) { + $diff_end = $diff->start + $diff->length; + + if ($bookmark->start < $diff->start && $bookmark_end < $diff->start) { + break; + } + + if ($bookmark->start >= $diff->start && $bookmark_end < $diff_end) { + $this->release_bookmark($bookmark_name); + continue 2; + } + + $delta = strlen($diff->text) - $diff->length; + + if ($bookmark->start >= $diff->start) { + $head_delta += $delta; + } + + if ($bookmark_end >= $diff_end) { + $tail_delta += $delta; + } + } + + $bookmark->start += $head_delta; + $bookmark->length += $tail_delta - $head_delta; + } + + $this->lexical_updates = []; + + return $accumulated_shift_for_given_point; + } + + /** + * Checks whether a bookmark with the given name exists. + * + * @since 6.3.0 + * + * @param string $bookmark_name Name to identify a bookmark that potentially exists. + * + * @return bool Whether that bookmark exists. + */ + public function has_bookmark($bookmark_name) + { + return array_key_exists($bookmark_name, $this->bookmarks); + } + + /** + * Move the internal cursor in the Tag Processor to a given bookmark's location. + * + * In order to prevent accidental infinite loops, there's a + * maximum limit on the number of times seek() can be called. + * + * @since 6.2.0 + * + * @param string $bookmark_name Jump to the place in the document identified by this bookmark name. + * + * @return bool Whether the internal cursor was successfully moved to the bookmark's location. + */ + public function seek($bookmark_name) + { + if (!array_key_exists($bookmark_name, $this->bookmarks)) { + _doing_it_wrong( + __METHOD__, + __('Unknown bookmark name.'), + '6.2.0' + ); + return false; + } + + if (++$this->seek_count > static::MAX_SEEK_OPS) { + _doing_it_wrong( + __METHOD__, + __('Too many calls to seek() - this can lead to performance issues.'), + '6.2.0' + ); + return false; + } + + // Flush out any pending updates to the document. + $this->get_updated_html(); + + // Point this tag processor before the sought tag opener and consume it. + $this->bytes_already_parsed = $this->bookmarks[$bookmark_name]->start; + return $this->next_tag(['tag_closers' => 'visit']); + } + + /** + * Compare two WP_HTML_Text_Replacement objects. + * + * @since 6.2.0 + * + * @param WP_HTML_Text_Replacement $a First attribute update. + * @param WP_HTML_Text_Replacement $b Second attribute update. + * + * @return int Comparison value for string order. + */ + private static function sort_start_ascending($a, $b) + { + $by_start = $a->start - $b->start; + if (0 !== $by_start) { + return $by_start; + } + + $by_text = isset($a->text, $b->text) ? strcmp($a->text, $b->text) : 0; + if (0 !== $by_text) { + return $by_text; + } + + /* + * This code should be unreachable, because it implies the two replacements + * start at the same location and contain the same text. + */ + return $a->length - $b->length; + } + + /** + * Return the enqueued value for a given attribute, if one exists. + * + * Enqueued updates can take different data types: + * - If an update is enqueued and is boolean, the return will be `true` + * - If an update is otherwise enqueued, the return will be the string value of that update. + * - If an attribute is enqueued to be removed, the return will be `null` to indicate that. + * - If no updates are enqueued, the return will be `false` to differentiate from "removed." + * + * @since 6.2.0 + * + * @param string $comparable_name The attribute name in its comparable form. + * + * @return string|boolean|null Value of enqueued update if present, otherwise false. + */ + private function get_enqueued_attribute_value($comparable_name) + { + if (!isset($this->lexical_updates[$comparable_name])) { + return false; + } + + $enqueued_text = $this->lexical_updates[$comparable_name]->text; + + // Removed attributes erase the entire span. + if ('' === $enqueued_text) { + return null; + } + + /* + * Boolean attribute updates are just the attribute name without a corresponding value. + * + * This value might differ from the given comparable name in that there could be leading + * or trailing whitespace, and that the casing follows the name given in `set_attribute`. + * + * Example: + * + * $p->set_attribute( 'data-TEST-id', 'update' ); + * 'update' === $p->get_enqueued_attribute_value( 'data-test-id' ); + * + * Detect this difference based on the absence of the `=`, which _must_ exist in any + * attribute containing a value, e.g. ``. + * ¹ ² + * 1. Attribute with a string value. + * 2. Boolean attribute whose value is `true`. + */ + $equals_at = strpos($enqueued_text, '='); + if (false === $equals_at) { + return true; + } + + /* + * Finally, a normal update's value will appear after the `=` and + * be double-quoted, as performed incidentally by `set_attribute`. + * + * e.g. `type="text"` + * ¹² ³ + * 1. Equals is here. + * 2. Double-quoting starts one after the equals sign. + * 3. Double-quoting ends at the last character in the update. + */ + $enqueued_value = substr($enqueued_text, $equals_at + 2, -1); + return html_entity_decode($enqueued_value); + } + + /** + * Returns the value of a requested attribute from a matched tag opener if that attribute exists. + * + * Example: + * + * $p = new WP_HTML_Tag_Processor( '
Test
' ); + * $p->next_tag( array( 'class_name' => 'test' ) ) === true; + * $p->get_attribute( 'data-test-id' ) === '14'; + * $p->get_attribute( 'enabled' ) === true; + * $p->get_attribute( 'aria-label' ) === null; + * + * $p->next_tag() === false; + * $p->get_attribute( 'class' ) === null; + * + * @since 6.2.0 + * + * @param string $name Name of attribute whose value is requested. + * + * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`. + */ + public function get_attribute($name) + { + if (null === $this->tag_name_starts_at) { + return null; + } + + $comparable = strtolower($name); + + /* + * For every attribute other than `class` it's possible to perform a quick check if + * there's an enqueued lexical update whose value takes priority over what's found in + * the input document. + * + * The `class` attribute is special though because of the exposed helpers `add_class` + * and `remove_class`. These form a builder for the `class` attribute, so an additional + * check for enqueued class changes is required in addition to the check for any enqueued + * attribute values. If any exist, those enqueued class changes must first be flushed out + * into an attribute value update. + */ + if ('class' === $name) { + $this->class_name_updates_to_attributes_updates(); + } + + // Return any enqueued attribute value updates if they exist. + $enqueued_value = $this->get_enqueued_attribute_value($comparable); + if (false !== $enqueued_value) { + return $enqueued_value; + } + + if (!isset($this->attributes[$comparable])) { + return null; + } + + $attribute = $this->attributes[$comparable]; + + /* + * This flag distinguishes an attribute with no value + * from an attribute with an empty string value. For + * unquoted attributes this could look very similar. + * It refers to whether an `=` follows the name. + * + * e.g.
+ * ¹ ² + * 1. Attribute `boolean-attribute` is `true`. + * 2. Attribute `empty-attribute` is `""`. + */ + if (true === $attribute->is_true) { + return true; + } + + $raw_value = substr($this->html, $attribute->value_starts_at, $attribute->value_length); + + return html_entity_decode($raw_value); + } + + /** + * Gets lowercase names of all attributes matching a given prefix in the current tag. + * + * Note that matching is case-insensitive. This is in accordance with the spec: + * + * > There must never be two or more attributes on + * > the same start tag whose names are an ASCII + * > case-insensitive match for each other. + * - HTML 5 spec + * + * Example: + * + * $p = new WP_HTML_Tag_Processor( '
Test
' ); + * $p->next_tag( array( 'class_name' => 'test' ) ) === true; + * $p->get_attribute_names_with_prefix( 'data-' ) === array( 'data-enabled', 'data-test-id' ); + * + * $p->next_tag() === false; + * $p->get_attribute_names_with_prefix( 'data-' ) === null; + * + * @since 6.2.0 + * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive + * + * @param string $prefix Prefix of requested attribute names. + * + * @return array|null List of attribute names, or `null` when no tag opener is matched. + */ + public function get_attribute_names_with_prefix($prefix) + { + if ($this->is_closing_tag || null === $this->tag_name_starts_at) { + return null; + } + + $comparable = strtolower($prefix); + + $matches = []; + foreach (array_keys($this->attributes) as $attr_name) { + if (str_starts_with($attr_name, $comparable)) { + $matches[] = $attr_name; + } + } + return $matches; + } + + /** + * Returns the uppercase name of the matched tag. + * + * Example: + * + * $p = new WP_HTML_Tag_Processor( '
Test
' ); + * $p->next_tag() === true; + * $p->get_tag() === 'DIV'; + * + * $p->next_tag() === false; + * $p->get_tag() === null; + * + * @since 6.2.0 + * + * @return string|null Name of currently matched tag in input HTML, or `null` if none found. + */ + public function get_tag() + { + if (null === $this->tag_name_starts_at) { + return null; + } + + $tag_name = substr($this->html, $this->tag_name_starts_at, $this->tag_name_length); + + return strtoupper($tag_name); + } + + /** + * Indicates if the currently matched tag contains the self-closing flag. + * + * No HTML elements ought to have the self-closing flag and for those, the self-closing + * flag will be ignored. For void elements this is benign because they "self close" + * automatically. For non-void HTML elements though problems will appear if someone + * intends to use a self-closing element in place of that element with an empty body. + * For HTML foreign elements and custom elements the self-closing flag determines if + * they self-close or not. + * + * This function does not determine if a tag is self-closing, + * but only if the self-closing flag is present in the syntax. + * + * @since 6.3.0 + * + * @return bool Whether the currently matched tag contains the self-closing flag. + */ + public function has_self_closing_flag() + { + if (!$this->tag_name_starts_at) { + return false; + } + + /* + * The self-closing flag is the solidus at the _end_ of the tag, not the beginning. + * + * Example: + * + *
+ * ^ this appears one character before the end of the closing ">". + */ + return '/' === $this->html[$this->token_starts_at + $this->token_length - 1]; + } + + /** + * Indicates if the current tag token is a tag closer. + * + * Example: + * + * $p = new WP_HTML_Tag_Processor( '
' ); + * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) ); + * $p->is_tag_closer() === false; + * + * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) ); + * $p->is_tag_closer() === true; + * + * @since 6.2.0 + * + * @return bool Whether the current tag is a tag closer. + */ + public function is_tag_closer() + { + return $this->is_closing_tag; + } + + /** + * Updates or creates a new attribute on the currently matched tag with the passed value. + * + * For boolean attributes special handling is provided: + * - When `true` is passed as the value, then only the attribute name is added to the tag. + * - When `false` is passed, the attribute gets removed if it existed before. + * + * For string attributes, the value is escaped using the `esc_attr` function. + * + * @since 6.2.0 + * @since 6.2.1 Fix: Only create a single update for multiple calls with case-variant attribute names. + * + * @param string $name The attribute name to target. + * @param string|bool $value The new attribute value. + * + * @return bool Whether an attribute value was set. + */ + public function set_attribute($name, $value) + { + if ($this->is_closing_tag || null === $this->tag_name_starts_at) { + return false; + } + + /* + * WordPress rejects more characters than are strictly forbidden + * in HTML5. This is to prevent additional security risks deeper + * in the WordPress and plugin stack. Specifically the + * less-than (<) greater-than (>) and ampersand (&) aren't allowed. + * + * The use of a PCRE match enables looking for specific Unicode + * code points without writing a UTF-8 decoder. Whereas scanning + * for one-byte characters is trivial (with `strcspn`), scanning + * for the longer byte sequences would be more complicated. Given + * that this shouldn't be in the hot path for execution, it's a + * reasonable compromise in efficiency without introducing a + * noticeable impact on the overall system. + * + * @see https://html.spec.whatwg.org/#attributes-2 + * + * @todo As the only regex pattern maybe we should take it out? + * Are Unicode patterns available broadly in Core? + */ + if (preg_match( + '~[' . + // Syntax-like characters. + '"\'>& The values "true" and "false" are not allowed on boolean attributes. + * > To represent a false value, the attribute has to be omitted altogether. + * - HTML5 spec, https://html.spec.whatwg.org/#boolean-attributes + */ + if (false === $value) { + return $this->remove_attribute($name); + } + + if (true === $value) { + $updated_attribute = $name; + } else { + $escaped_new_value = esc_attr($value); + $updated_attribute = "{$name}=\"{$escaped_new_value}\""; + } + + /* + * > There must never be two or more attributes on + * > the same start tag whose names are an ASCII + * > case-insensitive match for each other. + * - HTML 5 spec + * + * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive + */ + $comparable_name = strtolower($name); + + if (isset($this->attributes[$comparable_name])) { + /* + * Update an existing attribute. + * + * Example – set attribute id to "new" in
: + * + *
+ * ^-------------^ + * start end + * replacement: `id="new"` + * + * Result:
+ */ + $existing_attribute = $this->attributes[$comparable_name]; + $this->lexical_updates[$comparable_name] = new WP_HTML_Text_Replacement( + $existing_attribute->start, + $existing_attribute->length, + $updated_attribute + ); + } else { + /* + * Create a new attribute at the tag's name end. + * + * Example – add attribute id="new" to
: + * + *
+ * ^ + * start and end + * replacement: ` id="new"` + * + * Result:
+ */ + $this->lexical_updates[$comparable_name] = new WP_HTML_Text_Replacement( + $this->tag_name_starts_at + $this->tag_name_length, + 0, + ' ' . $updated_attribute + ); + } + + /* + * Any calls to update the `class` attribute directly should wipe out any + * enqueued class changes from `add_class` and `remove_class`. + */ + if ('class' === $comparable_name && !empty($this->classname_updates)) { + $this->classname_updates = []; + } + + return true; + } + + /** + * Remove an attribute from the currently-matched tag. + * + * @since 6.2.0 + * + * @param string $name The attribute name to remove. + * + * @return bool Whether an attribute was removed. + */ + public function remove_attribute($name) + { + if ($this->is_closing_tag) { + return false; + } + + /* + * > There must never be two or more attributes on + * > the same start tag whose names are an ASCII + * > case-insensitive match for each other. + * - HTML 5 spec + * + * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive + */ + $name = strtolower($name); + + /* + * Any calls to update the `class` attribute directly should wipe out any + * enqueued class changes from `add_class` and `remove_class`. + */ + if ('class' === $name && count($this->classname_updates) !== 0) { + $this->classname_updates = []; + } + + /* + * If updating an attribute that didn't exist in the input + * document, then remove the enqueued update and move on. + * + * For example, this might occur when calling `remove_attribute()` + * after calling `set_attribute()` for the same attribute + * and when that attribute wasn't originally present. + */ + if (!isset($this->attributes[$name])) { + if (isset($this->lexical_updates[$name])) { + unset($this->lexical_updates[$name]); + } + return false; + } + + /* + * Removes an existing tag attribute. + * + * Example – remove the attribute id from
: + *
+ * ^-------------^ + * start end + * replacement: `` + * + * Result:
+ */ + $this->lexical_updates[$name] = new WP_HTML_Text_Replacement( + $this->attributes[$name]->start, + $this->attributes[$name]->length, + '' + ); + + // Removes any duplicated attributes if they were also present. + if (null !== $this->duplicate_attributes && array_key_exists($name, $this->duplicate_attributes)) { + foreach ($this->duplicate_attributes[$name] as $attribute_token) { + $this->lexical_updates[] = new WP_HTML_Text_Replacement( + $attribute_token->start, + $attribute_token->length, + '' + ); + } + } + + return true; + } + + /** + * Adds a new class name to the currently matched tag. + * + * @since 6.2.0 + * + * @param string $class_name The class name to add. + * + * @return bool Whether the class was set to be added. + */ + public function add_class($class_name) + { + if ($this->is_closing_tag) { + return false; + } + + if (null !== $this->tag_name_starts_at) { + $this->classname_updates[$class_name] = self::ADD_CLASS; + } + + return true; + } + + /** + * Removes a class name from the currently matched tag. + * + * @since 6.2.0 + * + * @param string $class_name The class name to remove. + * + * @return bool Whether the class was set to be removed. + */ + public function remove_class($class_name) + { + if ($this->is_closing_tag) { + return false; + } + + if (null !== $this->tag_name_starts_at) { + $this->classname_updates[$class_name] = self::REMOVE_CLASS; + } + + return true; + } + + /** + * Returns the string representation of the HTML Tag Processor. + * + * @since 6.2.0 + * @see WP_HTML_Tag_Processor::get_updated_html() + * + * @return string The processed HTML. + */ + public function __toString() + { + return $this->get_updated_html(); + } + + /** + * Returns the string representation of the HTML Tag Processor. + * + * @since 6.2.0 + * @since 6.2.1 Shifts the internal cursor corresponding to the applied updates. + * @since 6.4.0 No longer calls subclass method `next_tag()` after updating HTML. + * + * @return string The processed HTML. + */ + public function get_updated_html() + { + $requires_no_updating = 0 === count($this->classname_updates) && 0 === count($this->lexical_updates); + + /* + * When there is nothing more to update and nothing has already been + * updated, return the original document and avoid a string copy. + */ + if ($requires_no_updating) { + return $this->html; + } + + /* + * Keep track of the position right before the current tag. This will + * be necessary for reparsing the current tag after updating the HTML. + */ + $before_current_tag = $this->token_starts_at; + + /* + * 1. Apply the enqueued edits and update all the pointers to reflect those changes. + */ + $this->class_name_updates_to_attributes_updates(); + $before_current_tag += $this->apply_attributes_updates($before_current_tag); + + /* + * 2. Rewind to before the current tag and reparse to get updated attributes. + * + * At this point the internal cursor points to the end of the tag name. + * Rewind before the tag name starts so that it's as if the cursor didn't + * move; a call to `next_tag()` will reparse the recently-updated attributes + * and additional calls to modify the attributes will apply at this same + * location, but in order to avoid issues with subclasses that might add + * behaviors to `next_tag()`, the internal methods should be called here + * instead. + * + * It's important to note that in this specific place there will be no change + * because the processor was already at a tag when this was called and it's + * rewinding only to the beginning of this very tag before reprocessing it + * and its attributes. + * + *

Previous HTMLMore HTML

+ * ↑ │ back up by the length of the tag name plus the opening < + * └←─┘ back up by strlen("em") + 1 ==> 3 + */ + $this->bytes_already_parsed = $before_current_tag; + $this->parse_next_tag(); + // Reparse the attributes. + while ($this->parse_next_attribute()) { + continue; + } + + $tag_ends_at = strpos($this->html, '>', $this->bytes_already_parsed); + $this->token_length = $tag_ends_at - $this->token_starts_at; + $this->bytes_already_parsed = $tag_ends_at; + + return $this->html; + } + + /** + * Parses tag query input into internal search criteria. + * + * @since 6.2.0 + * + * @param array|string|null $query { + * Optional. Which tag name to find, having which class, etc. Default is to find any tag. + * + * @type string|null $tag_name Which tag to find, or `null` for "any tag." + * @type int|null $match_offset Find the Nth tag matching all search criteria. + * 1 for "first" tag, 3 for "third," etc. + * Defaults to first tag. + * @type string|null $class_name Tag must contain this class name to match. + * @type string $tag_closers "visit" or "skip": whether to stop on tag closers, e.g.
. + * } + */ + private function parse_query($query) + { + if (null !== $query && $query === $this->last_query) { + return; + } + + $this->last_query = $query; + $this->sought_tag_name = null; + $this->sought_class_name = null; + $this->sought_match_offset = 1; + $this->stop_on_tag_closers = false; + + // A single string value means "find the tag of this name". + if (is_string($query)) { + $this->sought_tag_name = $query; + return; + } + + // An empty query parameter applies no restrictions on the search. + if (null === $query) { + return; + } + + // If not using the string interface, an associative array is required. + if (!is_array($query)) { + _doing_it_wrong( + __METHOD__, + __('The query argument must be an array or a tag name.'), + '6.2.0' + ); + return; + } + + if (isset($query['tag_name']) && is_string($query['tag_name'])) { + $this->sought_tag_name = $query['tag_name']; + } + + if (isset($query['class_name']) && is_string($query['class_name'])) { + $this->sought_class_name = $query['class_name']; + } + + if (isset($query['match_offset']) && is_int($query['match_offset']) && 0 < $query['match_offset']) { + $this->sought_match_offset = $query['match_offset']; + } + + if (isset($query['tag_closers'])) { + $this->stop_on_tag_closers = 'visit' === $query['tag_closers']; + } + } + + /** + * Checks whether a given tag and its attributes match the search criteria. + * + * @since 6.2.0 + * + * @return bool Whether the given tag and its attribute match the search criteria. + */ + private function matches() + { + if ($this->is_closing_tag && !$this->stop_on_tag_closers) { + return false; + } + + // Does the tag name match the requested tag name in a case-insensitive manner? + if (null !== $this->sought_tag_name) { + /* + * String (byte) length lookup is fast. If they aren't the + * same length then they can't be the same string values. + */ + if (strlen($this->sought_tag_name) !== $this->tag_name_length) { + return false; + } + + /* + * Check each character to determine if they are the same. + * Defer calls to `strtoupper()` to avoid them when possible. + * Calling `strcasecmp()` here tested slowed than comparing each + * character, so unless benchmarks show otherwise, it should + * not be used. + * + * It's expected that most of the time that this runs, a + * lower-case tag name will be supplied and the input will + * contain lower-case tag names, thus normally bypassing + * the case comparison code. + */ + for ($i = 0; $i < $this->tag_name_length; $i++) { + $html_char = $this->html[$this->tag_name_starts_at + $i]; + $tag_char = $this->sought_tag_name[$i]; + + if ($html_char !== $tag_char && strtoupper($html_char) !== $tag_char) { + return false; + } + } + } + + if (null !== $this->sought_class_name && !$this->has_class($this->sought_class_name)) { + return false; + } + + return true; + } + + /** + * Modifications by IndexedSearch + */ + public function get_token_starts_at() + { + return $this->token_starts_at; + } + + public function get_token_ends_at() + { + return $this->token_starts_at + $this->token_length; + } + + public function get_is_closing_tag() + { + return $this->is_closing_tag; + } + + public function substr(int $offset, ?int $length = null) + { + return substr($this->html, $offset, $length); + } +} diff --git a/src/Contracts/EngineContract.php b/src/Contracts/EngineContract.php new file mode 100644 index 0000000..444c86c --- /dev/null +++ b/src/Contracts/EngineContract.php @@ -0,0 +1,46 @@ + + */ + public static function splitOnWhitespace(string $text): array + { + $result = preg_split('/\s+/', $text, -1, PREG_SPLIT_NO_EMPTY); + + if ($result === false) { + throw new \IndexedSearch\Exceptions\TokenizationException(); + } + + return $result; + } + + /** + * @return array + */ + public static function splitWords(string $text): array + { + $result = preg_split(self::$splitWordsPattern, $text, -1, PREG_SPLIT_NO_EMPTY); + + if ($result === false) { + throw new \IndexedSearch\Exceptions\TokenizationException(); + } + + return $result; + } +} diff --git a/src/Index/IndexRepository.php b/src/Index/IndexRepository.php new file mode 100644 index 0000000..66f2800 --- /dev/null +++ b/src/Index/IndexRepository.php @@ -0,0 +1,8 @@ + + * + * Simple stemmer for arabic language rewritten by Nenad Tičarić + * + * @link https://github.com/teamtnt/tntsearch + * + * Copyright (c) 2016 Nenad Tičarić nticaric@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +namespace IndexedSearch\Stemmer; + +class ArabicStemmer implements Stemmer +{ + private static $_verbPre = 'وأسفلي'; + + private static $_verbPost = 'ومكانيه'; + + private static $_verbMay; + + private static $_verbMaxPre = 4; + + private static $_verbMaxPost = 6; + + private static $_verbMinStem = 2; + + private static $_nounPre = 'ابفكلوأ'; + + private static $_nounPost = 'اتةكمنهوي'; + + private static $_nounMay; + + private static $_nounMaxPre = 4; + + private static $_nounMaxPost = 6; + + private static $_nounMinStem = 2; + + /** + * Loads initialize values + * + * @ignore + */ + public function __construct() + { + self::$_verbMay = self::$_verbPre . self::$_verbPost; + self::$_nounMay = self::$_nounPre . self::$_nounPost; + } + + /** + * Get rough stem of the given Arabic word + * + * @param string $word Arabic word you would like to get its stem + * + * @return string Arabic stem of the word + * + * @author Khaled Al-Sham'aa + */ + public static function stem($word) + { + $nounStem = self::roughStem( + $word, + self::$_nounMay, + self::$_nounPre, + self::$_nounPost, + self::$_nounMaxPre, + self::$_nounMaxPost, + self::$_nounMinStem + ); + $verbStem = self::roughStem( + $word, + self::$_verbMay, + self::$_verbPre, + self::$_verbPost, + self::$_verbMaxPre, + self::$_verbMaxPost, + self::$_verbMinStem + ); + + if (mb_strlen($nounStem, 'UTF-8') < mb_strlen($verbStem, 'UTF-8')) { + $stem = $nounStem; + } else { + $stem = $verbStem; + } + + return $stem; + } + + /** + * Get rough stem of the given Arabic word (under specific rules) + * + * @param string $word Arabic word you would like to get its stem + * @param string $notChars Arabic chars those can't be in postfix or prefix + * @param string $preChars Arabic chars those may exists in the prefix + * @param string $postChars Arabic chars those may exists in the postfix + * @param integer $maxPre Max prefix length + * @param integer $maxPost Max postfix length + * @param integer $minStem Min stem length + * + * @return string Arabic stem of the word under giving rules + * + * @author Khaled Al-Sham'aa + */ + protected static function roughStem( + $word, + $notChars, + $preChars, + $postChars, + $maxPre, + $maxPost, + $minStem + ) { + $right = -1; + $left = -1; + $max = mb_strlen($word, 'UTF-8'); + + for ($i = 0; $i < $max; $i++) { + $needle = mb_substr($word, $i, 1, 'UTF-8'); + if (mb_strpos($notChars, $needle, 0, 'UTF-8') === false) { + if ($right == -1) { + $right = $i; + } + $left = $i; + } + } + + if ($right > $maxPre) { + $right = $maxPre; + } + + if ($max - $left - 1 > $maxPost) { + $left = $max - $maxPost - 1; + } + + for ($i = 0; $i < $right; $i++) { + $needle = mb_substr($word, $i, 1, 'UTF-8'); + if (mb_strpos($preChars, $needle, 0, 'UTF-8') === false) { + $right = $i; + break; + } + } + + for ($i = $max - 1; $i > $left; $i--) { + $needle = mb_substr($word, $i, 1, 'UTF-8'); + if (mb_strpos($postChars, $needle, 0, 'UTF-8') === false) { + $left = $i; + break; + } + } + + if ($left - $right >= $minStem) { + $stem = mb_substr($word, $right, $left - $right + 1, 'UTF-8'); + } else { + $stem = null; + } + + return $stem; + } +} diff --git a/src/Stemmer/CroatianStemmer.php b/src/Stemmer/CroatianStemmer.php new file mode 100644 index 0000000..bfef18a --- /dev/null +++ b/src/Stemmer/CroatianStemmer.php @@ -0,0 +1,340 @@ + 0) { + return true; + } + + return false; + } + + public static function transformiraj($pojavnica) + { + foreach (self::$transformations as $trazi => $zamijeni) { + if (self::endsWith($pojavnica, $trazi)) { + return substr($pojavnica, 0, -1 * strlen($trazi)) . $zamijeni; + } + } + return $pojavnica; + } + + public static function korjenuj($pojavnica) + { + foreach (self::$rules as $rule) { + $rules = explode(' ', $rule); + $osnova = $rules[0]; + $nastavak = $rules[1]; + preg_match('/^(' . $osnova . ')(' . $nastavak . ')$/', $pojavnica, $dioba); + if (!empty($dioba)) { + if (self::imaSamoglasnik($dioba[1]) && strlen($dioba[1]) > 1) { + return $dioba[1]; + } + } + } + return $pojavnica; + } + + public static function endsWith($haystack, $needle) + { + // search forward starting from end minus needle length characters + return $needle === '' || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false); + } + + protected static $transformations = [ + 'lozi' => 'loga', + 'lozima' => 'loga', + 'pjesi' => 'pjeh', + 'pjesima' => 'pjeh', + 'vojci' => 'vojka', + 'bojci' => 'bojka', + 'jaci' => 'jak', + 'jacima' => 'jak', + 'čajan' => 'čajni', + 'ijeran' => 'ijerni', + 'laran' => 'larni', + 'ijesan' => 'ijesni', + 'anjac' => 'anjca', + 'ajac' => 'ajca', + 'ajaca' => 'ajca', + 'ljaca' => 'ljca', + 'ljac' => 'ljca', + 'ejac' => 'ejca', + 'ejaca' => 'ejca', + 'ojac' => 'ojca', + 'ojaca' => 'ojca', + 'ajaka' => 'ajka', + 'ojaka' => 'ojka', + 'šaca' => 'šca', + 'šac' => 'šca', + 'inzima' => 'ing', + 'inzi' => 'ing', + 'tvenici' => 'tvenik', + 'tetici' => 'tetika', + 'teticima' => 'tetika', + 'nstava' => 'nstva', + 'nicima' => 'nik', + 'ticima' => 'tik', + 'zicima' => 'zik', + 'snici' => 'snik', + 'kuse' => 'kusi', + 'kusan' => 'kusni', + 'kustava' => 'kustva', + 'dušan' => 'dušni', + 'antan' => 'antni', + 'bilan' => 'bilni', + 'tilan' => 'tilni', + 'avilan' => 'avilni', + 'silan' => 'silni', + 'gilan' => 'gilni', + 'rilan' => 'rilni', + 'nilan' => 'nilni', + 'alan' => 'alni', + 'ozan' => 'ozni', + 'rave' => 'ravi', + 'stavan' => 'stavni', + 'pravan' => 'pravni', + 'tivan' => 'tivni', + 'sivan' => 'sivni', + 'atan' => 'atni', + 'cenata' => 'centa', + 'denata' => 'denta', + 'genata' => 'genta', + 'lenata' => 'lenta', + 'menata' => 'menta', + 'jenata' => 'jenta', + 'venata' => 'venta', + 'tetan' => 'tetni', + 'pletan' => 'pletni', + 'šave' => 'šavi', + 'manata' => 'manta', + 'tanata' => 'tanta', + 'lanata' => 'lanta', + 'sanata' => 'santa', + 'ačak' => 'ačka', + 'ačaka' => 'ačka', + 'ušak' => 'uška', + 'atak' => 'atka', + 'ataka' => 'atka', + 'atci' => 'atka', + 'atcima' => 'atka', + 'etak' => 'etka', + 'etaka' => 'etka', + 'itak' => 'itka', + 'itaka' => 'itka', + 'itci' => 'itka', + 'otak' => 'otka', + 'otaka' => 'otka', + 'utak' => 'utka', + 'utaka' => 'utka', + 'utci' => 'utka', + 'utcima' => 'utka', + 'eskan' => 'eskna', + 'tičan' => 'tični', + 'ojsci' => 'ojska', + 'esama' => 'esma', + 'metara' => 'metra', + 'centar' => 'centra', + 'centara' => 'centra', + 'istara' => 'istra', + 'istar' => 'istra', + 'ošću' => 'osti', + 'daba' => 'dba', + 'čcima' => 'čka', + 'čci' => 'čka', + 'mac' => 'mca', + 'maca' => 'mca', + 'naca' => 'nca', + 'nac' => 'nca', + 'voljan' => 'voljni', + 'anaka' => 'anki', + 'vac' => 'vca', + 'vaca' => 'vca', + 'saca' => 'sca', + 'sac' => 'sca', + 'naca' => 'nca', + 'nac' => 'nca', + 'raca' => 'rca', + 'rac' => 'rca', + 'aoca' => 'alca', + 'alaca' => 'alca', + 'alac' => 'alca', + 'elaca' => 'elca', + 'elac' => 'elca', + 'olaca' => 'olca', + 'olac' => 'olca', + 'olce' => 'olca', + 'njac' => 'njca', + 'njaca' => 'njca', + 'ekata' => 'ekta', + 'ekat' => 'ekta', + 'izam' => 'izma', + 'izama' => 'izma', + 'jebe' => 'jebi', + 'baci' => 'baci', + 'ašan' => 'ašni', + ]; + + protected static $rules = [ + '.+(s|š)k ijima|ijega|ijemu|ijem|ijim|ijih|ijoj|ijeg|iji|ije|ija|oga|ome|omu|ima|og|om|im|ih|oj|i|e|o|a|u', + '.+(s|š)tv ima|om|o|a|u', + // N + '.+(t|m|p|r|g)anij ama|ima|om|a|u|e|i| ', + '.+an inom|ina|inu|ine|ima|in|om|u|i|a|e| ', + '.+in ima|ama|om|a|e|i|u|o| ', + '.+on ovima|ova|ove|ovi|ima|om|a|e|i|u| ', + '.+n ijima|ijega|ijemu|ijeg|ijem|ijim|ijih|ijoj|iji|ije|ija|iju|ima|ome|omu|oga|oj|om|ih|im|og|o|e|a|u|i| ', + // Ć + '.+(a|e|u)ć oga|ome|omu|ega|emu|ima|oj|ih|om|eg|em|og|uh|im|e|a', + // G + '.+ugov ima|i|e|a', + '.+ug ama|om|a|e|i|u|o', + '.+log ama|om|a|u|e| ', + '.+[^eo]g ovima|ama|ovi|ove|ova|om|a|e|i|u|o| ', + // I + '.+(rrar|ott|ss|ll)i jem|ja|ju|o| ', + // J + '.+uj ući|emo|ete|mo|em|eš|e|u| ', + '.+(c|č|ć|đ|l|r)aj evima|evi|eva|eve|ama|ima|em|a|e|i|u| ', + '.+(b|c|d|l|n|m|ž|g|f|p|r|s|t|z)ij ima|ama|om|a|e|i|u|o| ', + // L + //.+al inom|ina|inu|ine|ima|om|in|i|a|e + //.+[^(lo|ž)]il ima|om|a|e|u|i| + '.+[^z]nal ima|ama|om|a|e|i|u|o| ', + '.+ijal ima|ama|om|a|e|i|u|o| ', + '.+ozil ima|om|a|e|u|i| ', + '.+olov ima|i|a|e', + '.+ol ima|om|a|u|e|i| ', + // M + '.+lem ama|ima|om|a|e|i|u|o| ', + '.+ram ama|om|a|e|i|u|o', + //.+(es|e|u)m ama|om|a|e|i|u|o + // R + //.+(a|d|e|o|u)r ama|ima|om|u|a|e|i| + '.+(a|d|e|o)r ama|ima|om|u|a|e|i| ', + // S + '.+(e|i)s ima|om|e|a|u', + // Š + '.+(t|n|j|k|j|t|b|g|v)aš ama|ima|om|em|a|u|i|e| ', + '.+(e|i)š ima|ama|om|em|i|e|a|u| ', + // T + '.+ikat ima|om|a|e|i|u|o| ', + '.+lat ima|om|a|e|i|u|o| ', + '.+et ama|ima|om|a|e|i|u|o| ', + //.+ot ama|ima|om|a|u|e|i| + '.+(e|i|k|o)st ima|ama|om|a|e|i|u|o| ', + '.+išt ima|em|a|e|u', + //.+ut ovima|evima|ove|ovi|ova|eve|evi|eva|ima|om|a|u|e|i| + // V + '.+ova smo|ste|hu|ti|še|li|la|le|lo|t|h|o', + '.+(a|e|i)v ijemu|ijima|ijega|ijeg|ijem|ijim|ijih|ijoj|oga|ome|omu|ima|ama|iji|ije|ija|iju|im|ih|oj|om|og|i|a|u|e|o| ', + '.+[^dkml]ov ijemu|ijima|ijega|ijeg|ijem|ijim|ijih|ijoj|oga|ome|omu|ima|iji|ije|ija|iju|im|ih|oj|om|og|i|a|u|e|o| ', + '.+(m|l)ov ima|om|a|u|e|i| ', + // PRIDJEVI + '.+el ijemu|ijima|ijega|ijeg|ijem|ijim|ijih|ijoj|oga|ome|omu|ima|iji|ije|ija|iju|im|ih|oj|om|og|i|a|u|e|o| ', + '.+(a|e|š)nj ijemu|ijima|ijega|ijeg|ijem|ijim|ijih|ijoj|oga|ome|omu|ima|iji|ije|ija|iju|ega|emu|eg|em|im|ih|oj|om|og|a|e|i|o|u', + '.+čin ama|ome|omu|oga|ima|og|om|im|ih|oj|a|u|i|o|e| ', + '.+roši vši|smo|ste|še|mo|te|ti|li|la|lo|le|m|š|t|h|o', + '.+oš ijemu|ijima|ijega|ijeg|ijem|ijim|ijih|ijoj|oga|ome|omu|ima|iji|ije|ija|iju|im|ih|oj|om|og|i|a|u|e| ', + '.+(e|o)vit ijima|ijega|ijemu|ijem|ijim|ijih|ijoj|ijeg|iji|ije|ija|oga|ome|omu|ima|og|om|im|ih|oj|i|e|o|a|u| ', + //.+tit ijima|ijega|ijemu|ijem|ijim|ijih|ijoj|ijeg|iji|ije|ija|oga|ome|omu|ima|og|om|im|ih|oj|e|o|a|u|i| + '.+ast ijima|ijega|ijemu|ijem|ijim|ijih|ijoj|ijeg|iji|ije|ija|oga|ome|omu|ima|og|om|im|ih|oj|i|e|o|a|u| ', + '.+k ijemu|ijima|ijega|ijeg|ijem|ijim|ijih|ijoj|oga|ome|omu|ima|iji|ije|ija|iju|im|ih|oj|om|og|i|a|u|e|o| ', + // GLAGOLI + '.+(e|a|i|u)va jući|smo|ste|jmo|jte|ju|la|le|li|lo|mo|na|ne|ni|no|te|ti|še|hu|h|j|m|n|o|t|v|š| ', + '.+ir ujemo|ujete|ujući|ajući|ivat|ujem|uješ|ujmo|ujte|avši|asmo|aste|ati|amo|ate|aju|aše|ahu|ala|alo|ali|ale|uje|uju|uj|al|an|am|aš|at|ah|ao', + '.+ač ismo|iste|iti|imo|ite|iše|eći|ila|ilo|ili|ile|ena|eno|eni|ene|io|im|iš|it|ih|en|i|e', + '.+ača vši|smo|ste|smo|ste|hu|ti|mo|te|še|la|lo|li|le|ju|na|no|ni|ne|o|m|š|t|h|n', + //.+ači smo|ste|ti|li|la|lo|le|mo|te|še|m|š|t|h|o| + // Druga_vrsta + '.+n uvši|usmo|uste|ući|imo|ite|emo|ete|ula|ulo|ule|uli|uto|uti|uta|em|eš|uo|ut|e|u|i', + '.+ni vši|smo|ste|ti|mo|te|mo|te|la|lo|le|li|m|š|o', + // A + '.+((a|r|i|p|e|u)st|[^o]g|ik|uc|oj|aj|lj|ak|ck|čk|šk|uk|nj|im|ar|at|et|št|it|ot|ut|zn|zv)a jući|vši|smo|ste|jmo|jte|jem|mo|te|je|ju|ti|še|hu|la|li|le|lo|na|no|ni|ne|t|h|o|j|n|m|š', + '.+ur ajući|asmo|aste|ajmo|ajte|amo|ate|aju|ati|aše|ahu|ala|ali|ale|alo|ana|ano|ani|ane|al|at|ah|ao|aj|an|am|aš', + '.+(a|i|o)staj asmo|aste|ahu|ati|emo|ete|aše|ali|ući|ala|alo|ale|mo|ao|em|eš|at|ah|te|e|u| ', + '.+(b|c|č|ć|d|e|f|g|j|k|n|r|t|u|v)a lama|lima|lom|lu|li|la|le|lo|l', + '.+(t|č|j|ž|š)aj evima|evi|eva|eve|ama|ima|em|a|e|i|u| ', + //.+(e|j|k|r|u|v)al ama|ima|om|u|i|a|e|o| + //.+(e|j|k|r|t|u|v)al ih|im + '.+([^o]m|ič|nč|uč|b|c|ć|d|đ|h|j|k|l|n|p|r|s|š|v|z|ž)a jući|vši|smo|ste|jmo|jte|mo|te|ju|ti|še|hu|la|li|le|lo|na|no|ni|ne|t|h|o|j|n|m|š', + '.+(a|i|o)sta dosmo|doste|doše|nemo|demo|nete|dete|nimo|nite|nila|vši|nem|dem|neš|deš|doh|de|ti|ne|nu|du|la|li|lo|le|t|o', + '.+ta smo|ste|jmo|jte|vši|ti|mo|te|ju|še|la|lo|le|li|na|no|ni|ne|n|j|o|m|š|t|h', + '.+inj asmo|aste|ati|emo|ete|ali|ala|alo|ale|aše|ahu|em|eš|at|ah|ao', + '.+as temo|tete|timo|tite|tući|tem|teš|tao|te|li|ti|la|lo|le', + // I + '.+(elj|ulj|tit|ac|ič|od|oj|et|av|ov)i vši|eći|smo|ste|še|mo|te|ti|li|la|lo|le|m|š|t|h|o', + '.+(tit|jeb|ar|ed|uš|ič)i jemo|jete|jem|ješ|smo|ste|jmo|jte|vši|mo|še|te|ti|ju|je|la|lo|li|le|t|m|š|h|j|o', + '.+(b|č|d|l|m|p|r|s|š|ž)i jemo|jete|jem|ješ|smo|ste|jmo|jte|vši|mo|lu|še|te|ti|ju|je|la|lo|li|le|t|m|š|h|j|o', + '.+luč ujete|ujući|ujemo|ujem|uješ|ismo|iste|ujmo|ujte|uje|uju|iše|iti|imo|ite|ila|ilo|ili|ile|ena|eno|eni|ene|uj|io|en|im|iš|it|ih|e|i', + '.+jeti smo|ste|še|mo|te|ti|li|la|lo|le|m|š|t|h|o', + '.+e lama|lima|lom|lu|li|la|le|lo|l', + '.+i lama|lima|lom|lu|li|la|le|lo|l', + // Pridjev_t + '.+at ijega|ijemu|ijima|ijeg|ijem|ijih|ijim|ima|oga|ome|omu|iji|ije|ija|iju|oj|og|om|im|ih|a|u|i|e|o| ', + // Pridjev + '.+et avši|ući|emo|imo|em|eš|e|u|i', + '.+ ajući|alima|alom|avši|asmo|aste|ajmo|ajte|ivši|amo|ate|aju|ati|aše|ahu|ali|ala|ale|alo|ana|ano|ani|ane|am|aš|at|ah|ao|aj|an', + '.+ anje|enje|anja|enja|enom|enoj|enog|enim|enih|anom|anoj|anog|anim|anih|eno|ovi|ova|oga|ima|ove|enu|anu|ena|ama', + '.+ nijega|nijemu|nijima|nijeg|nijem|nijim|nijih|nima|niji|nije|nija|niju|noj|nom|nog|nim|nih|an|na|nu|ni|ne|no', + '.+ om|og|im|ih|em|oj|an|u|o|i|e|a', + ]; +} diff --git a/src/Stemmer/FrenchStemmer.php b/src/Stemmer/FrenchStemmer.php new file mode 100644 index 0000000..b4044bc --- /dev/null +++ b/src/Stemmer/FrenchStemmer.php @@ -0,0 +1,720 @@ +analyze($word); + } + + public function analyze($word) + { + $this->word = mb_strtolower($word); + + $this->plainVowels = implode('', static::$vowels); + + $this->step0(); + + $this->rv(); + $this->r1(); + $this->r2(); + + // to know if step1, 2a or 2b have altered the word + $this->originalWord = $this->word; + + $nextStep = $this->step1(); + + // Do step 2a if either no ending was removed by step 1, or if one of endings amment, emment, ment, ments was found. + if (($nextStep == 2) || ($this->originalWord === $this->word)) { + $modified = $this->step2a(); + + if (!$modified) { + $this->step2b(); + } + } + + if ($this->word != $this->originalWord) { + $this->step3(); + } else { + $this->step4(); + } + + $this->step5(); + $this->step6(); + $this->finish(); + + return $this->word; + } + + /** + * Assume the word is in lower case. + * Then put into upper case u or i preceded and followed by a vowel, and y preceded or followed by a vowel. + * u after q is also put into upper case. For example, + * jouer -> joUer + * ennuie -> ennuIe + * yeux -> Yeux + * quand -> qUand + */ + private function step0() + { + $this->word = preg_replace('#([q])u#u', '$1U', $this->word); + $this->word = preg_replace('#(['.$this->plainVowels.'])y#u', '$1Y', $this->word); + $this->word = preg_replace('#y(['.$this->plainVowels.'])#u', 'Y$1', $this->word); + $this->word = preg_replace('#(['.$this->plainVowels.'])u(['.$this->plainVowels.'])#u', '$1U$2', $this->word); + $this->word = preg_replace('#(['.$this->plainVowels.'])i(['.$this->plainVowels.'])#u', '$1I$2', $this->word); + } + + /** + * Step 1 + * Search for the longest among the following suffixes, and perform the action indicated. + * + * @return integer Next step number + */ + private function step1() + { + // ance iqUe isme able iste eux ances iqUes ismes ables istes + // delete if in R2 + if (($position = $this->search([ + 'ances', 'iqUes', 'ismes', 'ables', 'istes', 'ance', 'iqUe', 'isme', 'able', 'iste', 'eux', + ])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } + + return 3; + } + + // atrice ateur ation atrices ateurs ations + // delete if in R2 + // if preceded by ic, delete if in R2, else replace by iqU + if (($position = $this->search(['atrices', 'ateurs', 'ations', 'atrice', 'ateur', 'ation'])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + + if (($position2 = $this->searchIfInR2(['ic'])) !== false) { + $this->word = mb_substr($this->word, 0, $position2); + } else { + $this->word = preg_replace('#(ic)$#u', 'iqU', $this->word); + } + } + + return 3; + } + + // logie logies + // replace with log if in R2 + if (($position = $this->search(['logies', 'logie'])) !== false) { + if ($this->inR2($position)) { + $this->word = preg_replace('#(logies|logie)$#u', 'log', $this->word); + } + + return 3; + } + + // usion ution usions utions + // replace with u if in R2 + if (($position = $this->search(['usions', 'utions', 'usion', 'ution'])) !== false) { + if ($this->inR2($position)) { + $this->word = preg_replace('#(usion|ution|usions|utions)$#u', 'u', $this->word); + } + + return 3; + } + + // ence ences + // replace with ent if in R2 + if (($position = $this->search(['ences', 'ence'])) !== false) { + if ($this->inR2($position)) { + $this->word = preg_replace('#(ence|ences)$#u', 'ent', $this->word); + } + + return 3; + } + + // issement issements + // delete if in R1 and preceded by a non-vowel + if (($position = $this->search(['issements', 'issement'])) != false) { + if ($this->inR1($position)) { + $before = $position - 1; + $letter = mb_substr($this->word, $before, 1); + + if (!in_array($letter, static::$vowels)) { + $this->word = mb_substr($this->word, 0, $position); + } + } + + return 3; + } + + // ement ements + // delete if in RV + // if preceded by iv, delete if in R2 (and if further preceded by at, delete if in R2), otherwise, + // if preceded by eus, delete if in R2, else replace by eux if in R1, otherwise, + // if preceded by abl or iqU, delete if in R2, otherwise, + // if preceded by ièr or Ièr, replace by i if in RV + if (($position = $this->search(['ements', 'ement'])) !== false) { + if ($this->inRv($position)) { + $this->word = mb_substr($this->word, 0, $position); + } + + if (($position = $this->searchIfInR2(['iv'])) !== false) { + $this->word = mb_substr($this->word, 0, $position); + + if (($position2 = $this->searchIfInR2(['at'])) !== false) { + $this->word = mb_substr($this->word, 0, $position2); + } + } elseif (($position = $this->search(['eus'])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } elseif ($this->inR1($position)) { + $this->word = preg_replace('#(eus)$#u', 'eux', $this->word); + } + } elseif (($position = $this->searchIfInR2(['abl', 'iqU'])) !== false) { + $this->word = mb_substr($this->word, 0, $position); + } elseif (($this->searchIfInRv(['ièr', 'Ièr'])) !== false) { + $this->word = preg_replace('#(ièr|Ièr)$#u', 'i', $this->word); + } + + return 3; + } + + // ité ités + // delete if in R2 + // if preceded by abil, delete if in R2, else replace by abl, otherwise, + // if preceded by ic, delete if in R2, else replace by iqU, otherwise, + // if preceded by iv, delete if in R2 + if (($position = $this->search(['ités', 'ité'])) !== false) { + // delete if in R2 + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } + + // if preceded by abil, delete if in R2, else replace by abl, otherwise, + if (($position = $this->search(['abil'])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } else { + $this->word = preg_replace('#(abil)$#u', 'abl', $this->word); + } + + // if preceded by ic, delete if in R2, else replace by iqU, otherwise, + } elseif (($position = $this->search(['ic'])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } else { + $this->word = preg_replace('#(ic)$#u', 'iqU', $this->word); + } + + // if preceded by iv, delete if in R2 + } elseif (($position = $this->searchIfInR2(['iv'])) !== false) { + $this->word = mb_substr($this->word, 0, $position); + } + + return 3; + } + + // if ive ifs ives + // delete if in R2 + // if preceded by at, delete if in R2 (and if further preceded by ic, delete if in R2, else replace by iqU) + if (($position = $this->search(['ifs', 'ives', 'if', 'ive'])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } + + if (($position = $this->searchIfInR2(['at'])) !== false) { + $this->word = mb_substr($this->word, 0, $position); + + if (($position2 = $this->search(['ic'])) !== false) { + if ($this->inR2($position2)) { + $this->word = mb_substr($this->word, 0, $position2); + } else { + $this->word = preg_replace('#(ic)$#u', 'iqU', $this->word); + } + } + } + + return 3; + } + + // eaux + // replace with eau + if (($this->search(['eaux'])) !== false) { + $this->word = preg_replace('#(eaux)$#u', 'eau', $this->word); + + return 3; + } + + // aux + // replace with al if in R1 + if (($position = $this->search(['aux'])) !== false) { + if ($this->inR1($position)) { + $this->word = preg_replace('#(aux)$#u', 'al', $this->word); + } + + return 3; + } + + // euse euses + // delete if in R2, else replace by eux if in R1 + if (($position = $this->search(['euses', 'euse'])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } elseif ($this->inR1($position)) { + $this->word = preg_replace('#(euses|euse)$#u', 'eux', $this->word); + } + + return 3; + } + + // amment + // replace with ant if in RV + if (($position = $this->search(['amment'])) !== false) { + if ($this->inRv($position)) { + $this->word = preg_replace('#(amment)$#u', 'ant', $this->word); + } + return 2; + } + + // emment + // replace with ent if in RV + if (($position = $this->search(['emment'])) !== false) { + if ($this->inRv($position)) { + $this->word = preg_replace('#(emment)$#u', 'ent', $this->word); + } + + return 2; + } + + // ment ments + // delete if preceded by a vowel in RV + if (($position = $this->search(['ments', 'ment'])) != false) { + $before = $position - 1; + $letter = mb_substr($this->word, $before, 1); + + if ($this->inRv($before) && (in_array($letter, static::$vowels))) { + $this->word = mb_substr($this->word, 0, $position); + } + + return 2; + } + + return 2; + } + + /** + * Step 2a: Verb suffixes beginning i + * In steps 2a and 2b all tests are confined to the RV region. + * Search for the longest among the following suffixes and if found, delete if preceded by a non-vowel. + * îmes ît îtes i ie ies ir ira irai iraIent irais irait iras irent irez iriez + * irions irons iront is issaIent issais issait issant issante issantes issants isse + * issent isses issez issiez issions issons it + * (Note that the non-vowel itself must also be in RV.) + */ + private function step2a() + { + if (($position = $this->searchIfInRv([ + 'îmes', 'îtes', 'ît', 'ies', 'ie', 'iraIent', 'irais', 'irait', 'irai', 'iras', 'ira', 'irent', 'irez', 'iriez', + 'irions', 'irons', 'iront', 'ir', 'issaIent', 'issais', 'issait', 'issant', 'issantes', 'issante', 'issants', + 'issent', 'isses', 'issez', 'isse', 'issiez', 'issions', 'issons', 'is', 'it', 'i'])) !== false) { + $before = $position - 1; + $letter = mb_substr($this->word, $before, 1); + + if ($this->inRv($before) && (!in_array($letter, static::$vowels))) { + $this->word = mb_substr($this->word, 0, $position); + + return true; + } + } + + return false; + } + + /** + * Do step 2b if step 2a was done, but failed to remove a suffix. + * Step 2b: Other verb suffixes + */ + private function step2b() + { + // é ée ées és èrent er era erai eraIent erais erait eras erez eriez erions erons eront ez iez + // delete + if (($position = $this->searchIfInRv([ + 'ées', 'èrent', 'erais', 'erait', 'erai', 'eraIent', 'eras', 'erez', 'eriez', + 'erions', 'erons', 'eront', 'era', 'er', 'iez', 'ez', 'és', 'ée', 'é'])) !== false) { + $this->word = mb_substr($this->word, 0, $position); + + return true; + } + + // âmes ât âtes a ai aIent ais ait ant ante antes ants as asse assent asses assiez assions + // delete + // if preceded by e, delete + if (($position = $this->searchIfInRv([ + 'âmes', 'âtes', 'ât', 'aIent', 'ais', 'ait', 'antes', 'ante', 'ants', 'ant', + 'assent', 'asses', 'assiez', 'assions', 'asse', 'as', 'ai', 'a'])) !== false) { + $before = $position - 1; + $letter = mb_substr($this->word, $before, 1); + + if ($this->inRv($before) && ($letter === 'e')) { + $this->word = mb_substr($this->word, 0, $before); + } else { + $this->word = mb_substr($this->word, 0, $position); + } + + return true; + } + + // ions + // delete if in R2 + if (($position = $this->searchIfInRv(['ions'])) !== false) { + if ($this->inR2($position)) { + $this->word = mb_substr($this->word, 0, $position); + } + + return true; + } + + return false; + } + + /** + * Step 3: Replace final Y with i or final ç with c + */ + private function step3() + { + $this->word = preg_replace('#(Y)$#u', 'i', $this->word); + $this->word = preg_replace('#(ç)$#u', 'c', $this->word); + } + + /** + * Step 4: Residual suffix + */ + private function step4() + { + //If the word ends s, not preceded by a, i, o, u, è or s, delete it. + if (preg_match('#[^aiouès]s$#', $this->word)) { + $this->word = mb_substr($this->word, 0, -1); + } + + // In the rest of step 4, all tests are confined to the RV region. + // ion + // delete if in R2 and preceded by s or t + if ((($position = $this->searchIfInRv(['ion'])) !== false) && ($this->inR2($position))) { + $before = $position - 1; + $letter = mb_substr($this->word, $before, 1); + + if ($this->inRv($before) && (($letter === 's') || ($letter === 't'))) { + $this->word = mb_substr($this->word, 0, $position); + } + + return true; + } + + // ier ière Ier Ière + // replace with i + if (($this->searchIfInRv(['ier', 'ière', 'Ier', 'Ière'])) !== false) { + $this->word = preg_replace('#(ier|ière|Ier|Ière)$#u', 'i', $this->word); + + return true; + } + + // e + // delete + if (($this->searchIfInRv(['e'])) !== false) { + $this->word = mb_substr($this->word, 0, -1); + + return true; + } + + // ë + // if preceded by gu, delete + if (($position = $this->searchIfInRv(['guë'])) !== false) { + if ($this->inRv($position + 2)) { + $this->word = mb_substr($this->word, 0, -1); + + return true; + } + } + + return false; + } + + /** + * Step 5: Undouble + * If the word ends enn, onn, ett, ell or eill, delete the last letter + */ + private function step5() + { + if ($this->search(['enn', 'onn', 'ett', 'ell', 'eill']) !== false) { + $this->word = mb_substr($this->word, 0, -1); + } + } + + /** + * Step 6: Un-accent + * If the words ends é or è followed by at least one non-vowel, remove the accent from the e. + */ + private function step6() + { + $this->word = preg_replace('#(é|è)([^'.$this->plainVowels.']+)$#u', 'e$2', $this->word); + } + + /** + * And finally: + * Turn any remaining I, U and Y letters in the word back into lower case. + */ + private function finish() + { + $this->word = str_replace(['I', 'U', 'Y'], ['i', 'u', 'y'], $this->word); + } + + /** + * If the word begins with two vowels, RV is the region after the third letter, + * otherwise the region after the first vowel not at the beginning of the word, + * or the end of the word if these positions cannot be found. + * (Exceptionally, par, col or tap, at the begining of a word is also taken to define RV as the region to their right.) + */ + protected function rv() + { + $length = mb_strlen($this->word); + + $this->rv = ''; + $this->rvIndex = $length; + + if ($length < 3) { + return true; + } + + // If the word begins with two vowels, RV is the region after the third letter + $first = mb_substr($this->word, 0, 1); + $second = mb_substr($this->word, 1, 1); + + if ((in_array($first, static::$vowels)) && (in_array($second, static::$vowels))) { + $this->rv = mb_substr($this->word, 3); + $this->rvIndex = 3; + + return true; + } + + // (Exceptionally, par, col or tap, at the begining of a word is also taken to define RV as the region to their right.) + $begin3 = mb_substr($this->word, 0, 3); + + if (in_array($begin3, ['par', 'col', 'tap'])) { + $this->rv = mb_substr($this->word, 3); + $this->rvIndex = 3; + + return true; + } + + // otherwise the region after the first vowel not at the beginning of the word, + for ($i = 1; $i < $length; ++$i) { + $letter = mb_substr($this->word, $i, 1); + + if (in_array($letter, static::$vowels)) { + $this->rv = mb_substr($this->word, ($i + 1)); + $this->rvIndex = $i + 1; + + return true; + } + } + + return false; + } + + protected function inRv($position) + { + return ($position >= $this->rvIndex); + } + + protected function inR1($position) + { + return ($position >= $this->r1Index); + } + + protected function inR2($position) + { + return ($position >= $this->r2Index); + } + + protected function searchIfInRv($suffixes) + { + return $this->search($suffixes, $this->rvIndex); + } + + protected function searchIfInR2($suffixes) + { + return $this->search($suffixes, $this->r2Index); + } + + protected function search($suffixes, $offset = 0) + { + $length = mb_strlen($this->word); + + if ($offset > $length) { + return false; + } + + foreach ($suffixes as $suffixe) { + if ((($position = mb_strrpos($this->word, $suffixe, $offset)) !== false) + && ((mb_strlen($suffixe) + $position) == $length)) { + return $position; + } + } + + return false; + } + + /** + * R1 is the region after the first non-vowel following a vowel, or the end of the word if there is no such non-vowel. + */ + protected function r1() + { + [$this->r1Index, $this->r1] = $this->rx($this->word); + } + + /** + * R2 is the region after the first non-vowel following a vowel in R1, or the end of the word if there is no such non-vowel. + */ + protected function r2() + { + [$index, $value] = $this->rx($this->r1); + + $this->r2 = $value; + $this->r2Index = $this->r1Index + $index; + } + + /** + * Common function for R1 and R2 + * Search the region after the first non-vowel following a vowel in $word, or the end of the word if there is no such non-vowel. + * R1 : $in = $this->word + * R2 : $in = R1 + */ + protected function rx($in) + { + $length = mb_strlen($in); + + // defaults + $value = ''; + $index = $length; + + // we search all vowels + $vowels = []; + + for ($i = 0; $i < $length; ++$i) { + $letter = mb_substr($in, $i, 1); + + if (in_array($letter, static::$vowels)) { + $vowels[] = $i; + } + } + + // search the non-vowel following a vowel + foreach ($vowels as $position) { + $after = $position + 1; + $letter = mb_substr($in, $after, 1); + + if (!in_array($letter, static::$vowels)) { + $index = $after + 1; + $value = mb_substr($in, ($after + 1)); + + break; + } + } + + return [$index, $value]; + } +} diff --git a/src/Stemmer/GermanStemmer.php b/src/Stemmer/GermanStemmer.php new file mode 100644 index 0000000..27e67bc --- /dev/null +++ b/src/Stemmer/GermanStemmer.php @@ -0,0 +1,258 @@ + + * @author Pascal Landau + */ + +class GermanStemmer implements Stemmer +{ + /** + * R1 and R2 regions (see the Porter algorithm) + */ + private static $R1; + + private static $R2; + + private static $cache = []; + + private static $vowels = ['a', 'e', 'i', 'o', 'u', 'y', 'ä', 'ö', 'ü']; + + private static $s_ending = ['b', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 'n', 'r', 't']; + + private static $st_ending = ['b', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 'n', 't']; + + /** + * Gets the stem of $word. + * + * @param string $word + * + * @return string + */ + public static function stem($word) + { + $word = mb_strtolower($word); + //check for invalid characters + preg_match('#.#u', $word); + if (preg_last_error() !== 0) { + throw new \InvalidArgumentException("Word '$word' seems to be errornous. Error code from preg_last_error(): " . preg_last_error()); + } + if (!isset(self::$cache[$word])) { + $result = self::getStem($word); + self::$cache[$word] = $result; + } + + return self::$cache[$word]; + } + + /** + * @param $word + * + * @return string + */ + private static function getStem($word) + { + $word = self::step0a($word); + $word = self::step1($word); + $word = self::step2($word); + $word = self::step3($word); + $word = self::step0b($word); + + return $word; + } + + /** + * Replaces to protect some characters + * + * @param string $word + * + * @return string mixed + */ + private static function step0a($word) + { + $vstr = implode('', self::$vowels); + $word = preg_replace('#([' . $vstr . '])u([' . $vstr . '])#u', '$1U$2', $word); + $word = preg_replace('#([' . $vstr . '])y([' . $vstr . '])#u', '$1Y$2', $word); + + return $word; + } + + /** + * Undo the initial replaces + * + * @param string $word + * + * @return string + */ + private static function step0b($word) + { + $word = str_replace(['ä', 'ö', 'ü', 'U', 'Y'], ['a', 'o', 'u', 'u', 'y'], $word); + + return $word; + } + + private static function step1($word) + { + $word = str_replace('ß', 'ss', $word); + + self::getR($word); + + $replaceCount = 0; + + $arr = ['em', 'ern', 'er']; + foreach ($arr as $s) { + self::$R1 = preg_replace('#' . $s . '$#u', '', self::$R1, -1, $replaceCount); + if ($replaceCount > 0) { + $word = preg_replace('#' . $s . '$#u', '', $word); + } + } + + $arr = ['en', 'es', 'e']; + foreach ($arr as $s) { + self::$R1 = preg_replace('#' . $s . '$#u', '', self::$R1, -1, $replaceCount); + if ($replaceCount > 0) { + $word = preg_replace('#' . $s . '$#u', '', $word); + $word = preg_replace('#niss$#u', 'nis', $word); + } + } + + $word = preg_replace('/([' . implode('', self::$s_ending) . '])s$/u', '$1', $word); + + return $word; + } + + private static function step2($word) + { + self::getR($word); + + $replaceCount = 0; + + $arr = ['est', 'er', 'en']; + foreach ($arr as $s) { + self::$R1 = preg_replace('#' . $s . '$#u', '', self::$R1, -1, $replaceCount); + if ($replaceCount > 0) { + $word = preg_replace('#' . $s . '$#u', '', $word); + } + } + + if (strpos(self::$R1, 'st') !== false) { + self::$R1 = preg_replace('#st$#u', '', self::$R1); + $word = preg_replace('#(...[' . implode('', self::$st_ending) . '])st$#u', '$1', $word); + } + + return $word; + } + + private static function step3($word) + { + self::getR($word); + + $replaceCount = 0; + + $arr = ['end', 'ung']; + foreach ($arr as $s) { + if (preg_match('#' . $s . '$#u', self::$R2)) { + $word = preg_replace('#([^e])' . $s . '$#u', '$1', $word, -1, $replaceCount); + if ($replaceCount > 0) { + self::$R2 = preg_replace('#' . $s . '$#u', '', self::$R2, -1, $replaceCount); + } + } + } + + $arr = ['isch', 'ik', 'ig']; + foreach ($arr as $s) { + if (preg_match('#' . $s . '$#u', self::$R2)) { + $word = preg_replace('#([^e])' . $s . '$#u', '$1', $word, -1, $replaceCount); + if ($replaceCount > 0) { + self::$R2 = preg_replace('#' . $s . '$#u', '', self::$R2); + } + } + } + + $arr = ['lich', 'heit']; + foreach ($arr as $s) { + self::$R2 = preg_replace('#' . $s . '$#u', '', self::$R2, -1, $replaceCount); + if ($replaceCount > 0) { + $word = preg_replace('#' . $s . '$#u', '', $word); + } else { + if (preg_match('#' . $s . '$#u', self::$R1)) { + $word = preg_replace('#(er|en)' . $s . '$#u', '$1', $word, -1, $replaceCount); + if ($replaceCount > 0) { + self::$R1 = preg_replace('#' . $s . '$#u', '', self::$R1); + } + } + } + } + + $arr = ['keit']; + foreach ($arr as $s) { + self::$R2 = preg_replace('#' . $s . '$#u', '', self::$R2, -1, $replaceCount); + if ($replaceCount > 0) { + $word = preg_replace('#' . $s . '$#u', '', $word); + } + } + + return $word; + } + + /** + * Find R1 and R2 + * + * @param string $word + */ + private static function getR($word) + { + self::$R1 = ''; + self::$R2 = ''; + + $vowels = implode('', self::$vowels); + $vowelGroup = "[{$vowels}]"; + $nonVowelGroup = "[^{$vowels}]"; + // R1 is the region after the first non-vowel following a vowel, or is the null region at the end of the word if there is no such non-vowel. + $pattern = "#(?P.*?{$vowelGroup}{$nonVowelGroup})(?P.*)#u"; + if (preg_match($pattern, $word, $match)) { + $rest = $match['rest']; + $r1 = $match['r']; + // [...], but then R1 is adjusted so that the region before it contains at least 3 letters. + $cutOff = 3 - mb_strlen($rest); + if ($cutOff > 0) { + $r1 = mb_substr($r1, $cutOff); + } + self::$R1 = $r1; + } + + //R2 is the region after the first non-vowel following a vowel in R1, or is the null region at the end of the word if there is no such non-vowel. + if (preg_match($pattern, self::$R1, $match)) { + self::$R2 = $match['r']; + } + } +} diff --git a/src/Stemmer/ItalianStemmer.php b/src/Stemmer/ItalianStemmer.php new file mode 100644 index 0000000..f97570d --- /dev/null +++ b/src/Stemmer/ItalianStemmer.php @@ -0,0 +1,463 @@ +, + * was originally written by Roberto Mirizzi (, + * ) in February 2007. It was the PHP5 implementation + * of Martin Porter's stemming algorithm for Italian language. This algorithm can be found + * at the address: . + * + * It was rewritten in March 2017 for TNTSearch by GaspariLab S.r.l., . + */ + +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +class ItalianStemmer implements Stemmer +{ + private static $cache = []; + + private static $vocali = ['a', 'e', 'i', 'o', 'u', 'à', 'è', 'ì', 'ò', 'ù']; + + private static $consonanti = [ + 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', + 'I', 'U', + ]; + + private static $accenti_acuti = ['á', 'é', 'í', 'ó', 'ú']; + + private static $accenti_gravi = ['à', 'è', 'ì', 'ò', 'ù']; + + private static $suffissi_step0 = [ + 'ci', 'gli', 'la', 'le', 'li', 'lo', 'mi', 'ne', 'si', 'ti', 'vi', 'sene', + 'gliela', 'gliele', 'glieli', 'glielo', 'gliene', 'mela', 'mele', 'meli', 'melo', 'mene', 'tela', 'tele', + 'teli', 'telo', 'tene', 'cela', 'cele', 'celi', 'celo', 'cene', 'vela', 'vele', 'veli', 'velo', 'vene', + ]; + + private static $suffissi_step1_a = [ + 'anza', 'anze', 'ico', 'ici', 'ica', 'ice', 'iche', 'ichi', 'ismo', 'ismi', 'abile', 'abili', 'ibile', + 'ibili', 'ista', 'iste', 'isti', 'istà', 'istè', 'istì', 'oso', 'osi', 'osa', 'ose', 'mente', 'atrice', + 'atrici', 'ante', 'anti', + ]; + + private static $suffissi_step1_b = ['azione', 'azioni', 'atore', 'atori']; + + private static $suffissi_step1_c = ['logia', 'logie']; + + private static $suffissi_step1_d = ['uzione', 'uzioni', 'usione', 'usioni']; + + private static $suffissi_step1_e = ['enza', 'enze']; + + private static $suffissi_step1_f = ['amento', 'amenti', 'imento', 'imenti']; + + private static $suffissi_step1_g = ['amente']; + + private static $suffissi_step1_h = ['ità']; + + private static $suffissi_step1_i = ['ivo', 'ivi', 'iva', 'ive']; + + private static $suffissi_step2 = [ + 'ammo', 'ando', 'ano', 'are', 'arono', 'asse', 'assero', 'assi', 'assimo', 'ata', 'ate', 'ati', 'ato', 'ava', + 'avamo', 'avano', 'avate', 'avi', 'avo', 'emmo', 'enda', 'ende', 'endi', 'endo', 'erà', 'erai', 'eranno', + 'ere', 'erebbe', 'erebbero', 'erei', 'eremmo', 'eremo', 'ereste', 'eresti', 'erete', 'erò', 'erono', 'essero', + 'ete', 'eva', 'evamo', 'evano', 'evate', 'evi', 'evo', 'Yamo', 'iamo', 'immo', 'irà', 'irai', 'iranno', 'ire', + 'irebbe', 'irebbero', 'irei', 'iremmo', 'iremo', 'ireste', 'iresti', 'irete', 'irò', 'irono', 'isca', + 'iscano', 'isce', 'isci', 'isco', 'iscono', 'issero', 'ita', 'ite', 'iti', 'ito', 'iva', 'ivamo', 'ivano', + 'ivate', 'ivi', 'ivo', 'ono', 'uta', 'ute', 'uti', 'uto', 'ar', 'ir', + ]; + + private static $ante_suff_a = ['ando', 'endo']; + + private static $ante_suff_b = ['ar', 'er', 'ir']; + + public function __construct() + { + usort(self::$suffissi_step0, function ($a, $b) { return mb_strlen($a) > mb_strlen($b) ? -1 : 1; }); + usort(self::$suffissi_step1_a, function ($a, $b) { return mb_strlen($a) > mb_strlen($b) ? -1 : 1;}); + usort(self::$suffissi_step2, function ($a, $b) { return mb_strlen($a) > mb_strlen($b) ? -1 : 1;}); + } + + /** + * Gets the stem of $word. + * + * @param string $word + * + * @return string + */ + public static function stem($word) + { + $word = mb_strtolower($word); + + // Check for invalid characters + preg_match('#.#u', $word); + if (preg_last_error() !== 0) { + throw new \InvalidArgumentException('Word "'.$word.'" seems to be errornous. + Error code from preg_last_error(): '.preg_last_error()); + } + + if (!isset(self::$cache[$word])) { + $result = self::getStem($word); + self::$cache[$word] = $result; + } + + return self::$cache[$word]; + } + + /** + * @param $word + * + * @return string + */ + private static function getStem($word) + { + $str = self::trim($word); + $str = self::toLower($str); + $str = self::replaceAccAcuti($str); + $str = self::putUAfterQToUpper($str); + $str = self::IUBetweenVowToUpper($str); + $step0 = self::step0($str); + $step1 = self::step1($step0); + $step2 = self::step2($step0, $step1); + $step3a = self::step3a($step2); + $step3b = self::step3b($step3a); + $step4 = self::step4($step3b); + + return $step4; + } + + private static function trim($str) + { + return trim($str); + } + + private static function toLower($str) + { + return strtolower($str); + } + + private static function replaceAccAcuti($str) + { + return str_replace(self::$accenti_acuti, self::$accenti_gravi, $str); //strtr + } + + private static function putUAfterQToUpper($str) + { + return str_replace('qu', 'qU', $str); + } + + private static function IUBetweenVowToUpper($str) + { + $pattern = '/([aeiouàèìòù])([iu])([aeiouàèìòù])/'; + + return preg_replace_callback($pattern, function ($matches) { + return strtoupper($matches[0]); + }, $str); + } + + private static function returnRV($str) + { + /* + If the second letter is a consonant, RV is the region after the next following vowel, + or if the first two letters are vowels, RV is the region after the next consonant, and otherwise + (consonant-vowel case) RV is the region after the third letter. + But RV is the end of the word if these positions cannot be found. Example: + m a c h o [ho] o l i v a [va] t r a b a j o [bajo] á u r e o [eo] prezzo sprezzante + */ + + if (mb_strlen($str) < 2) { + return ''; + } //$str; + + if (in_array($str[1], self::$consonanti)) { + $str = mb_substr($str, 2); + $str = strpbrk($str, implode(self::$vocali)); + + return mb_substr($str, 1); //secondo me devo mettere 1 + } elseif (in_array($str[0], self::$vocali) && in_array($str[1], self::$vocali)) { + $str = strpbrk($str, implode(self::$consonanti)); + + return mb_substr($str, 1); + } elseif (in_array($str[0], self::$consonanti) && in_array($str[1], self::$vocali)) { + return mb_substr($str, 3); + } + } + + private static function returnR1($str) + { + /* + R1 is the region after the first non-vowel following a vowel, or is the null region at the end + of the word if there is no such non-vowel. Example: + beautiful [iful] beauty [y] beau [NULL] animadversion [imadversion] sprinkled [kled] eucharist [harist] + */ + + $pattern = '/['.implode(self::$vocali).']+'.'['.implode(self::$consonanti).']'.'(.*)/'; + preg_match($pattern, $str, $matches); + + return count($matches) >= 1 ? $matches[1] : ''; + } + + private static function returnR2($str) + { + /* + R2 is the region after the first non-vowel following a vowel in R1, or is the null region at the end + of the word if there is no such non-vowel. Example: + beautiful [ul] beauty [NULL] beau [NULL] animadversion [adversion] sprinkled [NULL] eucharist [ist] + */ + + $R1 = self::returnR1($str); + + $pattern = '/['.implode(self::$vocali).']+'.'['.implode(self::$consonanti).']'.'(.*)/'; + preg_match($pattern, $R1, $matches); + + return count($matches) >= 1 ? $matches[1] : ''; + } + + private static function step0($str) + { + //Step 0: Attached pronoun + //Always do steps 0 + + $str_len = mb_strlen($str); + $rv = self::returnRV($str); + $rv_len = mb_strlen($rv); + + $pos = 0; + foreach (self::$suffissi_step0 as $suff) { + if ($rv_len - mb_strlen($suff) < 0) { + continue; + } + $pos = mb_strpos($rv, $suff, $rv_len - mb_strlen($suff)); + if ($pos !== false) { + break; + } + } + + $ante_suff = mb_substr($rv, 0, $pos); + $ante_suff_len = mb_strlen($ante_suff); + + foreach (self::$ante_suff_a as $ante_a) { + if ($ante_suff_len - mb_strlen($ante_a) < 0) { + continue; + } + $pos_a = mb_strpos($ante_suff, $ante_a, $ante_suff_len - mb_strlen($ante_a)); + if ($pos_a !== false) { + return mb_substr($str, 0, $pos + $str_len - $rv_len); + } + } + + foreach (self::$ante_suff_b as $ante_b) { + if ($ante_suff_len - mb_strlen($ante_b) < 0) { + continue; + } + $pos_b = mb_strpos($ante_suff, $ante_b, $ante_suff_len - mb_strlen($ante_b)); + if ($pos_b !== false) { + return mb_substr($str, 0, $pos + $str_len - $rv_len).'e'; + } + } + + return $str; + } + + private static function deleteStuff($arr_suff, $str, $str_len, $where, $ovunque = false) + { + if ($where === 'r2') { + $r = self::returnR2($str); + } elseif ($where === 'rv') { + $r = self::returnRV($str); + } elseif ($where === 'r1') { + $r = self::returnR1($str); + } + + $r_len = mb_strlen($r); + + if ($ovunque) { + foreach ($arr_suff as $suff) { + if ($str_len - mb_strlen($suff) < 0) { + continue; + } + $pos = mb_strpos($str, $suff, $str_len - mb_strlen($suff)); + if ($pos !== false) { + $pattern = '/'.$suff.'$/'; + $ret_str = preg_match($pattern, $r) ? mb_substr($str, 0, $pos) : ''; + if ($ret_str !== '') { + return $ret_str; + } + break; + } + } + } else { + foreach ($arr_suff as $suff) { + if ($r_len - mb_strlen($suff) < 0) { + continue; + } + $pos = mb_strpos($r, $suff, $r_len - mb_strlen($suff)); + if ($pos !== false) { + return mb_substr($str, 0, $pos + $str_len - $r_len); + } + } + } + } + + private static function step1($str) + { + // Step 1: Standard suffix removal + // Always do steps 1 + + $str_len = mb_strlen($str); + + // Delete if in R1, if preceded by 'iv', delete if in R2 (and if further preceded by 'at', delete if in R2), + // otherwise, if preceded by 'os', 'ic' or 'abil', delete if in R2 + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_g, $str, $str_len, 'r1'))) { + if (!empty($ret_str1 = self::deleteStuff(['iv'], $ret_str, mb_strlen($ret_str), 'r2'))) { + if (!empty($ret_str2 = self::deleteStuff(['at'], $ret_str1, mb_strlen($ret_str1), 'r2'))) { + return $ret_str2; + } else { + return $ret_str1; + } + } elseif (!empty( + $ret_str1 = self::deleteStuff(['os', 'ic', 'abil'], $ret_str, mb_strlen($ret_str), 'r2') + )) { + return $ret_str1; + } else { + return $ret_str; + } + } + + // Delete if in R2 + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_a, $str, $str_len, 'r2', true))) { + return $ret_str; + } + + // Delete if in R2, if preceded by 'ic', delete if in R2 + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_b, $str, $str_len, 'r2'))) { + if (!empty($ret_str1 = self::deleteStuff(['ic'], $ret_str, mb_strlen($ret_str), 'r2'))) { + return $ret_str1; + } else { + return $ret_str; + } + } + + // Replace with 'log' if in R2 + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_c, $str, $str_len, 'r2'))) { + return $ret_str.'log'; + } + + // Replace with 'u' if in R2 + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_d, $str, $str_len, 'r2'))) { + return $ret_str.'u'; + } + + // Replace with 'ente' if in R2 + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_e, $str, $str_len, 'r2'))) { + return $ret_str.'ente'; + } + + // Delete if in RV + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_f, $str, $str_len, 'rv'))) { + return $ret_str; + } + + // Delete if in R2, if preceded by 'abil', 'ic' or 'iv', delete if in R2 + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_h, $str, $str_len, 'r2'))) { + if (!empty($ret_str1 = self::deleteStuff(['abil', 'ic', 'iv'], $ret_str, mb_strlen($ret_str), 'r2'))) { + return $ret_str1; + } else { + return $ret_str; + } + } + + // Delete if in R2, if preceded by 'at', delete if in R2 (and if further preceded by 'ic', delete if in R2) + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_i, $str, $str_len, 'r2'))) { + if (!empty($ret_str1 = self::deleteStuff(['at'], $ret_str, mb_strlen($ret_str), 'r2'))) { + if (!empty($ret_str2 = self::deleteStuff(['ic'], $ret_str1, mb_strlen($ret_str1), 'r2'))) { + return $ret_str2; + } else { + return $ret_str1; + } + } else { + return $ret_str; + } + } + + return $str; + } + + private static function step2($str, $str_step1) + { + //Step 2: Verb suffixes + //Do step 2 if no ending was removed by step 1 + + if ($str != $str_step1) { + return $str_step1; + } + + $str_len = mb_strlen($str); + + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step2, $str, $str_len, 'rv'))) { + return $ret_str; + } + + return $str; + } + + private static function step3a($str) + { + // Step 3a: Delete a final 'a', 'e', 'i', 'o',' à', 'è', 'ì' or 'ò' if it is in RV, + // and a preceding 'i' if it is in RV ('crocchi' -> 'crocch', 'crocchio' -> 'crocch') + // Always do steps 3a + + $vocale_finale = ['a', 'e', 'i', 'o', 'à', 'è', 'ì', 'ò']; + + $str_len = mb_strlen($str); + + if (!empty($ret_str = self::deleteStuff($vocale_finale, $str, $str_len, 'rv'))) { + if (!empty($ret_str1 = self::deleteStuff(['i'], $ret_str, mb_strlen($ret_str), 'rv'))) { + return $ret_str1; + } else { + return $ret_str; + } + } + + return $str; + } + + private static function step3b($str) + { + // Step 3b: Replace final 'ch' (or 'gh') with 'c' (or 'g') if in 'RV' ('crocch' -> 'crocc') + // Always do steps 3b + + $rv = self::returnRV($str); + + $pattern = '/([cg])h$/'; + + return mb_substr($str, 0, mb_strlen($str) - mb_strlen($rv)) + . preg_replace_callback( + $pattern, + function ($matches) { + return $matches[0]; + }, + $rv + ); + } + + private static function step4($str) + { + // Step 4: Finally, turn I and U back into lower case + + return strtolower($str); + } +} diff --git a/src/Stemmer/LatvianStemmer.php b/src/Stemmer/LatvianStemmer.php new file mode 100644 index 0000000..457e33c --- /dev/null +++ b/src/Stemmer/LatvianStemmer.php @@ -0,0 +1,212 @@ + + * This is a light version of the algorithm in Karlis Kreslin's PhD thesis + * A stemming algorithm for Latvian with the following modifications: + *
    + *
  • Only explicitly stems noun and adjective morphology + *
  • Stricter length/vowel checks for the resulting stems (verb etc suffix stripping is removed) + *
  • Removes only the primary inflectional suffixes: case and number for nouns + * case, number, gender, and definitiveness for adjectives. + *
  • Palatalization is only handled when a declension II,V,VI noun suffix is removed. + *
+ */ + +class LatvianStemmer implements Stemmer +{ + private static $affixes = [ + ['ajiem', 3, false], + ['ajai', 3, false], + ['ajam', 2, false], + ['ajām', 2, false], + ['ajos', 2, false], + ['ajās', 2, false], + ['iem', 2, true], + ['ajā', 2, false], + ['ais', 2, false], + ['ai', 2, false], + ['ei', 2, false], + ['ām', 1, false], + ['am', 1, false], + ['ēm', 1, false], + ['īm', 1, false], + ['im', 1, false], + ['um', 1, false], + ['us', 1, true], + ['as', 1, false], + ['ās', 1, false], + ['es', 1, false], + ['os', 1, true], + ['ij', 1, false], + ['īs', 1, false], + ['ēs', 1, false], + ['is', 1, false], + ['ie', 1, false], + ['u', 1, true], + ['a', 1, true], + ['i', 1, true], + ['e', 1, false], + ['ā', 1, false], + ['ē', 1, false], + ['ī', 1, false], + ['ū', 1, false], + ['o', 1, false], + ['s', 0, false], + ['š', 0, false], + ]; + + private static $VOWELS = 'aāeēiīouū'; + + /** + * @param $word string + * + * @return string + */ + public static function stem($word) + { + $word = mb_strtolower($word); + $s = mb_str_split($word); + $numVowels = self::numVowels($s); + $length = count($s); + + foreach (self::$affixes as $affix) { + if ($numVowels > $affix[1] and $length >= mb_strlen($affix[0]) + 3 and self::endswith( + $s, + $length, + $affix[0] + )) { + $length -= mb_strlen($affix[0]); + if ($affix[2]) { + $s = self::unPalatalize($s, $length); + } else { + $s = array_slice($s, 0, $length); + } + break; + } + } + return implode('', $s); + } + + /** + * @param $s array + * + * @return int + */ + private static function numVowels($s) + { + $count = 0; + foreach ($s as $char) { + if (mb_substr_count(self::$VOWELS, $char) > 0) { + $count++; + } + } + return $count; + } + + /** + * @param $s array + * @param $length integer + * @param $suffix string + * + * @return bool + */ + public static function endswith($s, $length, $suffix) + { + return str_ends_with(implode('', array_splice($s, 0, $length)), $suffix); + } + + /** + * @param $s array + * @param $length integer + * + * @return array + */ + public static function unPalatalize($s, $length) + { + // we check the character removed: if its -u then + // its 2,5, or 6 gen pl., and these two can only apply then. + if ($s[$length] === 'u') { + // kš -> kst + if (self::endswith($s, $length, 'kš')) { + $length += 1; + $s[$length - 2] = 's'; + $s[$length - 1] = 't'; + return array_splice($s, 0, $length); + } elseif (self::endswith($s, $length, 'ņņ')) { + $s[$length - 2] = 'n'; + $s[$length - 1] = 'n'; + return array_splice($s, 0, $length); + } + } + // otherwise all other rules + if (self::endswith($s, $length, 'pj') or self::endswith($s, $length, 'bj') or self::endswith( + $s, + $length, + 'mj' + ) or self::endswith($s, $length, 'vj')) { + $length--; + } elseif (self::endswith($s, $length, 'šņ')) { + $s[$length - 2] = 's'; + $s[$length - 1] = 'n'; + } elseif (self::endswith($s, $length, 'žņ')) { + $s[$length - 2] = 'z'; + $s[$length - 1] = 'n'; + } elseif (self::endswith($s, $length, 'šļ')) { + $s[$length - 2] = 's'; + $s[$length - 1] = 'l'; + } elseif (self::endswith($s, $length, 'žļ')) { + $s[$length - 2] = 'z'; + $s[$length - 1] = 'l'; + } elseif (self::endswith($s, $length, 'ļņ')) { + $s[$length - 2] = 'l'; + $s[$length - 1] = 'n'; + } elseif (self::endswith($s, $length, 'ļļ')) { + $s[$length - 2] = 'l'; + $s[$length - 1] = 'l'; + } elseif (self::endswith($s, $length, 'č')) { + $s[$length - 1] = 'c'; + } elseif (self::endswith($s, $length, 'ļ')) { + $s[$length - 1] = 'l'; + } elseif (self::endswith($s, $length, 'ņ')) { + $s[$length - 1] = 'n'; + } + return array_splice($s, 0, $length); + } +} diff --git a/src/Stemmer/NoStemmer.php b/src/Stemmer/NoStemmer.php new file mode 100644 index 0000000..c7392a9 --- /dev/null +++ b/src/Stemmer/NoStemmer.php @@ -0,0 +1,11 @@ + 7 && in_array(mb_substr($word, -5), ['zacja', 'zacją', 'zacji'])) { + return mb_substr($word, 0, -4); + } + if (strlen($word) > 6 && in_array(mb_substr($word, -4), ['acja', 'acji', 'acją', 'tach', 'anie', 'enie', 'eniu', 'aniu'])) { + return mb_substr($word, 0, -4); + } + if (strlen($word) > 6 && (mb_substr($word, -4) == 'tyka')) { + return mb_substr($word, 0, -2); + } + if (strlen($word) > 5 && in_array(mb_substr($word, -3), ['ach', 'ami', 'nia', 'niu', 'cia', 'ciu'])) { + return mb_substr($word, 0, -3); + } + if (strlen($word) > 5 && in_array(mb_substr($word, -3), ['cji', 'cja', 'cją'])) { + return mb_substr($word, 0, -2); + } + if (strlen($word) > 5 && in_array(mb_substr($word, -2), ['ce', 'ta'])) { + return mb_substr($word, 0, -2); + } + return $word; + } + + public static function removeDiminutive($word) + { + if (strlen($word) > 6) { + if (in_array(mb_substr($word, -5), ['eczek', 'iczek', 'iszek', 'aszek', 'uszek'])) { + return mb_substr($word, 0, -5); + } + if (in_array(mb_substr($word, -4), ['enek', 'ejek', 'erek'])) { + return mb_substr($word, 0, -2); + } + } + if (strlen($word) > 4) { + if (in_array(mb_substr($word, -2), ['ek', 'ak'])) { + return mb_substr($word, 0, -2); + } + } + return $word; + } + + public static function removeAdjectiveEnds($word) + { + if (strlen($word) > 7 && (mb_substr($word, 0, 3) == 'naj') && in_array(mb_substr($word, -3), ['sze', 'szy'])) { + return mb_substr($word, 3, -3); + } + if (strlen($word) > 7 && (mb_substr($word, 0, 3) == 'naj') && (mb_substr($word, 0, 5) == 'szych')) { + return mb_substr($word, 3, -5); + } + if (strlen($word) > 6 && (mb_substr($word, -4) == 'czny')) { + return mb_substr($word, 0, -4); + } + if (strlen($word) > 5 && in_array(mb_substr($word, -3), ['owy', 'owa', 'owe', 'ych', 'ego'])) { + return mb_substr($word, 0, -3); + } + if (strlen($word) > 5 && (mb_substr($word, -2) == 'ej')) { + return mb_substr($word, 0, -2); + } + return $word; + } + + public static function removeVerbsEnds($word) + { + if (strlen($word) > 5 && (mb_substr($word, -3) == 'bym')) { + return mb_substr($word, 0, -3); + } + if (strlen($word) > 5 && in_array(mb_substr($word, -3), ['esz', 'asz', 'cie', 'eść', 'aść', 'łem', 'amy', 'emy'])) { + return mb_substr($word, 0, -3); + } + if (strlen($word) > 3 && in_array(mb_substr($word, -3), ['esz', 'asz', 'eść', 'aść', 'eć', 'ać'])) { + return mb_substr($word, 0, -2); + } + if (strlen($word) > 3 && in_array(mb_substr($word, -2), ['aj'])) { + return mb_substr($word, 0, -1); + } + if (strlen($word) > 3 && in_array(mb_substr($word, -2), ['ać', 'em', 'am', 'ał', 'ił', 'ić', 'ąc'])) { + return mb_substr($word, 0, -2); + } + return $word; + } + + public static function removeAdverbsEnds($word) + { + if (strlen($word) > 4 && in_array(mb_substr($word, -3), ['nie', 'wie', 'rze'])) { + return mb_substr($word, 0, -2); + } + return $word; + } + + public static function removePluralForms($word) + { + if (strlen($word) > 4 && in_array(mb_substr($word, -2), ['ów', 'om'])) { + return mb_substr($word, 0, -2); + } + if (strlen($word) > 4 && (mb_substr($word, -3) == 'ami')) { + return mb_substr($word, 0, -3); + } + return $word; + } + + public static function removeGeneralEnds($word) + { + if (strlen($word) > 4 && in_array(substr($word, -2), ['ia', 'ie'])) { + return substr($word, 0, -2); + } + if (strlen($word) > 4 && in_array(substr($word, -1), ['u', 'ą', 'i', 'a', 'ę', 'y', 'ę', 'ł'])) { + return substr($word, 0, -1); + } + return $word; + } + + public static function stem($word) + { + $word = mb_strtolower($word); + + $stem = $word; + + $stem = self::removeNouns($stem); + $stem = self::removeDiminutive($stem); + $stem = self::removeAdjectiveEnds($stem); + $stem = self::removeVerbsEnds($stem); + $stem = self::removeAdverbsEnds($stem); + $stem = self::removePluralForms($stem); + $stem = self::removeGeneralEnds($stem); + + return $stem; + } +} diff --git a/src/Stemmer/PorterStemmer.php b/src/Stemmer/PorterStemmer.php new file mode 100644 index 0000000..2dd48c9 --- /dev/null +++ b/src/Stemmer/PorterStemmer.php @@ -0,0 +1,403 @@ + 1) { + self::replace($word, 'e', ''); + } elseif (self::m(substr($word, 0, -1)) == 1) { + if (!self::cvc(substr($word, 0, -1))) { + self::replace($word, 'e', ''); + } + } + } + + // Part b + if (self::m($word) > 1 && self::doubleConsonant($word) && substr($word, -1) == 'l') { + $word = substr($word, 0, -1); + } + + return $word; + } + + /** + * Replaces the first string with the second, at the end of the string. If third + * arg is given, then the preceding string must match that m count at least. + * + * @param string $str String to check + * @param string $check Ending to check for + * @param string $repl Replacement string + * @param int $m Optional minimum number of m() to meet + * + * @return bool Whether the $check string was at the end + * of the $str string. True does not necessarily mean + * that it was replaced. + */ + private static function replace(&$str, $check, $repl, $m = null) + { + $len = 0 - strlen($check); + + if (substr($str, $len) == $check) { + $substr = substr($str, 0, $len); + if (is_null($m) || self::m($substr) > $m) { + $str = $substr.$repl; + } + + return true; + } + + return false; + } + + /** + * What, you mean it's not obvious from the name? + * + * Measures the number of consonant sequences in $str. if c is + * a consonant sequence and v a vowel sequence, and <..> indicates arbitrary + * presence, + * + * gives 0 + * vc gives 1 + * vcvc gives 2 + * vcvcvc gives 3 + * + * @param string $str The string to return the m count for + * + * @return int The m count + */ + private static function m($str) + { + $c = self::$regex_consonant; + $v = self::$regex_vowel; + + $str = preg_replace("#^$c+#", '', $str); + $str = preg_replace("#$v+$#", '', $str); + + preg_match_all("#($v+$c+)#", $str, $matches); + + return count($matches[1]); + } + + /** + * Returns true/false as to whether the given string contains two + * of the same consonant next to each other at the end of the string. + * + * @param string $str String to check + * + * @return bool Result + */ + private static function doubleConsonant($str) + { + $c = self::$regex_consonant; + + return preg_match("#$c{2}$#", $str, $matches) && $matches[0][0] == $matches[0][1]; + } + + /** + * Checks for ending CVC sequence where second C is not W, X or Y + * + * @param string $str String to check + * + * @return bool Result + */ + private static function cvc($str) + { + $c = self::$regex_consonant; + $v = self::$regex_vowel; + + $matchFound = preg_match("#($c$v$c)$#", $str, $matches); + + $return = false; + + if ($matchFound && strlen($matches[1]) == 3) { + $return = true; + if (in_array($matches[1][2], ['w', 'x', 'y'])) { + $return = false; + } + } + + return $return; + } +} diff --git a/src/Stemmer/PortugeseStemmer.php b/src/Stemmer/PortugeseStemmer.php new file mode 100644 index 0000000..940cd84 --- /dev/null +++ b/src/Stemmer/PortugeseStemmer.php @@ -0,0 +1,766 @@ +. + */ + +/** + * This is a reimplementation of the Porter Stemmer Algorithm for Portuguese. + * This script is based on the implementation found on + * and has been rewriten to work with TNTSearch by Lucas Padilha + * + * Takes a word and reduces it to its Portuguese stem using the Porter stemmer algorithm. + * + * References: + * - http://snowball.tartarus.org/algorithms/porter/stemmer.html + * - http://snowball.tartarus.org/algorithms/portuguese/stemmer.html + * + * Usage: + * $stem = PortugueseStemmer::stem($word); + * + * @author Lucas Padilha + */ + +class PortugueseStemmer implements Stemmer +{ + /** + * UTF-8 Case lookup table + * + * This lookuptable defines the upper case letters to their correspponding + * lower case letter in UTF-8 + * + * @author Andreas Gohr + */ + private static $utf8_lower_to_upper = [ + 0x0061 => 0x0041, 0x03C6 => 0x03A6, 0x0163 => 0x0162, 0x00E5 => 0x00C5, 0x0062 => 0x0042, + 0x013A => 0x0139, 0x00E1 => 0x00C1, 0x0142 => 0x0141, 0x03CD => 0x038E, 0x0101 => 0x0100, + 0x0491 => 0x0490, 0x03B4 => 0x0394, 0x015B => 0x015A, 0x0064 => 0x0044, 0x03B3 => 0x0393, + 0x00F4 => 0x00D4, 0x044A => 0x042A, 0x0439 => 0x0419, 0x0113 => 0x0112, 0x043C => 0x041C, + 0x015F => 0x015E, 0x0144 => 0x0143, 0x00EE => 0x00CE, 0x045E => 0x040E, 0x044F => 0x042F, + 0x03BA => 0x039A, 0x0155 => 0x0154, 0x0069 => 0x0049, 0x0073 => 0x0053, 0x1E1F => 0x1E1E, + 0x0135 => 0x0134, 0x0447 => 0x0427, 0x03C0 => 0x03A0, 0x0438 => 0x0418, 0x00F3 => 0x00D3, + 0x0440 => 0x0420, 0x0454 => 0x0404, 0x0435 => 0x0415, 0x0449 => 0x0429, 0x014B => 0x014A, + 0x0431 => 0x0411, 0x0459 => 0x0409, 0x1E03 => 0x1E02, 0x00F6 => 0x00D6, 0x00F9 => 0x00D9, + 0x006E => 0x004E, 0x0451 => 0x0401, 0x03C4 => 0x03A4, 0x0443 => 0x0423, 0x015D => 0x015C, + 0x0453 => 0x0403, 0x03C8 => 0x03A8, 0x0159 => 0x0158, 0x0067 => 0x0047, 0x00E4 => 0x00C4, + 0x03AC => 0x0386, 0x03AE => 0x0389, 0x0167 => 0x0166, 0x03BE => 0x039E, 0x0165 => 0x0164, + 0x0117 => 0x0116, 0x0109 => 0x0108, 0x0076 => 0x0056, 0x00FE => 0x00DE, 0x0157 => 0x0156, + 0x00FA => 0x00DA, 0x1E61 => 0x1E60, 0x1E83 => 0x1E82, 0x00E2 => 0x00C2, 0x0119 => 0x0118, + 0x0146 => 0x0145, 0x0070 => 0x0050, 0x0151 => 0x0150, 0x044E => 0x042E, 0x0129 => 0x0128, + 0x03C7 => 0x03A7, 0x013E => 0x013D, 0x0442 => 0x0422, 0x007A => 0x005A, 0x0448 => 0x0428, + 0x03C1 => 0x03A1, 0x1E81 => 0x1E80, 0x016D => 0x016C, 0x00F5 => 0x00D5, 0x0075 => 0x0055, + 0x0177 => 0x0176, 0x00FC => 0x00DC, 0x1E57 => 0x1E56, 0x03C3 => 0x03A3, 0x043A => 0x041A, + 0x006D => 0x004D, 0x016B => 0x016A, 0x0171 => 0x0170, 0x0444 => 0x0424, 0x00EC => 0x00CC, + 0x0169 => 0x0168, 0x03BF => 0x039F, 0x006B => 0x004B, 0x00F2 => 0x00D2, 0x00E0 => 0x00C0, + 0x0434 => 0x0414, 0x03C9 => 0x03A9, 0x1E6B => 0x1E6A, 0x00E3 => 0x00C3, 0x044D => 0x042D, + 0x0436 => 0x0416, 0x01A1 => 0x01A0, 0x010D => 0x010C, 0x011D => 0x011C, 0x00F0 => 0x00D0, + 0x013C => 0x013B, 0x045F => 0x040F, 0x045A => 0x040A, 0x00E8 => 0x00C8, 0x03C5 => 0x03A5, + 0x0066 => 0x0046, 0x00FD => 0x00DD, 0x0063 => 0x0043, 0x021B => 0x021A, 0x00EA => 0x00CA, + 0x03B9 => 0x0399, 0x017A => 0x0179, 0x00EF => 0x00CF, 0x01B0 => 0x01AF, 0x0065 => 0x0045, + 0x03BB => 0x039B, 0x03B8 => 0x0398, 0x03BC => 0x039C, 0x045C => 0x040C, 0x043F => 0x041F, + 0x044C => 0x042C, 0x00FE => 0x00DE, 0x00F0 => 0x00D0, 0x1EF3 => 0x1EF2, 0x0068 => 0x0048, + 0x00EB => 0x00CB, 0x0111 => 0x0110, 0x0433 => 0x0413, 0x012F => 0x012E, 0x00E6 => 0x00C6, + 0x0078 => 0x0058, 0x0161 => 0x0160, 0x016F => 0x016E, 0x03B1 => 0x0391, 0x0457 => 0x0407, + 0x0173 => 0x0172, 0x00FF => 0x0178, 0x006F => 0x004F, 0x043B => 0x041B, 0x03B5 => 0x0395, + 0x0445 => 0x0425, 0x0121 => 0x0120, 0x017E => 0x017D, 0x017C => 0x017B, 0x03B6 => 0x0396, + 0x03B2 => 0x0392, 0x03AD => 0x0388, 0x1E85 => 0x1E84, 0x0175 => 0x0174, 0x0071 => 0x0051, + 0x0437 => 0x0417, 0x1E0B => 0x1E0A, 0x0148 => 0x0147, 0x0105 => 0x0104, 0x0458 => 0x0408, + 0x014D => 0x014C, 0x00ED => 0x00CD, 0x0079 => 0x0059, 0x010B => 0x010A, 0x03CE => 0x038F, + 0x0072 => 0x0052, 0x0430 => 0x0410, 0x0455 => 0x0405, 0x0452 => 0x0402, 0x0127 => 0x0126, + 0x0137 => 0x0136, 0x012B => 0x012A, 0x03AF => 0x038A, 0x044B => 0x042B, 0x006C => 0x004C, + 0x03B7 => 0x0397, 0x0125 => 0x0124, 0x0219 => 0x0218, 0x00FB => 0x00DB, 0x011F => 0x011E, + 0x043E => 0x041E, 0x1E41 => 0x1E40, 0x03BD => 0x039D, 0x0107 => 0x0106, 0x03CB => 0x03AB, + 0x0446 => 0x0426, 0x00FE => 0x00DE, 0x00E7 => 0x00C7, 0x03CA => 0x03AA, 0x0441 => 0x0421, + 0x0432 => 0x0412, 0x010F => 0x010E, 0x00F8 => 0x00D8, 0x0077 => 0x0057, 0x011B => 0x011A, + 0x0074 => 0x0054, 0x006A => 0x004A, 0x045B => 0x040B, 0x0456 => 0x0406, 0x0103 => 0x0102, + 0x03BB => 0x039B, 0x00F1 => 0x00D1, 0x043D => 0x041D, 0x03CC => 0x038C, 0x00E9 => 0x00C9, + 0x00F0 => 0x00D0, 0x0457 => 0x0407, 0x0123 => 0x0122, + ]; + + private static $vowels = ['a', 'e', 'i', 'o', 'u', 'á', 'é', 'í', 'ó', 'ú', 'â', 'ê', 'ô']; + + public static function stem($word) + { + // we do ALL in UTF-8 + if (!self::check($word)) { + throw new \Exception('Word must be in UTF-8'); + } + + $word = self::strtolower($word); + $word = self::str_replace(['ã', 'õ'], ['a~', 'o~'], $word); + + $rv = ''; + $rvIndex = ''; + self::rv($word, $rv, $rvIndex); + + $r1 = ''; + $r1Index = ''; + self::r1($word, $r1, $r1Index); + + $r2 = ''; + $r2Index = ''; + self::r2($r1, $r1Index, $r2, $r2Index); + + $initialWord = $word; + + self::step1($word, $r1Index, $r2Index, $rvIndex); + + if ($initialWord == $word) { + self::step2($word, $rvIndex); + } + + if ($initialWord != $word) { + self::step3($word, $rvIndex); + } else { + self::step4($word, $rvIndex); + } + + self::step5($word, $rvIndex); + + self::finish($word); + + return $word; + } + + /** + * R1 is the region after the first non-vowel following a vowel, or the end of the word if there is no such non-vowel. + */ + private static function r1($word, &$r1, &$r1Index) + { + [$index, $value] = self::rx($word); + + $r1 = $value; + $r1Index = $index; + + return true; + } + + /** + * R2 is the region after the first non-vowel following a vowel in R1, or the end of the word if there is no such non-vowel. + */ + private static function r2($r1, $r1Index, &$r2, &$r2Index) + { + [$index, $value] = self::rx($r1); + + $r2 = $value; + $r2Index = $r1Index + $index; + + return true; + } + + /** + * Common function for R1 and R2 + * Search the region after the first non-vowel following a vowel in $word, or the end of the word if there is no such non-vowel. + * R1 : $in = $this->word + * R2 : $in = R1 + */ + private static function rx($in) + { + $length = self::strlen($in); + + // Defaults + $value = ''; + $index = $length; + + // Search all vowels + $vowels = []; + for ($i = 0; $i < $length; $i++) { + $letter = self::substr($in, $i, 1); + + if (in_array($letter, static::$vowels)) { + $vowels[] = $i; + } + } + + // Search the non-vowel following a vowel + foreach ($vowels as $position) { + $after = $position + 1; + $letter = self::substr($in, $after, 1); + + if (!in_array($letter, static::$vowels)) { + $index = $after + 1; + $value = self::substr($in, ($after + 1)); + break; + } + } + + return [$index, $value]; + } + + /** + * Used by spanish, italian, portuguese, etc (but not by french) + * + * If the second letter is a consonant, RV is the region after the next following vowel, + * or if the first two letters are vowels, RV is the region after the next consonant, + * and otherwise (consonant-vowel case) RV is the region after the third letter. + * But RV is the end of the word if these positions cannot be found. + */ + private static function rv($word, &$rv, &$rvIndex) + { + $length = self::strlen($word); + + if ($length < 3) { + return true; + } + + $first = self::substr($word, 0, 1); + $second = self::substr($word, 1, 1); + + // If the second letter is a consonant, RV is the region after the next following vowel, + if (!in_array($second, static::$vowels)) { + for ($i = 2; $i < $length; $i++) { + $letter = self::substr($word, $i, 1); + + if (in_array($letter, static::$vowels)) { + $rv = self::substr($word, ($i + 1)); + $rvIndex = $i + 1; + + return true; + } + } + } + + // or if the first two letters are vowels, RV is the region after the next consonant, + if ((in_array($first, static::$vowels)) && (in_array($second, static::$vowels))) { + for ($i = 2; $i < $length; $i++) { + $letter = self::substr($word, $i, 1); + + if (!in_array($letter, static::$vowels)) { + $rv = self::substr($word, ($i + 1)); + $rvIndex = $i + 1; + + return true; + } + } + } + + // and otherwise (consonant-vowel case) RV is the region after the third letter. + if ((!in_array($first, static::$vowels)) && (in_array($second, static::$vowels))) { + $rv = self::substr($word, 3); + $rvIndex = 3; + + return true; + } + + return false; + } + + private static function inRv($position, $rvIndex) + { + return ($position >= $rvIndex); + } + + private static function inR1($position, $r1Index) + { + return ($position >= $r1Index); + } + + private static function inR2($position, $r2Index) + { + return ($position >= $r2Index); + } + + private static function searchIfInRv($word, $suffixes, $rvIndex) + { + return self::search($word, $suffixes, $rvIndex); + } + + private static function searchIfInR2($word, $suffixes, $r2Index) + { + return self::search($word, $suffixes, $r2Index); + } + + private static function search($word, $suffixes, $offset = 0) + { + $length = self::strlen($word); + + if ($offset > $length) { + return false; + } + + foreach ($suffixes as $suffix) { + if ((($position = self::strrpos($word, $suffix, $offset)) !== false) && ((self::strlen($suffix) + $position) == $length)) { + return $position; + } + } + return false; + } + + /** + * Step 1: Standard suffix removal + */ + private static function step1(&$word, $r1Index, $r2Index, $rvIndex) + { + // delete if in R2 + if (($position = self::search($word, ['amentos', 'imentos', 'adoras', 'adores', 'amento', 'imento', 'adora', 'istas', 'ismos', 'antes', 'ância', 'ezas', 'eza', 'icos', 'icas', 'ismo', 'ável', 'ível', 'ista', 'oso', 'osos', 'osas', 'osa', 'ico', 'ica', 'ador', 'aça~o', 'aço~es', 'ante'])) !== false) { + if (self::inR2($position, $r2Index)) { + $word = self::substr($word, 0, $position); + } + + return true; + } + + // replace with log if in R2 + if (($position = self::search($word, ['logías', 'logía'])) !== false) { + if (self::inR2($position, $r2Index)) { + $word = preg_replace('#(logías|logía)$#u', 'log', $word); + } + + return true; + } + + // replace with u if in R2 + if (($position = self::search($word, ['uciones', 'ución'])) !== false) { + if (self::inR2($position, $r2Index)) { + $word = preg_replace('#(uciones|ución)$#u', 'u', $word); + } + + return true; + } + + // replace with ente if in R2 + if (($position = self::search($word, ['ências', 'ência'])) !== false) { + if (self::inR2($position, $r2Index)) { + $word = preg_replace('#(ências|ência)$#u', 'ente', $word); + } + + return true; + } + + // delete if in R1 + // if preceded by iv, delete if in R2 (and if further preceded by at, delete if in R2), otherwise, + // if preceded by os, ic or ad, delete if in R2 + if (($position = self::search($word, ['amente'])) !== false) { + // delete if in R1 + if (self::inR1($position, $r1Index)) { + $word = self::substr($word, 0, $position); + } + + // if preceded by iv, delete if in R2 (and if further preceded by at, delete if in R2), otherwise, + if (($position2 = self::searchIfInR2($word, ['iv'], $r2Index)) !== false) { + $word = self::substr($word, 0, $position2); + + if (($position3 = self::searchIfInR2($word, ['at'], $r2Index)) !== false) { + $word = self::substr($word, 0, $position3); + } + + // if preceded by os, ic or ad, delete if in R2 + } elseif (($position4 = self::searchIfInR2($word, ['os', 'ic', 'ad'], $r2Index)) !== false) { + $word = self::substr($word, 0, $position4); + } + + return true; + } + + // delete if in R2 + // if preceded by ante, avel or ível, delete if in R2 + if (($position = self::search($word, ['mente'])) !== false) { + // delete if in R2 + if (self::inR2($position, $r2Index)) { + $word = self::substr($word, 0, $position); + } + + // if preceded by ante, avel or ível, delete if in R2 + if (($position2 = self::searchIfInR2($word, ['ante', 'avel', 'ível'], $r2Index)) != false) { + $word = self::substr($word, 0, $position2); + } + + return true; + } + + // delete if in R2 + // if preceded by abil, ic or iv, delete if in R2 + if (($position = self::search($word, ['idades', 'idade'])) !== false) { + // delete if in R2 + if (self::inR2($position, $r2Index)) { + $word = self::substr($word, 0, $position); + } + + // if preceded by abil, ic or iv, delete if in R2 + if (($position2 = self::searchIfInR2($word, ['abil', 'ic', 'iv'], $r2Index)) !== false) { + $word = self::substr($word, 0, $position2); + } + + return true; + } + + // delete if in R2 + // if preceded by at, delete if in R2 + if (($position = self::search($word, ['ivas', 'ivos', 'iva', 'ivo'])) !== false) { + // delete if in R2 + if (self::inR2($position, $r2Index)) { + $word = self::substr($word, 0, $position); + } + + // if preceded by at, delete if in R2 + if (($position2 = self::searchIfInR2($word, ['at'], $r2Index)) !== false) { + $word = self::substr($word, 0, $position2); + } + + return true; + } + + // replace with ir if in RV and preceded by e + if (($position = self::search($word, ['iras', 'ira'])) !== false) { + if (self::inRv($position, $rvIndex)) { + $before = $position - 1; + $letter = self::substr($word, $before, 1); + + if ($letter == 'e') { + $word = preg_replace('#(iras|ira)$#u', 'ir', $word); + } + } + + return true; + } + + return false; + } + + /** + * Step 2: Verb suffixes + * Search for the longest among the following suffixes in RV, and if found, delete. + */ + private static function step2(&$word, $rvIndex) + { + if (($position = self::searchIfInRv($word, ['aríamos', 'eríamos', 'iríamos', 'ássemos', 'êssemos', 'íssemos', 'aríeis', 'eríeis', 'iríeis', 'ásseis', 'ésseis', 'ísseis', 'áramos', 'éramos', 'íramos', 'ávamos', 'aremos', 'eremos', 'iremos', 'ariam', 'eriam', 'iriam', 'assem', 'essem', 'issem', 'arias', 'erias', 'irias', 'ardes', 'erdes', 'irdes', 'asses', 'esses', 'isses', 'astes', 'estes', 'istes', 'áreis', 'areis', 'éreis', 'ereis', 'íreis', 'ireis', 'áveis', 'íamos', 'armos', 'ermos', 'irmos', 'aria', 'eria', 'iria', 'asse', 'esse', 'isse', 'aste', 'este', 'iste', 'arei', 'erei', 'irei', 'adas', 'idas', 'aram', 'eram', 'iram', 'avam', 'arem', 'erem', 'irem', 'ando', 'endo', 'indo', 'ara~o', 'era~o', 'ira~o', 'arás', 'aras', 'erás', 'eras', 'irás', 'avas', 'ares', 'eres', 'ires', 'íeis', 'ados', 'idos', 'ámos', 'amos', 'emos', 'imos', 'iras', 'ada', 'ida', 'ará', 'ara', 'erá', 'era', 'irá', 'ava', 'iam', 'ado', 'ido', 'ias', 'ais', 'eis', 'ira', 'ia', 'ei', 'am', 'em', 'ar', 'er', 'ir', 'as', 'es', 'is', 'eu', 'iu', 'ou'], $rvIndex)) !== false) { + $word = self::substr($word, 0, $position); + + return true; + } + + return false; + } + + /** + * Step 3: d-suffixes + */ + private static function step3(&$word, $rvIndex) + { + // Delete suffix i if in RV and preceded by c + if (self::searchIfInRv($word, ['i'], $rvIndex) !== false) { + $letter = self::substr($word, -2, 1); + + if ($letter == 'c') { + $word = self::substr($word, 0, -1); + } + + return true; + } + + return false; + } + + /** + * Step 4 + */ + private static function step4(&$word, $rvIndex) + { + // If the word ends with one of the suffixes "os a i o á í ó" in RV, delete it + if (($position = self::searchIfInRv($word, ['os', 'a', 'i', 'o', 'á', 'í', 'ó'], $rvIndex)) !== false) { + $word = self::substr($word, 0, $position); + + return true; + } + + return false; + } + + /** + * Step 5 + */ + private static function step5(&$word, $rvIndex) + { + // If the word ends with one of "e é ê" in RV, delete it, and if preceded by gu (or ci) with the u (or i) in RV, delete the u (or i). + if (self::searchIfInRv($word, ['e', 'é', 'ê'], $rvIndex) !== false) { + $word = self::substr($word, 0, -1); + + if (($position2 = self::search($word, ['gu', 'ci'])) !== false) { + if (self::inRv(($position2 + 1), $rvIndex)) { + $word = self::substr($word, 0, -1); + } + } + + return true; + } elseif (self::search($word, ['ç']) !== false) { + $word = preg_replace('#(ç)$#u', 'c', $word); + + return true; + } + + return false; + } + + private static function finish(&$word) + { + // turn U and Y back into lower case, and remove the umlaut accent from a, o and u. + $word = self::str_replace(['a~', 'o~'], ['ã', 'õ'], $word); + } + + /** + * Tries to detect if a string is in Unicode encoding + * + * @author + * + * @link http://www.php.net/manual/en/function.utf8-encode.php + */ + private static function check($str) + { + for ($i = 0; $i < strlen($str); $i++) { + if (ord($str[$i]) < 0x80) { + continue; + } + # 0bbbbbbb + elseif ((ord($str[$i]) & 0xE0) == 0xC0) { + $n = 1; + } + # 110bbbbb + elseif ((ord($str[$i]) & 0xF0) == 0xE0) { + $n = 2; + } + # 1110bbbb + elseif ((ord($str[$i]) & 0xF8) == 0xF0) { + $n = 3; + } + # 11110bbb + elseif ((ord($str[$i]) & 0xFC) == 0xF8) { + $n = 4; + } + # 111110bb + elseif ((ord($str[$i]) & 0xFE) == 0xFC) { + $n = 5; + } + # 1111110b + else { + return false; + } + # Does not match any model + for ($j = 0; $j < $n; $j++) { + # n bytes matching 10bbbbbb follow ? + if ((++$i == strlen($str)) || ((ord($str[$i]) & 0xC0) != 0x80)) { + return false; + } + } + } + return true; + } + + /** + * Unicode aware replacement for strlen() + * + * utf8_decode() converts characters that are not in ISO-8859-1 + * to '?', which, for the purpose of counting, is alright - It's + * even faster than mb_strlen. + * + * @author + * + * @see strlen() + * @see utf8_decode() + */ + private static function strlen($string) + { + return mb_strlen($string, 'UTF-8'); + } + + /** + * Unicode aware replacement for substr() + * + * @author lmak at NOSPAM dot iti dot gr + * + * @link http://www.php.net/manual/en/function.substr.php + * @see substr() + */ + private static function substr($str, $start, $length = null) + { + $ar = []; + preg_match_all('/./u', $str, $ar); + + if ($length != null) { + return join('', array_slice($ar[0], $start, $length)); + } else { + return join('', array_slice($ar[0], $start)); + } + } + + /** + * Unicode aware replacement for strrepalce() + * + * @author Harry Fuecks + * + * @see strreplace(); + */ + private static function str_replace($s, $r, $str) + { + if (!is_array($s)) { + $s = '!' . preg_quote($s, '!') . '!u'; + } else { + foreach ($s as $k => $v) { + $s[$k] = '!' . preg_quote($v) . '!u'; + } + } + return preg_replace($s, $r, $str); + } + + /** + * This is a unicode aware replacement for strtolower() + * + * Uses mb_string extension if available + * + * @author Andreas Gohr + * + * @see strtolower() + * @see utf8_strtoupper() + */ + private static function strtolower($string) + { + if (!defined('UTF8_NOMBSTRING') && function_exists('mb_strtolower')) { + return mb_strtolower($string, 'utf-8'); + } + + //global $utf8_upper_to_lower; + $utf8_upper_to_lower = array_flip(self::$utf8_lower_to_upper); + $uni = self::utf8_to_unicode($string); + $cnt = count($uni); + for ($i = 0; $i < $cnt; $i++) { + if ($utf8_upper_to_lower[$uni[$i]]) { + $uni[$i] = $utf8_upper_to_lower[$uni[$i]]; + } + } + return self::unicode_to_utf8($uni); + } + + /** + * This function returns any UTF-8 encoded text as a list of + * Unicode values: + * + * @author Scott Michael Reynen + * + * @link http://www.randomchaos.com/document.php?source=php_and_unicode + * @see unicode_to_utf8() + */ + private static function utf8_to_unicode(&$str) + { + $unicode = []; + $values = []; + $looking_for = 1; + + for ($i = 0; $i < strlen($str); $i++) { + $this_value = ord($str[$i]); + if ($this_value < 128) { + $unicode[] = $this_value; + } else { + if (count($values) == 0) { + $looking_for = ($this_value < 224) ? 2 : 3; + } + + $values[] = $this_value; + if (count($values) == $looking_for) { + $number = ($looking_for == 3) ? + (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64) : + (($values[0] % 32) * 64) + ($values[1] % 64); + $unicode[] = $number; + $values = []; + $looking_for = 1; + } + } + } + return $unicode; + } + + /** + * This function converts a Unicode array back to its UTF-8 representation + * + * @author Scott Michael Reynen + * + * @link http://www.randomchaos.com/document.php?source=php_and_unicode + * @see utf8_to_unicode() + */ + private static function unicode_to_utf8(&$str) + { + if (!is_array($str)) { + return ''; + } + + $utf8 = ''; + foreach ($str as $unicode) { + if ($unicode < 128) { + $utf8 .= chr($unicode); + } elseif ($unicode < 2048) { + $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); + $utf8 .= chr(128 + ($unicode % 64)); + } else { + $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); + $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); + $utf8 .= chr(128 + ($unicode % 64)); + } + } + return $utf8; + } + + /** + * This is an Unicode aware replacement for strrpos + * + * Uses mb_string extension if available + * + * @author Harry Fuecks + * + * @see strpos() + */ + private static function strrpos($haystack, $needle, $offset = 0) + { + if (!defined('UTF8_NOMBSTRING') && function_exists('mb_strrpos')) { + return mb_strrpos($haystack, $needle, $offset, 'utf-8'); + } + + if (!$offset) { + $ar = self::explode($needle, $haystack); + $count = count($ar); + if ($count > 1) { + return self::strlen($haystack) - self::strlen($ar[($count - 1)]) - self::strlen($needle); + } + return false; + } else { + if (!is_int($offset)) { + trigger_error('Offset must be an integer', E_USER_WARNING); + return false; + } + + $str = self::substr($haystack, $offset); + + if (false !== ($pos = self::strrpos($str, $needle))) { + return $pos + $offset; + } + return false; + } + } + + /** + * Unicode aware replacement for explode + * + * @author Harry Fuecks + * + * @see explode(); + */ + private static function explode($sep, $str) + { + if ($sep == '') { + trigger_error('Empty delimiter', E_USER_WARNING); + return false; + } + + return preg_split('!' . preg_quote($sep, '!') . '!u', $str); + } +} diff --git a/src/Stemmer/RussianStemmer.php b/src/Stemmer/RussianStemmer.php new file mode 100644 index 0000000..96991e8 --- /dev/null +++ b/src/Stemmer/RussianStemmer.php @@ -0,0 +1,112 @@ +processor = new WP_HTML_Tag_Processor($html); + } + + public function nextToken(): ?Token + { + // Could be text before the first tag? + + if (count($this->buffer) > 0) { + $token = array_shift($this->buffer); + return new Token($this->cursor, $token); + } elseif ($this->nextTag()) { + $this->processTag(); + $words = []; + + if ($this->chunk !== null) { + $words = Str::splitWords($this->chunk); + if (count($words) > 0) { + $this->buffer = $words; + } + } + + $tag = $this->processor->get_tag(); + + // This actually should never happen because of previous guards, the logic should be + // modified to reflect reality. + if ($tag === null) { + return null; + } + + return new Token($this->cursor, $tag, true); + } + + // Could be text after the last tag? + + return null; + } + + private function nextTag(): bool + { + return $this->processor->next_tag(['tag_closers' => 'visit']); + } + + /** + * @return void + */ + private function processTag() + { + $tokenStartsAt = $this->processor->get_token_starts_at(); + $tokenEndsAt = $this->processor->get_token_ends_at(); + + // Need to check if there is a gap between tags; + + if ($this->lastTokenEndsAt !== 0) { + $maybeChunkStartsAt = $this->lastTokenEndsAt + 1; + + if ($tokenStartsAt !== $maybeChunkStartsAt) { + $length = $tokenStartsAt - $maybeChunkStartsAt; + $this->chunk = $this->processor->substr($maybeChunkStartsAt, $length); + } else { + $this->chunk = null; + } + } + + $this->lastTokenEndsAt = $tokenEndsAt; + } +} diff --git a/src/Tokenizer/Token.php b/src/Tokenizer/Token.php new file mode 100644 index 0000000..2ae1cd1 --- /dev/null +++ b/src/Tokenizer/Token.php @@ -0,0 +1,34 @@ +isMetaword = $isMetaword; + $this->position = $position; + $this->value = $value; + } + + public function getIsMetaword(): bool + { + return $this->isMetaword; + } + + public function getPosition(): int + { + return $this->position; + } + + public function getValue(): string + { + return $this->value; + } +} diff --git a/src/Tokenizer/Tokenizer.php b/src/Tokenizer/Tokenizer.php new file mode 100644 index 0000000..afaae2c --- /dev/null +++ b/src/Tokenizer/Tokenizer.php @@ -0,0 +1,23 @@ +text = $text; + Str::splitWords($this->text); + } + + public function getToken(): Token + { + return new Token($this->cursor, 'test'); + } +} diff --git a/src/enqueue.php b/src/enqueue.php new file mode 100644 index 0000000..f48136e --- /dev/null +++ b/src/enqueue.php @@ -0,0 +1,10 @@ +
'; +} diff --git a/src/rest.php b/src/rest.php new file mode 100644 index 0000000..0f102d8 --- /dev/null +++ b/src/rest.php @@ -0,0 +1,70 @@ + 'POST', + 'callback' => 's_live_search', + 'permission_callback' => '__return_true', + ] + ); +} + +/** + * Generates search results for a live search query. + * + * @param WP_REST_Request $request The REST request object containing the search query. + * + * @throws Exception If an error occurs during the search process. + * + * @return WP_REST_Response The search results in JSON format. + */ +function s_live_search(WP_REST_Request $request) +{ + $query_string = sanitize_text_field($request->get_param('query')); + + // Generate a unique key for the transient based on the search parameters + $cache_key = 'custom_search_' . md5($query_string); + + // Try to retrieve the search results from the transient cache + $results = get_transient($cache_key); + + if (false === $results) { + // Perform your search logic and fetch data + $args = [ + 'post_type' => ['product', 'post'], + 's' => $query_string, + 'posts_per_page' => 4, + ]; + $query = new WP_Query($args); + + if ($query->have_posts()) { + ob_start(); + while ($query->have_posts()) { + $query->the_post(); + + global $post; + + echo $post->ID; + + echo '
' . get_the_title() . '
'; + } + $results = ob_get_clean(); + wp_reset_postdata(); + } else { + $results = ''; + } + } + + // Save the search results to the transient cache for 1 minute (60 seconds) + set_transient($cache_key, $results, 60); + + // Return the results as JSON + return rest_ensure_response($results); +} diff --git a/src/variation.php b/src/variation.php new file mode 100644 index 0000000..b0abeb6 --- /dev/null +++ b/src/variation.php @@ -0,0 +1,169 @@ +`. Support these by defaulting an undefined label and + // buttonText to `__( 'Search' )`. + $attributes = wp_parse_args( + $attributes, + [ + 'label' => __('Search', 'search-block'), + 'buttonText' => __('Search', 'search-block'), + ] + ); + + $input_id = wp_unique_id('wp-block-search__input-'); + $classnames = classnames_for_block_core_search($attributes); + $show_label = (!empty($attributes['showLabel'])) ? true : false; + $use_icon_button = (!empty($attributes['buttonUseIcon'])) ? true : false; + $show_input = (!empty($attributes['buttonPosition']) && 'button-only' === $attributes['buttonPosition']) ? false : true; + $show_button = (!empty($attributes['buttonPosition']) && 'no-button' === $attributes['buttonPosition']) ? false : true; + $query_params = (!empty($attributes['query'])) ? $attributes['query'] : []; + $input_markup = ''; + $button_markup = ''; + $query_params_markup = ''; + $inline_styles = styles_for_block_core_search($attributes); + $color_classes = get_color_classes_for_block_core_search($attributes); + $typography_classes = get_typography_classes_for_block_core_search($attributes); + $is_button_inside = !empty($attributes['buttonPosition']) && + 'button-inside' === $attributes['buttonPosition']; + // Border color classes need to be applied to the elements that have a border color. + $border_color_classes = get_border_color_classes_for_block_core_search($attributes); + + $label_inner_html = empty($attributes['label']) ? __('Search', 'search-block') : wp_kses_post($attributes['label']); + + $label_markup = sprintf( + '', + esc_attr($input_id), + $label_inner_html + ); + + if ($show_label && !empty($attributes['label'])) { + $label_classes = ['wp-block-search__label']; + if (!empty($typography_classes)) { + $label_classes[] = $typography_classes; + } + $label_markup = sprintf( + '', + esc_attr($input_id), + esc_attr(implode(' ', $label_classes)), + $inline_styles['label'], + $label_inner_html + ); + } + + if ($show_input) { + $input_classes = ['wp-block-search__input']; + if (!$is_button_inside && !empty($border_color_classes)) { + $input_classes[] = $border_color_classes; + } + if (!empty($typography_classes)) { + $input_classes[] = $typography_classes; + } + $input_markup = sprintf( + '', + $input_id, + esc_attr(implode(' ', $input_classes)), + get_search_query(), + esc_attr($attributes['placeholder']), + $inline_styles['input'] + ); + } + + if (count($query_params) > 0) { + foreach ($query_params as $param => $value) { + $query_params_markup .= sprintf( + '', + esc_attr($param), + esc_attr($value) + ); + } + } + + if ($show_button) { + $button_classes = ['wp-block-search__button']; + $button_internal_markup = ''; + if (!empty($color_classes)) { + $button_classes[] = $color_classes; + } + if (!empty($typography_classes)) { + $button_classes[] = $typography_classes; + } + $aria_label = ''; + + if (!$is_button_inside && !empty($border_color_classes)) { + $button_classes[] = $border_color_classes; + } + if (!$use_icon_button) { + if (!empty($attributes['buttonText'])) { + $button_internal_markup = wp_kses_post($attributes['buttonText']); + } + } else { + $aria_label = sprintf('aria-label="%s"', esc_attr(wp_strip_all_tags($attributes['buttonText']))); + $button_classes[] = 'has-icon'; + + $button_internal_markup = + ' + + '; + } + + // Include the button element class. + $button_classes[] = wp_theme_get_element_class_name('button'); + $button_markup = sprintf( + '', + esc_attr(implode(' ', $button_classes)), + $inline_styles['button'], + $aria_label, + $button_internal_markup + ); + } + + $field_markup_classes = $is_button_inside ? $border_color_classes : ''; + $field_markup = sprintf( + '
%s
', + esc_attr($field_markup_classes), + $inline_styles['wrapper'], + $input_markup . $query_params_markup . $button_markup + ); + $wrapper_attributes = get_block_wrapper_attributes( + ['class' => $classnames] + ); + + return sprintf( + '
%s
', + esc_url(home_url('/')), + $wrapper_attributes, + $label_markup . $field_markup + ); + }; + + // Get the existing block type + $cloned_block = WP_Block_Type_Registry::get_instance()->get_registered('core/search'); + + // Add the variation attributes + $cloned_block->attributes = array_merge($cloned_block->attributes, $variation_attributes); + + $cloned_block->name = 'search-block'; + $cloned_block->title = __('Live Search', 'search-block'); + $cloned_block->category = 'wp-blocks'; + + // Add the variation rendering callback + $cloned_block->render_callback = $variation_render_callback; + + $namespace = 'wp-blocks'; + $block_title = 'search-block'; + + // Register the new block type. + register_block_type($namespace . '/' . $block_title, $cloned_block); +} + +add_action('init', 'register_search_block_variation'); diff --git a/tests/.env.example b/tests/.env.example new file mode 100644 index 0000000..cf3a3ba --- /dev/null +++ b/tests/.env.example @@ -0,0 +1,39 @@ +# The path to the WordPress root directory, the one containing the wp-load.php file. +# This can be a relative path from the directory that contains the codeception.yml file, +# or an absolute path. +WORDPRESS_ROOT_FOLDER="/var/www/html" + +# The port on which the WordPress installation is served. +WORDPRESS_LOCALHOST_PORT=5389 + +# The URL and domain of the WordPress site used in end-to-end tests. +WORDPRESS_URL="http://localhost:5389" +WORDPRESS_DOMAIN=localhost:5389 + +# Tests will require a MySQL database to run. +# The database will be created if it does not exist. +# Do not use a database that contains important data! +WORDPRESS_DB_DSN="mysql:host=database;port=3306;dbname=wordpress" +WORDPRESS_DB_HOST=database:3306 +WORDPRESS_DB_NAME=wordpress +WORDPRESS_DB_USER=wordpress +WORDPRESS_DB_PASSWORD=wordpress +WORDPRESS_DB_URL=mysql://wordpress:wordpress@database:3306/wordpress +WORDPRESS_DB_LOCALHOST_PORT=5391 + +# The Integration suite will use this table prefix for the WordPress tables. +TEST_TABLE_PREFIX=test_ + +# This table prefix used by the WordPress site in end-to-end tests. +WORDPRESS_TABLE_PREFIX=wp_ + +# The username and password of the administrator user of the WordPress site used in end-to-end tests. +WORDPRESS_ADMIN_USER=admin +WORDPRESS_ADMIN_PASSWORD=password + +# The host and port of the ChromeDriver server that will be used in end-to-end tests. +CHROMEDRIVER_HOST=localhost +CHROMEDRIVER_PORT=5390 +CHROMEDRIVER_BINARY=vendor/bin/chromedriver + +WORDPRESS_ADMIN_PATH="/wp-admin" diff --git a/tests/_data/.gitignore b/tests/_data/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/_data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/_output/.gitignore b/tests/_output/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/_output/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php new file mode 100644 index 0000000..3214c87 --- /dev/null +++ b/tests/_support/AcceptanceTester.php @@ -0,0 +1,30 @@ +loginAsAdmin(); + $I->amOnPluginsPage(); + + $I->seePluginActivated('indexed-search'); + + $I->deactivatePlugin('indexed-search'); + + $I->seePluginDeactivated('indexed-search'); + + $I->activatePlugin('indexed-search'); + + $I->seePluginActivated('indexed-search'); + } +} diff --git a/tests/acceptance/_bootstrap.php b/tests/acceptance/_bootstrap.php new file mode 100644 index 0000000..4d73b8c --- /dev/null +++ b/tests/acceptance/_bootstrap.php @@ -0,0 +1,18 @@ +` command + * to run WP-CLI commands on the WordPress site and database used by the Acceptance suite. + * E.g.: + * `vendor/bin/codecept wp:cli Acceptance db import tests/Support/Data/dump.sql` to load dump file. + * `vendor/bin/codecept wp:cli Acceptance plugin activate woocommerce` to activate the WooCommerce plugin. + * `vendor/bin/codecept wp:cli Acceptance user create alice alice@example.com --role=administrator` to create a new user. + * `vendor/bin/codecept wp:cli Acceptance db export tests/Support/Data/dump.sql` to update the dump file. + */ diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml new file mode 100644 index 0000000..823f70b --- /dev/null +++ b/tests/docker-compose.yml @@ -0,0 +1,71 @@ +version: "3.8" + +services: + wordpress: + image: wordpress:6.4.1-php8.2-apache + restart: always + + env_file: + - .env + + ports: + - "${WORDPRESS_LOCALHOST_PORT}:80" + + environment: + WORDPRESS_DB_HOST: database + WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME} + WORDPRESS_DB_USER: ${WORDPRESS_DB_NAME} # Same as db name. + WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_NAME} # Same as db name. + WORDPRESS_SKIP_INSTALL: "yes" + + healthcheck: + test: + [ + "CMD", + "curl", + "--output", + "/dev/null", + "--silent", + "--fail", + "http://localhost:80", + ] + interval: 30s + timeout: 30s + retries: 3 + + tmpfs: + - /var/www/html + + volumes: + - ../:/var/www/html/wp-content/plugins/indexed-search + + depends_on: + - database + + database: + image: mariadb:10.8 + restart: always + + env_file: + - .env + + ports: + - "${WORDPRESS_DB_LOCALHOST_PORT}:3306" + + environment: + MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: "yes" + MARIADB_USER: ${WORDPRESS_DB_NAME} # Same as db name. + MARIADB_PASSWORD: ${WORDPRESS_DB_NAME} # Same as db name. + MARIADB_DATABASE: ${WORDPRESS_DB_NAME} # Same as db name. + + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 30s + timeout: 30s + retries: 3 + + tmpfs: + - /var/lib/mysql + + volumes: + - ./_data:/docker-entrypoint-initdb.d diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml new file mode 100644 index 0000000..830f50b --- /dev/null +++ b/tests/unit.suite.yml @@ -0,0 +1,4 @@ +# Unit Test Suite Configuration + +bootstrap: _bootstrap.php +modules: diff --git a/tests/unit/Tokenizer/TokenizerTest.php b/tests/unit/Tokenizer/TokenizerTest.php new file mode 100644 index 0000000..22bbd44 --- /dev/null +++ b/tests/unit/Tokenizer/TokenizerTest.php @@ -0,0 +1,22 @@ +tokenizer = new Tokenizer('

Hello

World!
'); + } + + /** + * @group tokenizer + */ + public function test_tokenizer_initializes(): void + { + $tokenizer = new Tokenizer('

Hello

World!
'); + $this->assertInstanceOf(Tokenizer::class, $tokenizer); + } +} diff --git a/tests/unit/_bootstrap.php b/tests/unit/_bootstrap.php new file mode 100644 index 0000000..7ba3814 --- /dev/null +++ b/tests/unit/_bootstrap.php @@ -0,0 +1,4 @@ +