diff --git a/plugins/woo-ai/.distignore b/plugins/woo-ai/.distignore new file mode 100644 index 00000000000..b7af8d72da2 --- /dev/null +++ b/plugins/woo-ai/.distignore @@ -0,0 +1,28 @@ +.distignore +.editorconfig +.gitignore +.travis.yml +.git/ +.eslintrc +.eslintignore +.wordpress-org/ +.turbo/ +composer.json +tsconfig.json +composer.lock +package-lock.json +package.json +webpack.config.js +phpcs.xml +NEXT_CHANGELOG.md +DEVELOPMENT.md + +changelog/ + +# build files +woo-ai.zip +node_modules/ +bin/ +vendor/ +woo-ai/ +src/ diff --git a/plugins/woo-ai/.editorconfig b/plugins/woo-ai/.editorconfig new file mode 100644 index 00000000000..c3dfa83750f --- /dev/null +++ b/plugins/woo-ai/.editorconfig @@ -0,0 +1,24 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +tab_width = 4 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +[*.txt] +trim_trailing_whitespace = false + +[*.{md,json,yml}] +trim_trailing_whitespace = false +indent_style = space +indent_size = 2 diff --git a/plugins/woo-ai/.eslintignore b/plugins/woo-ai/.eslintignore new file mode 100644 index 00000000000..84cb3903f19 --- /dev/null +++ b/plugins/woo-ai/.eslintignore @@ -0,0 +1,5 @@ +*.min.js +build +build-module +node_modules +vendor diff --git a/plugins/woo-ai/.eslintrc b/plugins/woo-ai/.eslintrc new file mode 100644 index 00000000000..4abb0869fc0 --- /dev/null +++ b/plugins/woo-ai/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + "extends": [ "plugin:@woocommerce/eslint-plugin/recommended" ], + "env": { + "browser": true, + "node": true + }, + "rules": { + "camelcase": 0, + "react/react-in-jsx-scope": "off", + "no-alert": "off" + } +} diff --git a/plugins/woo-ai/.gitignore b/plugins/woo-ai/.gitignore new file mode 100644 index 00000000000..b5946e7ed3f --- /dev/null +++ b/plugins/woo-ai/.gitignore @@ -0,0 +1,26 @@ +# Operating System files +.DS_Store +Thumbs.db + +# IDE files +.idea +.vscode/ +project.xml +project.properties +.project +.settings* +*.sublime-project +*.sublime-workspace +.sublimelinterrc + +# Dependencies +vendor/ +node_modules/ + +# Built assets +build/ +woo-ai.zip +build +build-module +build-style +woo-ai/ diff --git a/plugins/woo-ai/.nvmrc b/plugins/woo-ai/.nvmrc new file mode 100644 index 00000000000..b6a7d89c68e --- /dev/null +++ b/plugins/woo-ai/.nvmrc @@ -0,0 +1 @@ +16 diff --git a/plugins/woo-ai/.prettierrc.js b/plugins/woo-ai/.prettierrc.js new file mode 100644 index 00000000000..548adf77728 --- /dev/null +++ b/plugins/woo-ai/.prettierrc.js @@ -0,0 +1,3 @@ +// Import the default config file and expose it in the project root. +// Useful for editor integrations. +module.exports = require("@wordpress/prettier-config"); diff --git a/plugins/woo-ai/.travis.yml b/plugins/woo-ai/.travis.yml new file mode 100644 index 00000000000..215d3731dec --- /dev/null +++ b/plugins/woo-ai/.travis.yml @@ -0,0 +1,19 @@ +language: php + +before_script: + - | + # Remove Xdebug for a huge performance increase: + if [ -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini ]; then + phpenv config-rm xdebug.ini + else + echo "xdebug.ini does not exist" + fi + - composer install + +script: + - ./vendor/bin/phpcs -s -n -p * + +# Specifies that Travis should create branch builds only for master. +branches: + only: + - master diff --git a/plugins/woo-ai/CHANGELOG.md b/plugins/woo-ai/CHANGELOG.md new file mode 100644 index 00000000000..96437aa4d33 --- /dev/null +++ b/plugins/woo-ai/CHANGELOG.md @@ -0,0 +1,5 @@ +## [0.1.0](https://github.com/woocommerce/woocommerce/releases/tag/0.1.0) - 2023-06-05 + +- Patch - Unhook a duplicate Jetpack Contact Form button hook. +- Minor - Declare HPOS compatibility. +- Minor - Truncating product title before sending. diff --git a/plugins/woo-ai/DEVELOPMENT.md b/plugins/woo-ai/DEVELOPMENT.md new file mode 100644 index 00000000000..7bceb6726da --- /dev/null +++ b/plugins/woo-ai/DEVELOPMENT.md @@ -0,0 +1,52 @@ +# Woo AI + +Woo AI is a WooCommerce plugin that utilizes the power of artificial intelligence to enhance your eCommerce experience. With features like AI-powered product title optimization and automated product description generation, Woo AI is designed to boost your store's efficiency and sales potential. + +## Getting Started + +Please refer to [the Getting Started section of the WooCommerce Core `README.md`](https://github.com/woocommerce/woocommerce/blob/trunk/README.md) for a general-purpose guide on getting started. The rest of this document will assume that you've installed all of the prequisites and setup described there. + +## Plugin Development Environments + +The plugin makes use of [the `@wordpress/env` package](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/). +This supplies convenient commands for creating, destroying, cleaning, and testing WordPress environments. + +```bash +# Make sure you are in the working directory of the plugin you are interested in setting up the environment for +cd plugins/woo-ai +# Start will create the environment if necessary or start an existing one +pnpm -- wp-env start +# Stop will, well, stop the environment +pnpm -- wp-env stop +# Destroy will remove all of the environment's files. +pnpm -- wp-env destroy +``` + +## Development + +To enable Live(Hot) Reload when code is changed, run the following commands: + +```text +pnpm install +pnpm run start +``` + +To build the /woo-ai/ plugin directory (when loading the plugin via symlink), run: + +```text +pnpm install +pnpm run build +``` + +To build the plugin ZIP file, run: + +```text +pnpm install +pnpm run build:zip +``` + +See [wp-scripts](https://github.com/WordPress/gutenberg/tree/master/packages/scripts) for more usage information. + +## License + +This plugin is licensed under the GPL v3 or later. \ No newline at end of file diff --git a/plugins/woo-ai/NEXT_CHANGELOG.md b/plugins/woo-ai/NEXT_CHANGELOG.md new file mode 100644 index 00000000000..75f6c2bb0ac --- /dev/null +++ b/plugins/woo-ai/NEXT_CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +--- + +[See changelogs for previous versions](https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-beta-tester/readme.txt). diff --git a/plugins/woo-ai/README.md b/plugins/woo-ai/README.md new file mode 100644 index 00000000000..6f52944b7fb --- /dev/null +++ b/plugins/woo-ai/README.md @@ -0,0 +1,30 @@ +# Woo AI + +Woo AI is a WooCommerce plugin that utilizes the power of artificial intelligence to enhance your eCommerce experience. With features like AI-powered product title optimization and automated product description generation, Woo AI is designed to boost your store's efficiency and sales potential. + +## Installation + +1. Download the Woo AI plugin zip file. +2. Go to your WordPress Dashboard, then navigate to `Plugins > Add New > Upload Plugin`. +3. Select the downloaded Woo AI zip file to upload. +4. After uploading, click on `Activate Plugin`. + +## Usage + +**Improve Product Titles using AI Recommendations** + +1. Go to the WooCommerce `Products` page. +2. Select a product and click `Edit` or `Add New` to create a new product. +3. Start typing a product title. +4. Review and apply AI-generated title recommendations. + +**Generate Product Descriptions based on existing product data** + +1. Go to the WooCommerce `Products` page. +2. Select a product and click `Edit`. +3. Make sure the product has a sufficient title length and click on the `Write It For Me` button. +4. Review and apply the AI-generated product description. + +## License + +This plugin is licensed under the GPL v3 or later. \ No newline at end of file diff --git a/plugins/woo-ai/api/api.php b/plugins/woo-ai/api/api.php new file mode 100644 index 00000000000..7b07690dc4a --- /dev/null +++ b/plugins/woo-ai/api/api.php @@ -0,0 +1,23 @@ +product_data_suggestion_service = new Product_Data_Suggestion_Service( $prompt_generator, $completion_service ); + + $this->register_routes(); + } + + /** + * Register routes. + */ + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'get_response' ), + 'permission_callback' => array( $this, 'get_response_permission_check' ), + 'args' => array( + 'requested_data' => array( + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + 'required' => true, + ), + 'name' => array( + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + 'default' => '', + ), + 'description' => array( + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'sanitize_text_field', + 'default' => '', + ), + 'categories' => array( + 'type' => 'array', + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'wp_parse_id_list', + 'items' => array( + 'type' => 'integer', + ), + 'default' => array(), + ), + 'tags' => array( + 'type' => 'array', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'default' => array(), + ), + 'attributes' => array( + 'type' => 'array', + 'validate_callback' => 'rest_validate_request_arg', + 'default' => array(), + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'key' => array( + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'value' => array( + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ), + ), + ), + ) + ); + } + + /** + * Check if a given request has access to create a product. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_Error|boolean + */ + public function get_response_permission_check( WP_REST_Request $request ) { + if ( ! wc_rest_check_post_permissions( 'product', 'create' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Get the product-data suggestions. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_Error|WP_HTTP_Response|WP_REST_Response + */ + public function get_response( WP_REST_Request $request ) { + $requested_data = $request->get_param( 'requested_data' ); + $name = $request->get_param( 'name' ); + $description = $request->get_param( 'description' ); + $categories = $request->get_param( 'categories' ); + $tags = $request->get_param( 'tags' ); + $attributes = $request->get_param( 'attributes' ); + + // Strip HTML tags from the description. + if ( ! empty( $description ) ) { + $description = wp_strip_all_tags( $request->get_param( 'description' ) ); + } + + // Check if enough data is provided in the name and description to get suggestions. + if ( strlen( $name ) < 10 && strlen( $description ) < 50 ) { + return new WP_Error( 'error', __( 'Enter a few descriptive words or add product description, tags, or attributes to generate name ideas.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + try { + $product_data_request = new Product_Data_Suggestion_Request( $requested_data, $name, $description, $tags, $categories, $attributes ); + $suggestions = $this->product_data_suggestion_service->get_suggestions( $product_data_request ); + } catch ( Product_Data_Suggestion_Exception $e ) { + return new WP_Error( 'error', $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + return rest_ensure_response( $suggestions ); + + } + +} + +new Product_Data_Suggestion_API(); diff --git a/plugins/woo-ai/assets/images/icons/alert.svg b/plugins/woo-ai/assets/images/icons/alert.svg new file mode 100644 index 00000000000..7d8eadb5e5c --- /dev/null +++ b/plugins/woo-ai/assets/images/icons/alert.svg @@ -0,0 +1,15 @@ + + + + + diff --git a/plugins/woo-ai/assets/images/icons/magic.svg b/plugins/woo-ai/assets/images/icons/magic.svg new file mode 100644 index 00000000000..53c58273ef4 --- /dev/null +++ b/plugins/woo-ai/assets/images/icons/magic.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + diff --git a/plugins/woo-ai/bin/build-zip.sh b/plugins/woo-ai/bin/build-zip.sh new file mode 100755 index 00000000000..3bfc34d4f4a --- /dev/null +++ b/plugins/woo-ai/bin/build-zip.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +PLUGIN_SLUG="woo-ai" +PROJECT_PATH=$(pwd) +BUILD_PATH="${PROJECT_PATH}/build" +DEST_PATH="$BUILD_PATH/$PLUGIN_SLUG" + +echo "Generating build directory..." +rm -rf "$BUILD_PATH" +mkdir -p "$DEST_PATH" + +echo "Installing PHP and JS dependencies..." +pnpm install +echo "Running JS Build..." +pnpm -w run build --filter=woo-ai || exit "$?" + +echo "Syncing files..." +rsync -rc --exclude-from="$PROJECT_PATH/.distignore" "$PROJECT_PATH/" "$DEST_PATH/" --delete --delete-excluded + +echo "Generating zip file..." +cd "$BUILD_PATH" || exit +zip -q -r "${PLUGIN_SLUG}.zip" "$PLUGIN_SLUG/" + +cd "$PROJECT_PATH" || exit +mv "$BUILD_PATH/${PLUGIN_SLUG}.zip" "$PROJECT_PATH" +echo "${PLUGIN_SLUG}.zip file generated!" + +echo "Build done!" diff --git a/plugins/woo-ai/changelog/.gitkeep b/plugins/woo-ai/changelog/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/plugins/woo-ai/changelog/add-woo-ai-plugin b/plugins/woo-ai/changelog/add-woo-ai-plugin new file mode 100644 index 00000000000..ed87ab188a5 --- /dev/null +++ b/plugins/woo-ai/changelog/add-woo-ai-plugin @@ -0,0 +1,4 @@ +Significance: minor +Type: add + +Initial release of WooAI plugin. diff --git a/plugins/woo-ai/composer.json b/plugins/woo-ai/composer.json new file mode 100644 index 00000000000..d6d0892569a --- /dev/null +++ b/plugins/woo-ai/composer.json @@ -0,0 +1,65 @@ +{ + "name": "woocommerce/woo-ai", + "description": "Run AI experiments in WooCommerce.", + "homepage": "https://woocommerce.com/", + "type": "wordpress-plugin", + "license": "GPL-3.0-or-later", + "prefer-stable": true, + "minimum-stability": "dev", + "version": "0.1.0", + "require": { + "composer/installers": "~1.7", + "ext-json": "*" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.5", + "woocommerce/woocommerce-sniffs": "^0.1.3", + "automattic/jetpack-changelogger": "3.3.0" + }, + "scripts": { + "test": [ + "phpunit" + ], + "phpcs": [ + "phpcs -s -p" + ], + "phpcs-pre-commit": [ + "phpcs -s -p -n" + ], + "phpcbf": [ + "phpcbf -p" + ] + }, + "extra": { + "scripts-description": { + "test": "Run unit tests", + "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer", + "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier" + }, + "changelogger": { + "formatter": { + "filename": "../../tools/changelogger/class-plugin-formatter.php" + }, + "types": { + "fix": "Fixes an existing bug", + "add": "Adds functionality", + "update": "Update existing functionality", + "dev": "Development related task", + "tweak": "A minor adjustment to the codebase", + "performance": "Address performance issues", + "enhancement": "Improve existing functionality" + }, + "versioning": "wordpress", + "changelog": "CHANGELOG.md" + } + }, + "config": { + "platform": { + "php": "7.2" + }, + "allow-plugins": { + "composer/installers": true, + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/plugins/woo-ai/composer.lock b/plugins/woo-ai/composer.lock new file mode 100644 index 00000000000..ad6f0c9830a --- /dev/null +++ b/plugins/woo-ai/composer.lock @@ -0,0 +1,2654 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "f04d60d67b018f03857889eabb4fde67", + "packages": [ + { + "name": "composer/installers", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Starbug", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "miaoxing", + "modulework", + "modx", + "moodle", + "osclass", + "pantheon", + "phpbb", + "piwik", + "ppi", + "processwire", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "tastyigniter", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.12.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-09-13T08:19:44+00:00" + } + ], + "packages-dev": [ + { + "name": "automattic/jetpack-changelogger", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/Automattic/jetpack-changelogger.git", + "reference": "8f63c829b8d1b0d7b1d5de93510d78523ed18959" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Automattic/jetpack-changelogger/zipball/8f63c829b8d1b0d7b1d5de93510d78523ed18959", + "reference": "8f63c829b8d1b0d7b1d5de93510d78523ed18959", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "symfony/console": "^3.4 || ^5.2 || ^6.0", + "symfony/process": "^3.4 || ^5.2 || ^6.0", + "wikimedia/at-ease": "^1.2 || ^2.0" + }, + "require-dev": { + "wikimedia/testing-access-wrapper": "^1.0 || ^2.0", + "yoast/phpunit-polyfills": "1.0.4" + }, + "bin": [ + "bin/changelogger" + ], + "type": "project", + "extra": { + "autotagger": true, + "branch-alias": { + "dev-trunk": "3.3.x-dev" + }, + "mirror-repo": "Automattic/jetpack-changelogger", + "version-constants": { + "::VERSION": "src/Application.php" + }, + "changelogger": { + "link-template": "https://github.com/Automattic/jetpack-changelogger/compare/${old}...${new}" + } + }, + "autoload": { + "psr-4": { + "Automattic\\Jetpack\\Changelog\\": "lib", + "Automattic\\Jetpack\\Changelogger\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Jetpack Changelogger tool. Allows for managing changelogs by dropping change files into a changelog directory with each PR.", + "support": { + "source": "https://github.com/Automattic/jetpack-changelogger/tree/v3.3.0" + }, + "time": "2022-12-26T13:49:01+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.7.2", + "source": { + "type": "git", + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, + "time": "2022-02-04T12:51:07+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+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": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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/master" + }, + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.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/master" + }, + "time": "2018-07-08T19:19:57+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": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "77a32518733312af16a44300404e945338981de3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, + "time": "2022-03-15T21:29:03+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2", + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2 || ^2.0", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.17.0" + }, + "time": "2023-02-02T15:41:36+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1 || ^4.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.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": "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", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" + }, + "time": "2018-10-31T16:06:48+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", + "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "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": "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/2.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:42:26+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "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/1.2.1" + }, + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "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/2.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:20:02+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "9c1da83261628cb24b6a6df371b6e312b3954768" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768", + "reference": "9c1da83261628cb24b6a6df371b6e312b3954768", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "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" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "abandoned": true, + "time": "2021-07-26T12:15:06+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0.1", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^4.0", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.5-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": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" + }, + "time": "2020-01-08T08:45:45+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "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/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770", + "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "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" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:31:48+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/6296a0c086dd0117c1b78b059374d7fcbe7545ae", + "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "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" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-07T05:30:20+00:00" + }, + { + "name": "sebastian/environment", + "version": "4.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:53:42+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6", + "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.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": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:00:17+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "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" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" + }, + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:40:27+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:37:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", + "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.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": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:34:24+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "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" + } + ], + "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/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T07:30:19+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "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": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "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" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2023-02-22T23:07:41+00:00" + }, + { + "name": "symfony/console", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/a10b1da6fc93080c180bba7219b5ff5b7518fe81", + "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/debug": "~2.8|~3.0|~4.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.3|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.3|~4.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/v3.4.47" + }, + "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": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/debug", + "version": "v4.4.44", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "1a692492190773c5310bc7877cb590c04c2f05be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/1a692492190773c5310bc7877cb590c04c2f05be", + "reference": "1a692492190773c5310bc7877cb590c04c2f05be", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/log": "^1|^2|^3" + }, + "conflict": { + "symfony/http-kernel": "<3.4" + }, + "require-dev": { + "symfony/http-kernel": "^3.4|^4.0|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/debug/tree/v4.4.44" + }, + "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" + } + ], + "abandoned": "symfony/error-handler", + "time": "2022-07-28T16:29:46+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/process", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/b8648cf1d5af12a44a51d07ef9bf980921f15fca", + "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v3.4.47" + }, + "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": "2020-10-24T10:57:07+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "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" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "wikimedia/at-ease", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/at-ease.git", + "reference": "013ac61929797839c80a111a3f1a4710d8248e7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/at-ease/zipball/013ac61929797839c80a111a3f1a4710d8248e7a", + "reference": "013ac61929797839c80a111a3f1a4710d8248e7a", + "shasum": "" + }, + "require": { + "php": ">=5.6.99" + }, + "require-dev": { + "jakub-onderka/php-console-highlighter": "0.3.2", + "jakub-onderka/php-parallel-lint": "1.0.0", + "mediawiki/mediawiki-codesniffer": "22.0.0", + "mediawiki/minus-x": "0.3.1", + "ockcyp/covers-validator": "0.5.1 || 0.6.1", + "phpunit/phpunit": "4.8.36 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/Wikimedia/Functions.php" + ], + "psr-4": { + "Wikimedia\\AtEase\\": "src/Wikimedia/AtEase/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Tim Starling", + "email": "tstarling@wikimedia.org" + }, + { + "name": "MediaWiki developers", + "email": "wikitech-l@lists.wikimedia.org" + } + ], + "description": "Safe replacement to @ for suppressing warnings.", + "homepage": "https://www.mediawiki.org/wiki/at-ease", + "support": { + "source": "https://github.com/wikimedia/at-ease/tree/master" + }, + "time": "2018-10-10T15:39:06+00:00" + }, + { + "name": "woocommerce/woocommerce-sniffs", + "version": "0.1.3", + "source": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce-sniffs.git", + "reference": "4576d54595614d689bc4436acff8baaece3c5bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/4576d54595614d689bc4436acff8baaece3c5bb0", + "reference": "4576d54595614d689bc4436acff8baaece3c5bb0", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "php": ">=7.0", + "phpcompatibility/phpcompatibility-wp": "^2.1.0", + "wp-coding-standards/wpcs": "^2.3.0" + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Claudio Sanches", + "email": "claudio@automattic.com" + } + ], + "description": "WooCommerce sniffs", + "keywords": [ + "phpcs", + "standards", + "woocommerce", + "wordpress" + ], + "support": { + "issues": "https://github.com/woocommerce/woocommerce-sniffs/issues", + "source": "https://github.com/woocommerce/woocommerce-sniffs/tree/0.1.3" + }, + "time": "2022-02-17T15:34:51+00:00" + }, + { + "name": "wp-coding-standards/wpcs", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", + "reference": "7da1894633f168fe244afc6de00d141f27517b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62", + "reference": "7da1894633f168fe244afc6de00d141f27517b62", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "squizlabs/php_codesniffer": "^3.3.1" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6", + "phpcompatibility/php-compatibility": "^9.0", + "phpcsstandards/phpcsdevtools": "^1.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Contributors", + "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", + "keywords": [ + "phpcs", + "standards", + "wordpress" + ], + "support": { + "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", + "source": "https://github.com/WordPress/WordPress-Coding-Standards", + "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" + }, + "time": "2020-05-13T23:57:56+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "ext-json": "*" + }, + "platform-dev": [], + "platform-overrides": { + "php": "7.2" + }, + "plugin-api-version": "2.3.0" +} diff --git a/plugins/woo-ai/includes/class-woo-ai-admin-notices.php b/plugins/woo-ai/includes/class-woo-ai-admin-notices.php new file mode 100644 index 00000000000..b4861a31fb9 --- /dev/null +++ b/plugins/woo-ai/includes/class-woo-ai-admin-notices.php @@ -0,0 +1,28 @@ + array(), + 'version' => filemtime( $script_path ), + ); + $script_url = plugins_url( $script_path, __FILE__ ); + + $script_asset['dependencies'][] = WC_ADMIN_APP; // Add WCA as a dependency to ensure it loads first. + + wp_register_script( + 'woo-ai', + $script_url, + $script_asset['dependencies'], + $script_asset['version'], + true + ); + + wp_enqueue_script( 'woo-ai' ); + + if ( class_exists( '\Automattic\Jetpack\Connection\Initial_State' ) ) { + wp_add_inline_script( 'woo-ai', Connection_Initial_State::render(), 'before' ); + } + + $css_file_version = filemtime( dirname( __FILE__ ) . '/../build/index.css' ); + + wp_register_style( + 'wp-components', + plugins_url( 'dist/components/style.css', __FILE__ ), + array(), + $css_file_version + ); + + wp_register_style( + 'woo-ai', + plugins_url( '/../build/index.css', __FILE__ ), + // Add any dependencies styles may have, such as wp-components. + array( + 'wp-components', + ), + $css_file_version + ); + + wp_enqueue_style( 'woo-ai' ); + } + + /** + * Add gpt button to the editor. + * + * @param String $editor_id Editor Id. + */ + public function add_gpt_button( $editor_id ) { + if ( 'content' !== $editor_id || ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) ) { + return; + } + + echo '
'; + } + + /** + * Add the form and button for generating product title suggestions to the editor. + */ + public function add_name_generation_form() { + if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) { + return; + } + + echo '
'; + } + + /** + * Add gpt form to the editor. + * + * @param String $content Gpt form content. + */ + public function add_gpt_form( $content ) { + global $post; + + // Check if the current post type is 'product'. + if ( 'product' === $post->post_type ) { + + // Check if the content contains the specific editor ID. + $editor_container_id = 'wp-content-editor-container'; + $editor_container_position = strpos( $content, $editor_container_id ); + + if ( false !== $editor_container_position ) { + $gpt_form = + '
'; + $content = $gpt_form . $content; + } + } + + return $content; + } + +} + +new Woo_AI_Product_Text_Generation(); diff --git a/plugins/woo-ai/includes/class-woo-ai.php b/plugins/woo-ai/includes/class-woo-ai.php new file mode 100644 index 00000000000..af1ca05d2ea --- /dev/null +++ b/plugins/woo-ai/includes/class-woo-ai.php @@ -0,0 +1,204 @@ +plugin_name = plugin_basename( WOO_AI_FILE ); + $this->plugin_config = array( + 'plugin_file' => 'woocommerce/woocommerce.php', + 'slug' => 'woocommerce', + 'proper_folder_name' => 'woocommerce', + 'api_url' => 'https://K.wordpress.org/plugins/info/1.0/woocommerce.json', + 'repo_url' => 'https://wordpress.org/plugins/woocommerce/', + ); + + add_filter( 'jetpack_offline_mode', '__return_false' ); + add_action( 'current_screen', array( $this, 'includes' ) ); + } + + /** + * Include any classes we need within admin. + */ + public function includes() { + $current_screen = get_current_screen(); + + if ( 'post' === $current_screen->base && 'product' === $current_screen->post_type ) { + include_once dirname( __FILE__ ) . '/class-woo-ai-product-text-generation.php'; + } + } + + + /** + * Get plugin download URL. + * + * @since 1.0 + * @param string $version The version. + * @return string + */ + public function get_download_url( $version ) { + $data = $this->get_wporg_data(); + + if ( empty( $data->versions->$version ) ) { + return false; + } + + return $data->versions->$version; + } + + /** + * Get Plugin data. + * + * @since 1.0 + * @return object $data The data. + */ + public function get_plugin_data() { + return get_plugin_data( WP_PLUGIN_DIR . '/' . $this->plugin_config['plugin_file'] ); + } + + /** + * Return true if version string is a beta version. + * + * @param string $version_str Version string. + * @return bool + */ + protected static function is_beta_version( $version_str ) { + return strpos( $version_str, 'beta' ) !== false; + } + + /** + * Return true if version string is a Release Candidate. + * + * @param string $version_str Version string. + * @return bool + */ + protected static function is_rc_version( $version_str ) { + return strpos( $version_str, 'rc' ) !== false; + } + + /** + * Return true if version string is a stable version. + * + * @param string $version_str Version string. + * @return bool + */ + protected static function is_stable_version( $version_str ) { + return ! self::is_beta_version( $version_str ) && ! self::is_rc_version( $version_str ); + } + + /** + * Return true if release's version string belongs to beta channel, i.e. + * if it's beta, rc or stable release. + * + * @param string $version_str Version string of the release. + * @return bool + */ + protected static function is_in_beta_channel( $version_str ) { + return self::is_beta_version( $version_str ) || self::is_rc_version( $version_str ) || self::is_stable_version( $version_str ); + } + + /** + * Return true if release's version string belongs to release candidate channel, i.e. + * if it's rc or stable release. + * + * @param string $version_str Version string of the release. + * @return bool + */ + protected static function is_in_rc_channel( $version_str ) { + return self::is_rc_version( $version_str ) || self::is_stable_version( $version_str ); + } + + /** + * Return true if release's version string belongs to stable channel, i.e. + * if it's stable release and not a beta or rc. + * + * @param string $version_str Version string of the release. + * @return bool + */ + protected static function is_in_stable_channel( $version_str ) { + return self::is_stable_version( $version_str ); + } + + /** + * Return available versions from wp.org tags belonging to selected channel. + * + * @param string $channel Filter versions by channel: all|beta|rc|stable. + * @return array(string) + */ + public function get_tags( $channel = 'all' ) { + $data = $this->get_wporg_data(); + $releases = (array) $data->versions; + + unset( $releases['trunk'] ); + + $releases = array_keys( $releases ); + foreach ( $releases as $index => $version ) { + if ( version_compare( $version, '3.6', '<' ) ) { + unset( $releases[ $index ] ); + } + } + + if ( 'beta' === $channel ) { + $releases = array_filter( $releases, array( __CLASS__, 'is_in_beta_channel' ) ); + } elseif ( 'rc' === $channel ) { + $releases = array_filter( $releases, array( __CLASS__, 'is_in_rc_channel' ) ); + } elseif ( 'stable' === $channel ) { + $releases = array_filter( $releases, array( __CLASS__, 'is_in_stable_channel' ) ); + } + + return $releases; + } + +} diff --git a/plugins/woo-ai/includes/completion/class-completion-exception.php b/plugins/woo-ai/includes/completion/class-completion-exception.php new file mode 100644 index 00000000000..949f88c1392 --- /dev/null +++ b/plugins/woo-ai/includes/completion/class-completion-exception.php @@ -0,0 +1,17 @@ +validate_jetpack_connection(); + + $site_id = $this->get_site_id(); + $response = $this->send_request_to_api( $site_id, $arguments ); + + return $this->process_response( $response ); + } + + /** + * Validates the Jetpack connection. + * + * @throws Completion_Exception If Jetpack connection is not ready. + */ + private function validate_jetpack_connection(): void { + if ( ! $this->is_jetpack_ready() ) { + throw new Completion_Exception( __( 'Not connected to Jetpack. Please make sure that Jetpack is active and connected.', 'woocommerce' ), 400 ); + } + } + + /** + * Returns whether Jetpack connection is ready. + * + * @return bool True if Jetpack connection is ready, false otherwise. + */ + private function is_jetpack_ready(): bool { + return Jetpack::connection()->has_connected_owner() && Jetpack::is_connection_ready(); + } + + /** + * Gets the Jetpack Site ID. + * + * @return string The Jetpack Site ID. + * + * @throws Completion_Exception If no Jetpack Site ID is found. + */ + private function get_site_id(): string { + $site_id = Jetpack_Options::get_option( 'id' ); + if ( ! $site_id ) { + throw new Completion_Exception( __( 'No Jetpack Site ID found. Please make sure that Jetpack is active and connected.', 'woocommerce' ), 400 ); + } + + return (string) $site_id; + } + + /** + * Sends request to the API and gets the response. + * + * @param string $site_id The site ID. + * @param array $arguments An array of arguments to send to the API. + * + * @return array|WP_Error The response from the API. + */ + private function send_request_to_api( string $site_id, array $arguments ) { + return Client::wpcom_json_api_request_as_user( + "/sites/{$site_id}/jetpack-ai/completions", + '2', + array( + 'method' => 'POST', + 'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ), + 'timeout' => self::COMPLETION_TIMEOUT, + ), + $arguments + ); + } + + /** + * Processes the API response. + * + * @param array|WP_Error $response The response from the API. + * + * @return string The completion response. + * + * @throws Completion_Exception If there's an error in the response. + */ + private function process_response( $response ): string { + if ( is_wp_error( $response ) ) { + $this->handle_wp_error( $response ); + } + + if ( ! isset( $response['response']['code'] ) || 200 !== $response['response']['code'] ) { + /* translators: %s: The error message. */ + throw new Completion_Exception( sprintf( __( 'Failed to get completion ( reason: %s )', 'woocommerce' ), $response['response']['message'] ), 400 ); + } + + $response_body = wp_remote_retrieve_body( $response ); + + try { + // Extract the string from the response. Response might be wrapped in quotes and escaped. E.g. "{ \n \"foo\": \"bar\" \n }". + $decoded = json_decode( $response_body, true, 512, JSON_THROW_ON_ERROR ); + } catch ( JsonException $e ) { + $this->handle_json_exception( $e ); + } + + return $this->get_completion_string_from_decoded_response( $decoded, $response_body ); + } + + /** + * Handles WP_Error response. + * + * @param WP_Error $response The WP_Error response. + * + * @throws Completion_Exception With the error message from the response. + */ + private function handle_wp_error( WP_Error $response ): void { + /* translators: %s: The error message. */ + throw new Completion_Exception( sprintf( __( 'Failed to get completion ( reason: %s )', 'woocommerce' ), $response->get_error_message() ), 400 ); + } + + /** + * Handles JSON parsing exceptions. + * + * @param JsonException $e The JSON exception. + * + * @throws Completion_Exception With the error message from the JSON exception. + */ + private function handle_json_exception( JsonException $e ): void { + /* translators: %s: The error message. */ + throw new Completion_Exception( sprintf( __( 'Failed to decode completion response ( reason: %s )', 'woocommerce' ), $e->getMessage() ), 500, $e ); + } + + /** + * Retrieves the completion string from the decoded response. + * + * @param mixed $decoded The decoded JSON response. + * @param string $response_body The original response body. + * + * @return string The completion string. + * + * @throws Completion_Exception If the decoded response is invalid or empty. + */ + private function get_completion_string_from_decoded_response( $decoded, string $response_body ): string { + if ( ! is_string( $decoded ) ) { + // Check if the response is an error. + if ( isset( $decoded['code'] ) ) { + $error_message = $decoded['message'] ?? $decoded['code']; + /* translators: %s: The error message. */ + throw new Completion_Exception( sprintf( __( 'Failed to get completion ( reason: %s )', 'woocommerce' ), $error_message ), 400 ); + } + + // If the decoded response is not an error, it means that the response was not wrapped in quotes and escaped, so we can use it as is. + $decoded = $response_body; + } + if ( empty( $decoded ) || ! is_string( $decoded ) ) { + /* translators: %s: The response body. */ + throw new Completion_Exception( sprintf( __( 'Invalid or empty completion response: %s', 'woocommerce' ), $response_body ), 500 ); + } + + return $decoded; + } + +} diff --git a/plugins/woo-ai/includes/completion/interface-completion-service.php b/plugins/woo-ai/includes/completion/interface-completion-service.php new file mode 100644 index 00000000000..c44ea23a997 --- /dev/null +++ b/plugins/woo-ai/includes/completion/interface-completion-service.php @@ -0,0 +1,26 @@ +product_category_formatter = $product_category_formatter; + $this->product_attribute_formatter = $product_attribute_formatter; + $this->json_request_formatter = $json_request_formatter; + } + + /** + * Build the user prompt based on the request. + * + * @param Product_Data_Suggestion_Request $request The request to build the prompt for. + * + * @return string + */ + public function get_user_prompt( Product_Data_Suggestion_Request $request ): string { + $request_prompt = $this->get_request_prompt( $request ); + + $prompt = sprintf( + self::PROMPT_TEMPLATE, + $request->requested_data, + $request->requested_data, + $request->requested_data, + $request_prompt + ); + + // Append the JSON request prompt. + $prompt .= "\n" . $this->get_example_response( $request ); + + return $prompt; + } + + /** + * Build a prompt for the request. + * + * @param Product_Data_Suggestion_Request $request The request to build the prompt for. + * + * @return string + */ + private function get_request_prompt( Product_Data_Suggestion_Request $request ): string { + $request_prompt = ''; + + if ( ! empty( $request->name ) ) { + $request_prompt .= sprintf( + "\nName: %s", + $request->name + ); + } + + if ( ! empty( $request->description ) ) { + $request_prompt .= sprintf( + "\nDescription: %s", + $request->description + ); + } + + if ( ! empty( $request->tags ) ) { + $request_prompt .= sprintf( + "\nTags (comma separated): %s", + implode( ', ', $request->tags ) + ); + } + + if ( ! empty( $request->categories ) ) { + $request_prompt .= sprintf( + "\nCategories (comma separated, child categories separated with >): %s", + $this->product_category_formatter->format( $request->categories ) + ); + } + + if ( ! empty( $request->attributes ) ) { + $request_prompt .= sprintf( + "\n%s", + $this->product_attribute_formatter->format( $request->attributes ) + ); + } + + return $request_prompt; + } + + /** + * Get an example response for the request. + * + * @param Product_Data_Suggestion_Request $request The request to build the example response for. + * + * @return string + */ + private function get_example_response( Product_Data_Suggestion_Request $request ): string { + $response_array = array( + 'suggestions' => array( + array( + 'content' => sprintf( 'An improved alternative to the product\'s %s', $request->requested_data ), + 'reason' => sprintf( 'First concise reason why this %s helps the SEO and sales of the product.', $request->requested_data ), + ), + array( + 'content' => sprintf( 'Another improved alternative to the product\'s %s', $request->requested_data ), + 'reason' => sprintf( 'Second concise reason this %s helps the SEO and sales of the product.', $request->requested_data ), + ), + ), + ); + + return $this->json_request_formatter->format( $response_array ); + } + +} diff --git a/plugins/woo-ai/includes/product-data-suggestion/class-product-data-suggestion-request.php b/plugins/woo-ai/includes/product-data-suggestion/class-product-data-suggestion-request.php new file mode 100644 index 00000000000..e1bc5723e97 --- /dev/null +++ b/plugins/woo-ai/includes/product-data-suggestion/class-product-data-suggestion-request.php @@ -0,0 +1,109 @@ +validate_requested_data( $requested_data ); + + $this->requested_data = $requested_data; + $this->name = $name; + $this->description = $description; + $this->tags = $tags; + $this->categories = $categories; + $this->attributes = $attributes; + } + + /** + * Validates the requested attribute. + * + * @param string $requested_data The attribute that suggestions are being requested for. + * + * @return void + * + * @throws Product_Data_Suggestion_Exception If the requested data is invalid. + */ + private function validate_requested_data( string $requested_data ): void { + $valid_requested_data_keys = array( + self::REQUESTED_DATA_NAME, + self::REQUESTED_DATA_DESCRIPTION, + self::REQUESTED_DATA_TAGS, + self::REQUESTED_DATA_CATEGORIES, + ); + + if ( ! in_array( $requested_data, $valid_requested_data_keys, true ) ) { + throw new Product_Data_Suggestion_Exception( 'Invalid requested data.', 400 ); + } + } +} diff --git a/plugins/woo-ai/includes/product-data-suggestion/class-product-data-suggestion-service.php b/plugins/woo-ai/includes/product-data-suggestion/class-product-data-suggestion-service.php new file mode 100644 index 00000000000..9e0a9919555 --- /dev/null +++ b/plugins/woo-ai/includes/product-data-suggestion/class-product-data-suggestion-service.php @@ -0,0 +1,78 @@ +prompt_generator = $prompt_generator; + $this->completion_service = $completion_service; + } + + /** + * Get suggestions for the given request. + * + * @param Product_Data_Suggestion_Request $request The request. + * + * @return array An array of suggestions. Each suggestion is an associative array with the following keys: + * - content: The suggested content. + * - reason: The reason for the suggestion. + * + * @throws Product_Data_Suggestion_Exception If If getting the suggestions fails or the suggestions cannot be decoded from JSON. + */ + public function get_suggestions( Product_Data_Suggestion_Request $request ): array { + $arguments = array( + 'content' => $this->prompt_generator->get_user_prompt( $request ), + 'skip_cache' => true, + 'feature' => 'woo_ai_plugin', + ); + + try { + $completion = $this->completion_service->get_completion( $arguments ); + } catch ( Completion_Exception $e ) { + /* translators: %s: The error message. */ + throw new Product_Data_Suggestion_Exception( sprintf( __( 'Failed to fetch the suggestions: %s', 'woocommerce' ), $e->getMessage() ), $e->getCode(), $e ); + } + + try { + return json_decode( $completion, true, 512, JSON_THROW_ON_ERROR ); + } catch ( JsonException $e ) { + throw new Product_Data_Suggestion_Exception( 'Failed to decode the suggestions. Please try again.', 400, $e ); + } + } + +} diff --git a/plugins/woo-ai/includes/prompt-formatter/class-json-request-formatter.php b/plugins/woo-ai/includes/prompt-formatter/class-json-request-formatter.php new file mode 100644 index 00000000000..4e4bc79e498 --- /dev/null +++ b/plugins/woo-ai/includes/prompt-formatter/class-json-request-formatter.php @@ -0,0 +1,57 @@ +validate_data( $data ) ) { + throw new InvalidArgumentException( 'Invalid input data. Provide an array.' ); + } + + return sprintf( + self::JSON_REQUEST_PROMPT, + wp_json_encode( $data ) + ); + } + + /** + * Validates the data to make sure it can be formatted. + * + * @param mixed $data The data to format. + * + * @return bool True if the data is valid, false otherwise. + */ + public function validate_data( $data ): bool { + return ! empty( $data ) && is_array( $data ); + } + +} diff --git a/plugins/woo-ai/includes/prompt-formatter/class-product-attribute-formatter.php b/plugins/woo-ai/includes/prompt-formatter/class-product-attribute-formatter.php new file mode 100644 index 00000000000..b9513b9d410 --- /dev/null +++ b/plugins/woo-ai/includes/prompt-formatter/class-product-attribute-formatter.php @@ -0,0 +1,82 @@ +attribute_labels = wc_get_attribute_taxonomy_labels(); + } + + /** + * Format attributes for the prompt + * + * @param array $data An associative array of attributes with the format { "name": "name", "value": "value" }. + * + * @return string A string containing the formatted attributes. + * + * @throws InvalidArgumentException If the input data is not valid. + */ + public function format( $data ): string { + if ( ! $this->validate_data( $data ) ) { + throw new InvalidArgumentException( 'Invalid input data. Provide an array of attributes.' ); + } + + $formatted_attributes = ''; + + foreach ( $data as $attribute ) { + // Skip if the attribute value is empty or if the attribute label is empty. + if ( empty( $attribute['value'] ) || empty( $this->attribute_labels[ $attribute['name'] ] ) ) { + continue; + } + $label = $this->attribute_labels[ $attribute['name'] ]; + + $formatted_attributes .= sprintf( "%s: \"%s\"\n", $label, $attribute['value'] ); + } + + return $formatted_attributes; + } + + /** + * Validates the data to make sure it can be formatted. + * + * @param mixed $data The data to format. + * + * @return bool True if the data is valid, false otherwise. + */ + public function validate_data( $data ): bool { + if ( empty( $data ) || ! is_array( $data ) ) { + return false; + } + + foreach ( $data as $attribute ) { + if ( empty( $attribute['name'] ) ) { + return false; + } + } + + return true; + } + +} diff --git a/plugins/woo-ai/includes/prompt-formatter/class-product-category-formatter.php b/plugins/woo-ai/includes/prompt-formatter/class-product-category-formatter.php new file mode 100644 index 00000000000..e156c94f504 --- /dev/null +++ b/plugins/woo-ai/includes/prompt-formatter/class-product-category-formatter.php @@ -0,0 +1,104 @@ + '; + private const UNCATEGORIZED_SLUG = 'uncategorized'; + + /** + * Get the category names from the category ids from WooCommerce and recursively get all the parent categories and prepend them to the category names separated by >. + * + * @param array $data The category ids. + * + * @return string A string containing the formatted categories. E.g., "Books > Fiction, Books > Novels > Fiction" + * + * @throws InvalidArgumentException If the input data is not an array. + */ + public function format( $data ): string { + if ( ! $this->validate_data( $data ) ) { + throw new InvalidArgumentException( 'Invalid input data. Provide an array of category ids.' ); + } + + $categories = array(); + foreach ( $data as $category_id ) { + $category = get_term( $category_id, self::CATEGORY_TAXONOMY ); + + // If the category is not found, or it is the uncategorized category, skip it. + if ( ! $category instanceof WP_Term || self::UNCATEGORIZED_SLUG === $category->slug ) { + continue; + } + + $categories[] = $this->format_category_name( $category ); + } + + return implode( ', ', $categories ); + } + + /** + * Validates the data to make sure it can be formatted. + * + * @param mixed $data The data to format. + * + * @return bool True if the data is valid, false otherwise. + */ + public function validate_data( $data ): bool { + return ! empty( $data ) && is_array( $data ); + } + + /** + * Get formatted category name with parent categories prepended separated by >. + * + * @param WP_Term $category The category as a WP_Term object. + * + * @return string The formatted category name. + */ + private function format_category_name( WP_Term $category ): string { + $parent_categories = $this->get_parent_categories( $category->term_id ); + $parent_categories[] = $category->name; + + return implode( self::PARENT_CATEGORY_SEPARATOR, $parent_categories ); + } + + /** + * Get parent categories for the given category id. + * + * @param int $category_id The category id. + * + * @return array An array of names of the parent categories in the order of the hierarchy. + */ + private function get_parent_categories( int $category_id ): array { + $parent_category_ids = get_ancestors( $category_id, self::CATEGORY_TAXONOMY ); + + if ( empty( $parent_category_ids ) ) { + return array(); + } + + $parent_category_ids = array_reverse( $parent_category_ids ); + + return array_map( + function ( $parent_category_id ) { + $parent_category = get_term( $parent_category_id, self::CATEGORY_TAXONOMY ); + + return $parent_category->name; + }, + $parent_category_ids + ); + } + +} diff --git a/plugins/woo-ai/includes/prompt-formatter/interface-prompt-formatter.php b/plugins/woo-ai/includes/prompt-formatter/interface-prompt-formatter.php new file mode 100644 index 00000000000..ffffbd7b9b2 --- /dev/null +++ b/plugins/woo-ai/includes/prompt-formatter/interface-prompt-formatter.php @@ -0,0 +1,33 @@ + + +
+

+ ' . esc_html__( 'Woo AI', 'woocommerce' ) . '' ); + ?> +

+ + +

+ + + + + + +

+ + +

+ + + + +

+ +
diff --git a/plugins/woo-ai/includes/views/html-admin-missing-woocommerce.php b/plugins/woo-ai/includes/views/html-admin-missing-woocommerce.php new file mode 100644 index 00000000000..43bc664b066 --- /dev/null +++ b/plugins/woo-ai/includes/views/html-admin-missing-woocommerce.php @@ -0,0 +1,47 @@ + + +
+

+ ' . esc_html__( 'Woo AI', 'woocommerce' ) . '' ); + ?> +

+ + +

+ + + + + + +

+ + +

+ + + + +

+ +
diff --git a/plugins/woo-ai/package.json b/plugins/woo-ai/package.json new file mode 100644 index 00000000000..ac532566a18 --- /dev/null +++ b/plugins/woo-ai/package.json @@ -0,0 +1,92 @@ +{ + "name": "woo-ai", + "description": "Implementing WooCommerce AI Experiments.", + "license": "GPL-2.0", + "repository": { + "type": "git", + "url": "git://github.com/woocommerce/woo-ai.git" + }, + "title": "Woo AI", + "version": "0.1.0", + "homepage": "http://github.com/woocommerce/woo-ai", + "devDependencies": { + "@types/debug": "^4.1.7", + "@types/jquery": "^3.5.16", + "@types/react": "^17.0.2", + "@types/react-dom": "^17.0.2", + "@types/wordpress__components": "^19.10.3", + "@woocommerce/dependency-extraction-webpack-plugin": "workspace:*", + "@woocommerce/eslint-plugin": "workspace:*", + "@wordpress/env": "^8.0.0", + "@wordpress/prettier-config": "2.17.0", + "@wordpress/scripts": "^19.2.4", + "eslint": "^8.32.0", + "prettier": "npm:wp-prettier@^2.6.2", + "ts-loader": "^9.4.1", + "typescript": "^4.9.5", + "uglify-js": "^3.5.3" + }, + "dependencies": { + "@emotion/react": "^11.10.4", + "@types/prop-types": "^15.7.4", + "@types/react-outside-click-handler": "^1.3.1", + "@woocommerce/components": "workspace:*", + "@woocommerce/tracks": "workspace:*", + "@wordpress/api-fetch": "wp-6.0", + "@wordpress/components": "wp-6.0", + "@wordpress/compose": "wp-6.0", + "@wordpress/element": "wp-6.0", + "@wordpress/hooks": "wp-6.0", + "@wordpress/i18n": "wp-6.0", + "@wordpress/plugins": "wp-6.0", + "debug": "^4.3.3", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@types/react": "^17.0.2", + "@types/react-dom": "^17.0.2", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "@wordpress/data": "wp-6.0" + }, + "scripts": { + "postinstall": "composer install", + "changelog": "composer exec -- changelogger", + "build": "pnpm -w exec turbo run turbo:build --filter=$npm_package_name", + "turbo:build": "pnpm run build:admin && pnpm run uglify", + "build:admin": "wp-scripts build", + "build:zip": "./bin/build-zip.sh", + "build:dev": "pnpm run lint:js && pnpm run build", + "uglify": "rm -f $npm_package_assets_js_min && for f in $npm_package_assets_js_js; do file=${f%.js}; node_modules/.bin/uglifyjs $f -c -m > $file.min.js; done", + "check-engines": "wp-scripts check-engines", + "check-licenses": "wp-scripts check-licenses", + "format:js": "wp-scripts format-js", + "lint:css": "wp-scripts lint-style", + "lint:css:fix": "wp-scripts lint-style --fix", + "lint:js": "wp-scripts lint-js", + "lint:js:fix": "wp-scripts lint-js --fix", + "lint:md:docs": "wp-scripts lint-md-docs", + "lint:md:js": "wp-scripts lint-md-js", + "lint:pkg-json": "wp-scripts lint-pkg-json", + "packages-update": "wp-scripts packages-update", + "start": "wp-scripts start", + "test:e2e": "wp-scripts test-e2e", + "test:unit": "wp-scripts test-unit-js" + }, + "engines": { + "node": "^16.14.1", + "pnpm": "^8.3.1" + }, + "lint-staged": { + "*.php": [ + "php -d display_errors=1 -l", + "composer run-script phpcs-pre-commit" + ], + "*.(t|j)s?(x)": [ + "npm run lint:js:fix" + ], + "*.scss": [ + "npm run lint:css:fix" + ] + } +} diff --git a/plugins/woo-ai/src/components/description-completion-buttons.tsx b/plugins/woo-ai/src/components/description-completion-buttons.tsx new file mode 100644 index 00000000000..1c5d17867be --- /dev/null +++ b/plugins/woo-ai/src/components/description-completion-buttons.tsx @@ -0,0 +1,77 @@ +/** + * External dependencies + */ +import React from 'react'; +import { __, sprintf } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import MagicIcon from '../../assets/images/icons/magic.svg'; +import { MIN_TITLE_LENGTH_FOR_DESCRIPTION } from '../constants'; + +type MagicButtonProps = { + title?: string; + disabled?: boolean; + onClick: () => void; + label: string; +}; + +const MagicButton = ( { + title, + label, + onClick, + disabled = false, +}: MagicButtonProps ) => { + return ( + + ); +}; + +export const WriteItForMeBtn = ( { + disabled, + onClick, +}: Omit< MagicButtonProps, 'title' | 'label' > ) => { + return ( + + ); +}; + +export const StopCompletionBtn = ( { + disabled, + onClick, +}: Omit< MagicButtonProps, 'title' | 'label' > ) => { + return ( + + ); +}; diff --git a/plugins/woo-ai/src/components/index.ts b/plugins/woo-ai/src/components/index.ts new file mode 100644 index 00000000000..8b3e358145f --- /dev/null +++ b/plugins/woo-ai/src/components/index.ts @@ -0,0 +1,2 @@ +export * from './random-loading-message'; +export * from './description-completion-buttons'; diff --git a/plugins/woo-ai/src/components/random-loading-message/index.ts b/plugins/woo-ai/src/components/random-loading-message/index.ts new file mode 100644 index 00000000000..4ebb02fb872 --- /dev/null +++ b/plugins/woo-ai/src/components/random-loading-message/index.ts @@ -0,0 +1 @@ +export * from './random-loading-message'; diff --git a/plugins/woo-ai/src/components/random-loading-message/random-loading-message.tsx b/plugins/woo-ai/src/components/random-loading-message/random-loading-message.tsx new file mode 100644 index 00000000000..b29ca9e304d --- /dev/null +++ b/plugins/woo-ai/src/components/random-loading-message/random-loading-message.tsx @@ -0,0 +1,137 @@ +/** + * External dependencies + */ +import { useState, useEffect, useRef } from '@wordpress/element'; +import React from 'react'; +import { __ } from '@wordpress/i18n'; +import { Spinner } from '@woocommerce/components'; + +/** + * Internal dependencies + */ +import { shuffleArray } from '../../utils'; + +// Define the Property types for the RandomLoadingMessage component +type RandomLoadingMessageProps = { + isLoading: boolean; +}; + +const tipsAndTricksPhrases = [ + __( + 'Make your product title descriptive for better results.', + 'woocommerce' + ), + __( 'Tailor your product names to your target audience.', 'woocommerce' ), + __( + "Focus on your product's unique features and benefits in descriptions.", + 'woocommerce' + ), + __( + 'Add relevant categories and tags to make products easy to find.', + 'woocommerce' + ), + __( + 'Including precise product attributes helps us provide better suggestions.', + 'woocommerce' + ), + __( + 'Know your audience and speak their language in descriptions.', + 'woocommerce' + ), + __( + 'Get creative with product titles, but stay on topic for the best suggestions.', + 'woocommerce' + ), + __( + 'Enhance your suggestions further by adding important features to your product titles.', + 'woocommerce' + ), + __( + 'Balance accurate information & creativity for optimal titles…', + 'woocommerce' + ), + __( + 'Keep refining your product information for better suggestions…', + 'woocommerce' + ), + __( + 'Remember to showcase the benefits of your products in descriptions…', + 'woocommerce' + ), + __( + 'Consider your target audience while crafting product names…', + 'woocommerce' + ), + __( + 'Use keywords in titles and descriptions that customers search for…', + 'woocommerce' + ), + __( + 'Highlight unique features of your product for better suggestions…', + 'woocommerce' + ), + __( + 'Optimize descriptions and titles for mobile devices too…', + 'woocommerce' + ), + __( + 'Create catchy titles, but keep the focus on your product…', + 'woocommerce' + ), +]; + +const getRandomLoadingPhrase = ( phrasesStack: string[] ): string => { + // Pop the first message from the stack and push it back in + const poppedMessage = phrasesStack.shift(); + + if ( ! poppedMessage ) { + return ''; + } + + phrasesStack.push( poppedMessage ); + + return poppedMessage; +}; + +export const RandomLoadingMessage: React.FC< RandomLoadingMessageProps > = ( { + isLoading, +} ) => { + const messageUpdateTimeout = useRef< number >(); + const [ currentMessage, setCurrentMessage ] = useState( + __( 'Brainstorming ideas… hold on tight.', 'woocommerce' ) + ); + + useEffect( () => { + const phrasesStack = shuffleArray( tipsAndTricksPhrases ); + + // Recursive function to update the message on an increasing time interval + const updateMessage = ( delay: number ) => { + clearTimeout( messageUpdateTimeout.current ); + messageUpdateTimeout.current = window.setTimeout( () => { + setCurrentMessage( getRandomLoadingPhrase( phrasesStack ) ); + + // Updates the message after an increasing delay. It will update every 3s, 4.5s, 6.75s, 10.125s, etc. + updateMessage( delay * 1.5 ); + }, delay ); + }; + + if ( isLoading ) { + updateMessage( 3000 ); + } else { + clearTimeout( messageUpdateTimeout.current ); + } + + return () => { + clearTimeout( messageUpdateTimeout.current ); + }; + }, [ isLoading ] ); + + return ( + <> + + + + { currentMessage } + + ); +}; diff --git a/plugins/woo-ai/src/constants.ts b/plugins/woo-ai/src/constants.ts new file mode 100644 index 00000000000..e20778c5838 --- /dev/null +++ b/plugins/woo-ai/src/constants.ts @@ -0,0 +1,3 @@ +export const WOO_AI_PLUGIN_FEATURE_NAME = 'woo_ai_plugin'; +export const MAX_TITLE_LENGTH = 200; +export const MIN_TITLE_LENGTH_FOR_DESCRIPTION = 15; diff --git a/plugins/woo-ai/src/customer.d.ts b/plugins/woo-ai/src/customer.d.ts new file mode 100644 index 00000000000..4333ece7830 --- /dev/null +++ b/plugins/woo-ai/src/customer.d.ts @@ -0,0 +1,4 @@ +declare module '*.svg' { + const content: string; + export default content; +} diff --git a/plugins/woo-ai/src/hooks/index.ts b/plugins/woo-ai/src/hooks/index.ts new file mode 100644 index 00000000000..c9f68c701cb --- /dev/null +++ b/plugins/woo-ai/src/hooks/index.ts @@ -0,0 +1,3 @@ +export * from './useTinyEditor'; +export * from './useCompletion'; +export * from './useFeedbackSnackbar'; diff --git a/plugins/woo-ai/src/hooks/useCompletion.ts b/plugins/woo-ai/src/hooks/useCompletion.ts new file mode 100644 index 00000000000..9227f97014e --- /dev/null +++ b/plugins/woo-ai/src/hooks/useCompletion.ts @@ -0,0 +1,87 @@ +/** + * External dependencies + */ +import { useRef, useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { askQuestion } from '../utils'; + +type StopReason = 'abort' | 'finished' | 'error' | 'interrupted'; + +type UseCompletionProps = { + onStreamMessage: ( message: string, chunk: string ) => void; + onCompletionFinished?: ( + reason: StopReason, + previousContent: string + ) => void; + onStreamError?: ( event: Event ) => void; +}; + +export const useCompletion = ( { + onStreamMessage, + onCompletionFinished = () => {}, + onStreamError = () => {}, +}: UseCompletionProps ) => { + const completionSource = useRef< EventSource | null >( null ); + const previousContent = useRef< string >( '' ); + const [ completionActive, setCompletionActive ] = useState( false ); + + const stopCompletion = ( reason: StopReason ) => { + if ( completionSource.current?.close ) { + completionSource.current.close(); + } + onCompletionFinished( reason, previousContent.current ); + completionSource.current = null; + setCompletionActive( false ); + }; + + const onMessage = ( event: MessageEvent ) => { + if ( event.data === '[DONE]' ) { + stopCompletion( 'finished' ); + return; + } + + const data = JSON.parse( event.data ); + const chunk = data.choices[ 0 ].delta.content; + if ( chunk ) { + previousContent.current += chunk; + onStreamMessage( previousContent.current, chunk ); + } + }; + + const onError = ( event: Event ) => { + // eslint-disable-next-line no-console + console.debug( 'Streaming error encountered', event ); + stopCompletion( 'error' ); + onStreamError( event ); + }; + + const requestCompletion = async ( question: string ) => { + if ( completionSource.current ) { + stopCompletion( 'interrupted' ); + } + previousContent.current = ''; + + const suggestionsSource = await askQuestion( question ); + setCompletionActive( true ); + + suggestionsSource.addEventListener( 'message', ( e ) => + onMessage( e ) + ); + suggestionsSource.addEventListener( 'error', ( event ) => + onError( event ) + ); + + completionSource.current = suggestionsSource; + + return suggestionsSource; + }; + + return { + requestCompletion, + completionActive, + stopCompletion: stopCompletion.bind( null, 'abort' ), + }; +}; diff --git a/plugins/woo-ai/src/hooks/useFeedbackSnackbar.tsx b/plugins/woo-ai/src/hooks/useFeedbackSnackbar.tsx new file mode 100644 index 00000000000..a1724423035 --- /dev/null +++ b/plugins/woo-ai/src/hooks/useFeedbackSnackbar.tsx @@ -0,0 +1,92 @@ +/** + * External dependencies + */ +import React from 'react'; +import { createInterpolateElement, useState } from '@wordpress/element'; +// TODO: Re-add "@types/wordpress__data" package to resolve this, causing other issues until pnpm 8.6.0 is usable +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +// eslint-disable-next-line @woocommerce/dependency-group +import { useDispatch } from '@wordpress/data'; + +type ShowSnackbarProps = { + label: string; + onPositiveResponse: () => void; + onNegativeResponse: () => void; +}; + +type NoticeItem = { + notice: { id: string }; +}; + +export const useFeedbackSnackbar = () => { + const { createNotice, removeNotice } = useDispatch( 'core/notices' ); + const [ noticeId, setNoticeId ] = useState< string | null >( null ); + + const showSnackbar = async ( { + label, + onPositiveResponse, + onNegativeResponse, + }: ShowSnackbarProps ) => { + const noticePromise: unknown = createNotice( 'info', label, { + type: 'snackbar', + explicitDismiss: true, + actions: [ + { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + label: createInterpolateElement( + ' ', + { + ThumbsUp: ( + + 👍 + + ), + ThumbsDown: ( + + 👎 + + ), + } + ), + onClick: ( e: React.MouseEvent< HTMLButtonElement > ) => { + const response = ( + e.target as HTMLSpanElement + ).getAttribute( 'data-response' ); + + if ( response === 'positive' ) { + onPositiveResponse(); + } + + if ( response === 'negative' ) { + onNegativeResponse(); + } + }, + }, + ], + } ); + + ( noticePromise as Promise< NoticeItem > ).then( + ( item: NoticeItem ) => { + setNoticeId( item.notice.id ); + } + ); + return noticePromise as Promise< NoticeItem >; + }; + + return { + showSnackbar, + removeSnackbar: () => { + if ( noticeId ) { + removeNotice( noticeId ); + } + }, + }; +}; diff --git a/plugins/woo-ai/src/hooks/useProductDataSuggestions.ts b/plugins/woo-ai/src/hooks/useProductDataSuggestions.ts new file mode 100644 index 00000000000..e8d3c09ae5c --- /dev/null +++ b/plugins/woo-ai/src/hooks/useProductDataSuggestions.ts @@ -0,0 +1,64 @@ +/** + * External dependencies + */ +import apiFetch from '@wordpress/api-fetch'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { + ProductDataSuggestion, + ProductDataSuggestionRequest, + ApiErrorResponse, +} from '../utils/types'; + +type ProductDataSuggestionSuccessResponse = { + suggestions: ProductDataSuggestion[]; +}; + +type ProductDataSuggestionErrorResponse = ApiErrorResponse; + +export const useProductDataSuggestions = () => { + const fetchSuggestions = async ( + request: ProductDataSuggestionRequest + ): Promise< ProductDataSuggestion[] > => { + try { + const response = + await apiFetch< ProductDataSuggestionSuccessResponse >( { + path: '/wooai/product-data-suggestions', + method: 'POST', + data: request, + } ); + + return response.suggestions; + } catch ( error ) { + /* eslint-disable-next-line no-console */ + console.error( error ); + + const errorResponse = error as ProductDataSuggestionErrorResponse; + const hasStatus = errorResponse?.data?.status; + const hasMessage = errorResponse?.message; + + // Check if the status is 500 or greater. + const isStatusGte500 = + errorResponse?.data?.status && errorResponse.data.status >= 500; + + // If the error response doesn't have a status or message, or if the status is 500 or greater, throw a generic error. + if ( ! hasStatus || ! hasMessage || isStatusGte500 ) { + throw new Error( + __( + `Apologies, this is an experimental feature and there was an error with this service. Please try again.`, + 'woocommerce' + ) + ); + } + + throw new Error( errorResponse.message ); + } + }; + + return { + fetchSuggestions, + } as const; +}; diff --git a/plugins/woo-ai/src/hooks/useTinyEditor.ts b/plugins/woo-ai/src/hooks/useTinyEditor.ts new file mode 100644 index 00000000000..1fe98619c8d --- /dev/null +++ b/plugins/woo-ai/src/hooks/useTinyEditor.ts @@ -0,0 +1,8 @@ +/** + * Internal dependencies + */ +import { setTinyContent, getTinyContent } from '../utils/tiny-tools'; + +export const useTinyEditor = () => { + return { setContent: setTinyContent, getContent: getTinyContent }; +}; diff --git a/plugins/woo-ai/src/index.js b/plugins/woo-ai/src/index.js new file mode 100644 index 00000000000..a792a0bad2f --- /dev/null +++ b/plugins/woo-ai/src/index.js @@ -0,0 +1,36 @@ +/** + * External dependencies + */ +import { render, createRoot } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { WriteItForMeButtonContainer } from './product-description'; +import { ProductNameSuggestions } from './product-name'; + +import './index.scss'; + +const renderComponent = ( Component, rootElement ) => { + if ( ! rootElement ) { + return; + } + + if ( createRoot ) { + createRoot( rootElement ).render( ); + } else { + render( , rootElement ); + } +}; + +const descriptionButtonRoot = document.getElementById( + 'woocommerce-ai-app-product-gpt-button' +); +const nameSuggestionsRoot = document.getElementById( + 'woocommerce-ai-app-product-name-suggestions' +); + +if ( window.JP_CONNECTION_INITIAL_STATE?.connectionStatus?.isActive ) { + renderComponent( WriteItForMeButtonContainer, descriptionButtonRoot ); + renderComponent( ProductNameSuggestions, nameSuggestionsRoot ); +} diff --git a/plugins/woo-ai/src/index.scss b/plugins/woo-ai/src/index.scss new file mode 100644 index 00000000000..73083ec115b --- /dev/null +++ b/plugins/woo-ai/src/index.scss @@ -0,0 +1,2 @@ +@import 'product-description/product-description.scss'; +@import 'product-name/product-name.scss'; diff --git a/plugins/woo-ai/src/product-description/index.ts b/plugins/woo-ai/src/product-description/index.ts new file mode 100644 index 00000000000..05bfdcddaac --- /dev/null +++ b/plugins/woo-ai/src/product-description/index.ts @@ -0,0 +1 @@ +export * from './product-description-button-container'; diff --git a/plugins/woo-ai/src/product-description/product-description-button-container.tsx b/plugins/woo-ai/src/product-description/product-description-button-container.tsx new file mode 100644 index 00000000000..985f0215204 --- /dev/null +++ b/plugins/woo-ai/src/product-description/product-description-button-container.tsx @@ -0,0 +1,148 @@ +/** + * External dependencies + */ +import React from 'react'; +import { __ } from '@wordpress/i18n'; +import { useState, useEffect, useRef } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { + MAX_TITLE_LENGTH, + MIN_TITLE_LENGTH_FOR_DESCRIPTION, +} from '../constants'; +import { WriteItForMeBtn, StopCompletionBtn } from '../components'; +import { useTinyEditor, useCompletion, useFeedbackSnackbar } from '../hooks'; +import { recordTracksFactory, getPostId } from '../utils'; + +const DESCRIPTION_MAX_LENGTH = 300; + +const getApiError = () => { + return __( + `❗ We're currently experiencing high demand for our experimental feature. Please check back in shortly.`, + 'woocommerce' + ); +}; + +const recordDescriptionTracks = recordTracksFactory( + 'description_completion', + () => ( { + post_id: getPostId(), + } ) +); + +export function WriteItForMeButtonContainer() { + const titleEl = useRef< HTMLInputElement >( + document.querySelector( '#title' ) + ); + const [ fetching, setFetching ] = useState< boolean >( false ); + const [ productTitle, setProductTitle ] = useState< string >( + titleEl.current?.value || '' + ); + const tinyEditor = useTinyEditor(); + const { showSnackbar, removeSnackbar } = useFeedbackSnackbar(); + const { requestCompletion, completionActive, stopCompletion } = + useCompletion( { + onStreamMessage: ( content ) => { + // This prevents printing out incomplete HTML tags. + const ignoreRegex = new RegExp( /<\/?\w*[^>]*$/g ); + if ( ! ignoreRegex.test( content ) ) { + tinyEditor.setContent( content ); + } + }, + onStreamError: ( error ) => { + // eslint-disable-next-line no-console + console.debug( 'Streaming error encountered', error ); + + tinyEditor.setContent( getApiError() ); + }, + onCompletionFinished: ( reason, content ) => { + recordDescriptionTracks( 'stop', { + reason, + character_count: content.length, + current_title: productTitle, + } ); + + setFetching( false ); + + if ( reason === 'finished' ) { + showSnackbar( { + label: __( + 'Was the AI-generated description helpful?', + 'woocommerce' + ), + onPositiveResponse: () => { + recordDescriptionTracks( 'feedback', { + response: 'positive', + } ); + }, + onNegativeResponse: () => { + recordDescriptionTracks( 'feedback', { + response: 'negative', + } ); + }, + } ); + } + }, + } ); + + useEffect( () => { + const title = titleEl.current; + + const updateTitleHandler = ( e: Event ) => { + setProductTitle( + ( e.target as HTMLInputElement ).value.trim() || '' + ); + }; + + title?.addEventListener( 'keyup', updateTitleHandler ); + title?.addEventListener( 'change', updateTitleHandler ); + + return () => { + title?.removeEventListener( 'keyup', updateTitleHandler ); + title?.removeEventListener( 'change', updateTitleHandler ); + }; + }, [ titleEl ] ); + + const writeItForMeEnabled = + ! fetching && productTitle.length >= MIN_TITLE_LENGTH_FOR_DESCRIPTION; + + const buildPrompt = () => { + const instructions = [ + `Write a product description with the following product title: "${ productTitle.slice( + 0, + MAX_TITLE_LENGTH + ) }."`, + 'Identify the language used in this product title and use the same language in your response.', + 'Use a 9th grade reading level.', + `Make the description ${ DESCRIPTION_MAX_LENGTH } words or less.`, + 'Structure the description into paragraphs using standard HTML

tags.', + 'Only if appropriate, use

    and
  • tags to list product features.', + 'When appropriate, use and tags to emphasize text.', + 'Do not include a top-level heading at the beginning description.', + ]; + + return instructions.join( '\n' ); + }; + + const onWriteItForMeClick = () => { + setFetching( true ); + removeSnackbar(); + + const prompt = buildPrompt(); + recordDescriptionTracks( 'start', { + prompt, + } ); + requestCompletion( prompt ); + }; + + return completionActive ? ( + + ) : ( + + ); +} diff --git a/plugins/woo-ai/src/product-description/product-description.scss b/plugins/woo-ai/src/product-description/product-description.scss new file mode 100644 index 00000000000..1a28100cb3d --- /dev/null +++ b/plugins/woo-ai/src/product-description/product-description.scss @@ -0,0 +1,45 @@ +#postdivrich.woocommerce-product-description { + // hacks to fix visuals with "write it for me" button present + .wp-editor-tools { + top: -1px !important; + border-bottom: 0 !important; + } + + .wp-switch-editor + { + position: relative; + z-index: 1; + } +} + +#wpcontent { + .woo-ai-feedback-snackbar-action { + font-size: 1.4em; + } + + .woo-ai-feedback-snackbar-action + .woo-ai-feedback-snackbar-action { + margin-left: 10px; + } + + .components-snackbar__action:has( .woo-ai-feedback-snackbar-action) { + text-decoration: none; + } +} + +.wp-media-buttons { + .woo-ai-write-it-for-me-btn { + min-width: 126px; + + &[disabled] { + img { + opacity: 0.2; + } + } + + img { + filter: invert(32%) sepia(36%) saturate(2913%) hue-rotate(161deg) brightness(87%) contrast(91%); + padding: 0; + } + } +} + diff --git a/plugins/woo-ai/src/product-name/index.ts b/plugins/woo-ai/src/product-name/index.ts new file mode 100644 index 00000000000..5a606670887 --- /dev/null +++ b/plugins/woo-ai/src/product-name/index.ts @@ -0,0 +1,4 @@ +export * from './product-name-suggestions'; +export * from './powered-by-link'; +export * from './suggestion-item'; +export * from './name-utils'; diff --git a/plugins/woo-ai/src/product-name/name-utils.ts b/plugins/woo-ai/src/product-name/name-utils.ts new file mode 100644 index 00000000000..e284d29747e --- /dev/null +++ b/plugins/woo-ai/src/product-name/name-utils.ts @@ -0,0 +1,16 @@ +/** + * Internal dependencies + */ +import { recordTracksFactory, getPostId } from '../utils'; + +type TracksData = Record< + string, + string | number | Array< Record< string, string | number > > +>; + +export const recordNameTracks = recordTracksFactory< TracksData >( + 'name_completion', + () => ( { + post_id: getPostId(), + } ) +); diff --git a/plugins/woo-ai/src/product-name/powered-by-link.tsx b/plugins/woo-ai/src/product-name/powered-by-link.tsx new file mode 100644 index 00000000000..577d321efb2 --- /dev/null +++ b/plugins/woo-ai/src/product-name/powered-by-link.tsx @@ -0,0 +1,33 @@ +/** + * External dependencies + */ +import { createInterpolateElement } from '@wordpress/element'; +import { Link } from '@woocommerce/components'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { recordNameTracks } from './index'; + +export const PoweredByLink = () => ( + + { createInterpolateElement( + __( 'Powered by experimental AI. ', 'woocommerce' ), + { + link: ( + { + recordNameTracks( 'learn_more_click' ); + } } + > + { __( 'Learn more', 'woocommerce' ) } + + ), + } + ) } + +); diff --git a/plugins/woo-ai/src/product-name/product-name-suggestions.tsx b/plugins/woo-ai/src/product-name/product-name-suggestions.tsx new file mode 100644 index 00000000000..c854b48c313 --- /dev/null +++ b/plugins/woo-ai/src/product-name/product-name-suggestions.tsx @@ -0,0 +1,274 @@ +/** + * External dependencies + */ +import React from 'react'; +import { __ } from '@wordpress/i18n'; +import { useCallback, useEffect, useRef, useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import MagicIcon from '../../assets/images/icons/magic.svg'; +import AlertIcon from '../../assets/images/icons/alert.svg'; +import { productData } from '../utils'; +import { useProductDataSuggestions } from '../hooks/useProductDataSuggestions'; +import { + ProductDataSuggestion, + ProductDataSuggestionRequest, +} from '../utils/types'; +import { SuggestionItem, PoweredByLink, recordNameTracks } from './index'; +import { RandomLoadingMessage } from '../components'; + +const MIN_TITLE_LENGTH = 10; + +enum SuggestionsState { + Fetching = 'fetching', + Failed = 'failed', + None = 'none', +} + +type TinyEditor = { + on: ( eventName: string, handler: () => void ) => void; +}; + +declare const tinymce: { + on: ( + eventName: 'addeditor', + handler: ( event: Event & { editor: TinyEditor } ) => void, + thing?: boolean + ) => void; +}; + +const MagicImage = () => ( + +); + +export const ProductNameSuggestions = () => { + const [ suggestionsState, setSuggestionsState ] = + useState< SuggestionsState >( SuggestionsState.None ); + const [ isFirstLoad, setIsFirstLoad ] = useState< boolean >( true ); + const [ visible, setVisible ] = useState< boolean >( false ); + const [ suggestions, setSuggestions ] = useState< ProductDataSuggestion[] >( + [] + ); + const { fetchSuggestions } = useProductDataSuggestions(); + const nameInputRef = useRef< HTMLInputElement >( + document.querySelector( '#title' ) + ); + const [ productName, setProductName ] = useState< string >( + nameInputRef.current?.value || '' + ); + + useEffect( () => { + const nameInput = nameInputRef.current; + + const onFocus = () => { + setVisible( true ); + }; + const onKeyUp = ( e: KeyboardEvent ) => { + if ( e.key === 'Escape' ) { + setVisible( false ); + } + + setSuggestions( [] ); + setProductName( ( e.target as HTMLInputElement ).value || '' ); + }; + + const onChange = ( e: Event ) => { + setProductName( ( e.target as HTMLInputElement ).value || '' ); + }; + + const onBodyClick = ( e: MouseEvent ) => { + const target = e.target as HTMLElement; + + if ( + ! ( + nameInput?.ownerDocument.activeElement === nameInput || + // Need to capture errant handlediv click that happens on load as well + Boolean( target.querySelector( ':scope > .handlediv' ) ) || + target?.matches( + '#woocommerce-ai-app-product-name-suggestions *, #title' + ) + ) + ) { + setVisible( false ); + } + }; + + // Necessary since tinymce does not bubble click events. + const onDOMLoad = () => { + tinymce.on( + 'addeditor', + ( event ) => + event.editor.on( 'click', () => setVisible( false ) ), + true + ); + }; + + if ( nameInput ) { + nameInput.addEventListener( 'focus', onFocus ); + nameInput.addEventListener( 'keyup', onKeyUp ); + nameInput.addEventListener( 'change', onChange ); + } + document.body.addEventListener( 'click', onBodyClick ); + document.addEventListener( 'DOMContentLoaded', onDOMLoad ); + + return () => { + if ( nameInput ) { + nameInput.removeEventListener( 'focus', onFocus ); + nameInput.removeEventListener( 'keyup', onKeyUp ); + nameInput.removeEventListener( 'change', onChange ); + } + document.body.removeEventListener( 'click', onBodyClick ); + document.removeEventListener( 'DOMContentLoaded', onDOMLoad ); + }; + }, [] ); + + const updateProductName = ( newName: string ) => { + if ( ! nameInputRef.current || ! newName.length ) { + return; + } + nameInputRef.current.value = newName; + nameInputRef.current.setAttribute( 'value', newName ); + + // Ensure change event is fired for other interactions. + nameInputRef.current.dispatchEvent( new Event( 'change' ) ); + + setProductName( newName ); + }; + + const handleSuggestionClick = ( suggestion: ProductDataSuggestion ) => { + recordNameTracks( 'select', { + selected_title: suggestion.content, + } ); + + updateProductName( suggestion.content ); + setSuggestions( [] ); + }; + + const fetchProductSuggestions = async ( + event: React.MouseEvent< HTMLElement > + ) => { + if ( ( event.target as Element )?.closest( 'a' ) ) { + return; + } + setSuggestions( [] ); + setSuggestionsState( SuggestionsState.Fetching ); + try { + const currentProductData = productData(); + + recordNameTracks( 'start', { + current_title: currentProductData.name, + } ); + + const request: ProductDataSuggestionRequest = { + requested_data: 'name', + ...currentProductData, + }; + + const suggestionResults = await fetchSuggestions( request ); + + recordNameTracks( 'stop', { + reason: 'finished', + suggestions: suggestionResults, + } ); + setSuggestions( suggestionResults ); + setSuggestionsState( SuggestionsState.None ); + setIsFirstLoad( false ); + } catch ( e ) { + recordNameTracks( 'stop', { + reason: 'error', + error: ( e as { message?: string } )?.message || '', + } ); + setSuggestionsState( SuggestionsState.Failed ); + } + }; + + const shouldRenderSuggestionsButton = useCallback( () => { + return ( + productName.length >= MIN_TITLE_LENGTH && + suggestionsState !== SuggestionsState.Fetching + ); + }, [ productName, suggestionsState ] ); + + const getSuggestionsButtonLabel = useCallback( () => { + return isFirstLoad + ? __( 'Generate name ideas with AI', 'woocommerce' ) + : __( 'Get more ideas', 'woocommerce' ); + }, [ isFirstLoad ] ); + + return ( + + ); +}; diff --git a/plugins/woo-ai/src/product-name/product-name.scss b/plugins/woo-ai/src/product-name/product-name.scss new file mode 100644 index 00000000000..a9736622c94 --- /dev/null +++ b/plugins/woo-ai/src/product-name/product-name.scss @@ -0,0 +1,183 @@ +$border-color: #8c8f94; +$base-bg-color: #fff; +$hover-bg-color: #f0f0f1; +$base-text-color: #757575; +$z-index-container: 1001; +$z-index-header: 1002; +$border-radius: 4px; + +#woocommerce-ai-app-product-name-suggestions { + position: relative; +} + +.wc-product-name-suggestions-container { + border: 1px solid $border-color; + border-radius: $border-radius; + overflow: visible; + position: absolute; + top: 0; + left: 0; + width: 100%; + background: $base-bg-color; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); + z-index: $z-index-container; + box-sizing: border-box; + + .wc-product-name-suggestions__magic-image { + height: 24px; + width: 24px; + } + + .woo-ai-get-suggestions-btn { + border: none; + width: 100%; + text-align: left; + background-color: $base-bg-color; + padding: 10px; + border-radius: $border-radius; + display: flex; + align-items: center; + justify-content: space-between; + margin: 0; + line-height: 18px; + + img { + vertical-align: middle; + } + + &__content { + display: flex; + align-items: center; + } + + .woocommerce-pill { + display: inline-block; + font-size: .8em; + color: $base-text-color; + padding: 2px 8px; + } + } + + .woo-ai-get-suggestions-btn:hover { + background-color: $hover-bg-color; + } + + .wc-product-name-suggestions__suggested-names { + list-style: none; + padding: 0; + margin: 0; + border-bottom: 1px solid #dcdcde; + + .suggestion-item { + background-color: $base-bg-color; + margin-bottom: 0; + cursor: pointer; + + .suggestion-content-container { + display: flex; + flex-direction: column; + + .suggestion-content { + margin: .8em 0 .25em; + } + + .suggestion-reason { + color: grey; + margin: .25em 0 .8em; + } + } + + button.select-suggestion { + border: none; + width: 100%; + text-align: left; + background-color: $base-bg-color; + color: inherit; + display: flex; + justify-content: space-between; + align-items: center; + + .button.use-suggestion { + border: none; + background: initial; + visibility: hidden; + + &:hover { + visibility: visible; + } + } + + &:hover { + background-color: $hover-bg-color; + + .button.use-suggestion { + visibility: visible; + } + } + } + } + } + + .wc-product-name-suggestions__loading-message { + border-radius: $border-radius; + margin: 0; + background-color: $hover-bg-color; + padding: 10px; + display: flex; + align-items: center; + + .woo-ai-loading-message_spinner { + svg.woocommerce-spinner { + width: 28px; + height: 28px; + vertical-align: middle; + margin-right: 0.5em; + } + } + } + + .wc-product-name-suggestions__error-message { + display: flex; + align-items: center; + margin: 0; + padding: 10px; + + img { + margin-right: 10px; + } + } + + .wc-product-name-suggestions__tip-message { + margin: 0; + padding: 10px; + display: flex; + align-items: center; + justify-content: space-between; + + img { + vertical-align: middle; + } + } +} + +.woocommerce-layout > .woocommerce-layout__header { + z-index: $z-index-header; +} + +.woo-ai-get-suggestions-powered_by { + color: #8d8b8b; + + a { + text-decoration: none; + padding: 0 3px 3px 3px; + + &:after { + font: 16px/11px dashicons; + content: "\f504"; + font-weight: normal; + top: 2px; + position: relative; + margin-left: 3px; + } + } +} diff --git a/plugins/woo-ai/src/product-name/suggestion-item.tsx b/plugins/woo-ai/src/product-name/suggestion-item.tsx new file mode 100644 index 00000000000..0809374e1dd --- /dev/null +++ b/plugins/woo-ai/src/product-name/suggestion-item.tsx @@ -0,0 +1,26 @@ +/** + * Internal dependencies + */ +import { ProductDataSuggestion } from '../utils/types'; + +export const SuggestionItem = ( { + suggestion, + onSuggestionClick, +}: { + suggestion: ProductDataSuggestion; + onSuggestionClick: ( suggestion: ProductDataSuggestion ) => void; +} ) => ( +
  • + +
  • +); diff --git a/plugins/woo-ai/src/utils/get-post-id.ts b/plugins/woo-ai/src/utils/get-post-id.ts new file mode 100644 index 00000000000..66391a42fec --- /dev/null +++ b/plugins/woo-ai/src/utils/get-post-id.ts @@ -0,0 +1,4 @@ +export const getPostId = () => + Number( + ( document.querySelector( '#post_ID' ) as HTMLInputElement )?.value + ); diff --git a/plugins/woo-ai/src/utils/index.ts b/plugins/woo-ai/src/utils/index.ts new file mode 100644 index 00000000000..2f776171285 --- /dev/null +++ b/plugins/woo-ai/src/utils/index.ts @@ -0,0 +1,6 @@ +export * from './productData'; +export * from './shuffleArray'; +export * from './jetpack-completion'; +export * from './recordTracksFactory'; +export * from './get-post-id'; +export * from './tiny-tools'; diff --git a/plugins/woo-ai/src/utils/jetpack-completion.ts b/plugins/woo-ai/src/utils/jetpack-completion.ts new file mode 100644 index 00000000000..e50d19ceaaf --- /dev/null +++ b/plugins/woo-ai/src/utils/jetpack-completion.ts @@ -0,0 +1,100 @@ +/** + * External dependencies + */ +import apiFetch from '@wordpress/api-fetch'; +import debugFactory from 'debug'; +import { WOO_AI_PLUGIN_FEATURE_NAME } from '../constants'; + +const debugToken = debugFactory( 'jetpack-ai-assistant:token' ); + +const JWT_TOKEN_ID = 'jetpack-ai-jwt-token'; +const JWT_TOKEN_EXPIRATION_TIME = 2 * 60 * 1000; + +declare global { + interface Window { + JP_CONNECTION_INITIAL_STATE: { + apiNonce: string; + siteSuffix: string; + }; + } +} + +/** + * Request a token from the Jetpack site to use with the API + * + * @return {Promise<{token: string, blogId: string}>} The token and the blogId + */ +async function requestToken() { + // Trying to pick the token from localStorage + const token = localStorage.getItem( JWT_TOKEN_ID ); + let tokenData; + + if ( token ) { + try { + tokenData = JSON.parse( token ); + } catch ( err ) { + debugToken( 'Error parsing token', err ); + } + } + + if ( tokenData && tokenData?.expire > Date.now() ) { + debugToken( 'Using cached token' ); + return tokenData; + } + + const apiNonce = window.JP_CONNECTION_INITIAL_STATE?.apiNonce; + const siteSuffix = window.JP_CONNECTION_INITIAL_STATE?.siteSuffix; + const isJetpackSite = false; //! window.wpcomFetch; + + const data: { token: string; blog_id: string } = await apiFetch( { + path: '/jetpack/v4/jetpack-ai-jwt?_cacheBuster=' + Date.now(), + credentials: 'same-origin', + headers: { + 'X-WP-Nonce': apiNonce, + }, + method: 'POST', + } ); + + const newTokenData = { + token: data.token, + /** + * TODO: make sure we return id from the .com token acquisition endpoint too + */ + blogId: isJetpackSite ? data.blog_id : siteSuffix, + + /** + * Let's expire the token in 2 minutes + */ + expire: Date.now() + JWT_TOKEN_EXPIRATION_TIME, + }; + + // Store the token in localStorage + debugToken( 'Storing new token' ); + localStorage.setItem( JWT_TOKEN_ID, JSON.stringify( newTokenData ) ); + + return newTokenData; +} + +/** + * Leaving this here to make it easier to debug the streaming API calls for now + * + * @param {string} question - The query to send to the API + * @param {number} postId - The post where this completion is being requested, if available + */ +export async function askQuestion( question: string, postId = null ) { + const { token } = await requestToken(); + + const url = new URL( + 'https://public-api.wordpress.com/wpcom/v2/jetpack-ai-query' + ); + url.searchParams.append( 'question', question ); + url.searchParams.append( 'token', token ); + url.searchParams.append( 'feature', WOO_AI_PLUGIN_FEATURE_NAME ); + + if ( postId ) { + url.searchParams.append( 'post_id', postId ); + } + + const source = new EventSource( url.toString() ); + return source; +} diff --git a/plugins/woo-ai/src/utils/productData.ts b/plugins/woo-ai/src/utils/productData.ts new file mode 100644 index 00000000000..8b54ae3ebcb --- /dev/null +++ b/plugins/woo-ai/src/utils/productData.ts @@ -0,0 +1,124 @@ +/** + * Internal dependencies + */ +import { Attribute, ProductData } from './types'; +import { getTinyContent } from '../utils/tiny-tools'; + +const isElementVisible = ( element: HTMLElement ) => + ! ( window.getComputedStyle( element ).display === 'none' ); + +const getCategories = (): string[] => { + const categoryCheckboxEls: NodeListOf< HTMLInputElement > = + document.querySelectorAll( + '#taxonomy-product_cat input[name="tax_input[product_cat][]"]:checked' + ); + + const tempCategories: string[] = []; + + categoryCheckboxEls.forEach( ( el ) => { + if ( ! el.value.length ) { + return; + } + + tempCategories.push( el.value ); + } ); + + return tempCategories; +}; + +const getTags = (): string[] => { + const tagsEl: HTMLTextAreaElement | null = document.querySelector( + 'textarea[name="tax_input[product_tag]"]' + ); + + const tags = tagsEl ? tagsEl.value.split( ',' ) : []; + + return tags.filter( ( tag ) => tag !== '' ); +}; + +const getAttributes = (): Attribute[] => { + const attributeSelectEls: NodeListOf< HTMLSelectElement > = + document.querySelectorAll( + "#product_attributes select[name^='attribute_values']" + ); + + const tempAttributes: Attribute[] = []; + + attributeSelectEls.forEach( ( el: HTMLSelectElement ) => { + const attributeName = + el.getAttribute( 'data-taxonomy' )?.replace( 'pa_', '' ) || ''; + + const attributeValues = Array.from( el.selectedOptions ) + .map( ( option ) => option.text ) + .join( ',' ); + + if ( ! attributeValues || ! attributeName ) { + return; + } + + tempAttributes.push( { + name: attributeName, + value: attributeValues, + } ); + } ); + + return tempAttributes; +}; + +const getDescription = (): string => { + const isBlockEditor = + document.querySelectorAll( '.block-editor' ).length > 0; + + if ( ! isBlockEditor ) { + const content = document.querySelector( + '#content' + ) as HTMLInputElement; + const tinyContent = getTinyContent(); + if ( content && isElementVisible( content ) ) { + return content.value; + } else if ( tinyContent ) { + return tinyContent; + } + } + + return ( + document.querySelector( + '.block-editor-rich-text__editable' + ) as HTMLInputElement + )?.value; +}; + +const getProductName = (): string => { + const productNameEl: HTMLInputElement | null = + document.querySelector( '#title' ); + + return productNameEl ? productNameEl.value : ''; +}; + +const getProductType = () => { + const productTypeEl: HTMLInputElement | null = + document.querySelector( '#product-type' ); + + return productTypeEl ? productTypeEl.value : ''; +}; + +export const productData = (): ProductData => { + return { + name: getProductName(), + categories: getCategories(), + tags: getTags(), + attributes: getAttributes(), + description: getDescription(), + product_type: getProductType(), + is_downloadable: ( + document.querySelector( '#_downloadable' ) as HTMLInputElement + )?.checked + ? 'Yes' + : 'No', + is_virtual: ( + document.querySelector( '#_virtual' ) as HTMLInputElement + )?.checked + ? 'Yes' + : 'No', + }; +}; diff --git a/plugins/woo-ai/src/utils/recordTracksFactory.ts b/plugins/woo-ai/src/utils/recordTracksFactory.ts new file mode 100644 index 00000000000..71bffdde7ba --- /dev/null +++ b/plugins/woo-ai/src/utils/recordTracksFactory.ts @@ -0,0 +1,15 @@ +/** + * External dependencies + */ +import { recordEvent } from '@woocommerce/tracks'; + +export const recordTracksFactory = < T = Record< string, string | number > >( + feature: string, + propertiesCallback: () => Record< string, string | number > +) => { + return ( name: string, properties?: T ) => + recordEvent( `woo_ai_product_${ feature }_${ name }`, { + ...propertiesCallback(), + ...properties, + } ); +}; diff --git a/plugins/woo-ai/src/utils/shuffleArray.ts b/plugins/woo-ai/src/utils/shuffleArray.ts new file mode 100644 index 00000000000..274688623e4 --- /dev/null +++ b/plugins/woo-ai/src/utils/shuffleArray.ts @@ -0,0 +1,16 @@ +export const shuffleArray = ( array: string[] ) => { + let currentIndex = array.length; + let temporaryValue: string; + let randomIndex: number; + + while ( currentIndex !== 0 ) { + randomIndex = Math.floor( Math.random() * currentIndex ); + currentIndex -= 1; + + temporaryValue = array[ currentIndex ]; + array[ currentIndex ] = array[ randomIndex ]; + array[ randomIndex ] = temporaryValue; + } + + return array; +}; diff --git a/plugins/woo-ai/src/utils/tiny-tools.ts b/plugins/woo-ai/src/utils/tiny-tools.ts new file mode 100644 index 00000000000..89c3f291a81 --- /dev/null +++ b/plugins/woo-ai/src/utils/tiny-tools.ts @@ -0,0 +1,33 @@ +type TinyContent = { + getContent: () => string; + setContent: ( str: string ) => void; +}; + +declare const tinymce: { get: ( str: string ) => TinyContent }; + +const getTinyContentObject = () => + typeof tinymce === 'object' ? tinymce.get( 'content' ) : null; + +export const setTinyContent = ( str: string ) => { + if ( ! str.length ) { + return; + } + + const contentTinyMCE = getTinyContentObject(); + if ( contentTinyMCE ) { + contentTinyMCE.setContent( str ); + } else { + { + const el: HTMLInputElement | null = document.querySelector( + '#wp-content-editor-container .wp-editor-area' + ); + if ( el ) { + el.value = str; + } + } + } +}; + +export const getTinyContent = () => { + return getTinyContentObject()?.getContent(); +}; diff --git a/plugins/woo-ai/src/utils/types.ts b/plugins/woo-ai/src/utils/types.ts new file mode 100644 index 00000000000..14c6c18f709 --- /dev/null +++ b/plugins/woo-ai/src/utils/types.ts @@ -0,0 +1,41 @@ +export type Attribute = { + name: string; + value: string; +}; + +export type ProductData = { + name: string; + description: string; + categories: string[]; + tags: string[]; + attributes: Attribute[]; + product_type: string; + is_downloadable: string; + is_virtual: string; +}; + +export type ProductDataSuggestion = { + reason: string; + content: string; +}; + +export type ProductDataSuggestionRequest = { + requested_data: string; + name: string; + description: string; + categories: string[]; + tags: string[]; + attributes: Attribute[]; +}; + +// This is the standard API response data when an error is returned. +export type ApiErrorResponse = { + code: string; + message: string; + data?: ApiErrorResponseData | undefined; +}; + +// API errors contain data with the status, and more in-depth error details. This may be null. +export type ApiErrorResponseData = { + status: number; +} | null; diff --git a/plugins/woo-ai/tsconfig.json b/plugins/woo-ai/tsconfig.json new file mode 100644 index 00000000000..2f5ea6d6bf8 --- /dev/null +++ b/plugins/woo-ai/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + // Target latest version of ECMAScript. + "target": "esnext", + + // Make sure we're not pulling types from external projects. + "typeRoots": [ + "./typings", + "./node_modules/@types", + "src/custom.d.ts", + ], + + // Search under node_modules for non-relative imports. + "moduleResolution": "node", + + "jsx": "react-jsx", + + // Temporary for resolving the test data json, remove when moving to using the API + "resolveJsonModule": true, + + "jsxImportSource": "@emotion/react", + + // Enable strictest settings like strictNullChecks & noImplicitAny. + "strict": true, + + // Import non-ES modules as default imports. + "esModuleInterop": true, + + // Skip type checking of declaration files because some libraries define two copies of the same type in an inconsistent way + "skipLibCheck": true, + "module": "esnext", + }, +} diff --git a/plugins/woo-ai/webpack.config.js b/plugins/woo-ai/webpack.config.js new file mode 100644 index 00000000000..9ce86d2e18e --- /dev/null +++ b/plugins/woo-ai/webpack.config.js @@ -0,0 +1,34 @@ +const defaultConfig = require( '@wordpress/scripts/config/webpack.config' ); +const WooCommerceDependencyExtractionWebpackPlugin = require( '@woocommerce/dependency-extraction-webpack-plugin' ); + +module.exports = { + ...defaultConfig, + entry: { + ...defaultConfig.entry, + }, + module: { + ...defaultConfig.module, + rules: [ + ...defaultConfig.module.rules, + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + { + test: /\.(png|jp(e*)g|svg|gif)$/, + type: 'asset/resource', + }, + ], + }, + resolve: { + extensions: [ '.js', '.jsx', '.tsx', '.ts' ], + }, + plugins: [ + ...defaultConfig.plugins.filter( + ( plugin ) => + plugin.constructor.name !== 'DependencyExtractionWebpackPlugin' + ), + new WooCommerceDependencyExtractionWebpackPlugin(), + ], +}; diff --git a/plugins/woo-ai/woo-ai.php b/plugins/woo-ai/woo-ai.php new file mode 100644 index 00000000000..2be3ac8b3cf --- /dev/null +++ b/plugins/woo-ai/woo-ai.php @@ -0,0 +1,103 @@ +Learn more. + * Version: 0.1.0 + * Author: WooCommerce + * Author URI: http://woocommerce.com/ + * Requires at least: 5.8 + * Tested up to: 6.0 + * WC requires at least: 6.7 + * WC tested up to: 7.0 + * Text Domain: woo-ai + * + * @package Woo_AI + */ + +defined( 'ABSPATH' ) || exit; + +// Define WOO_AI_FILE. +if ( ! defined( 'WOO_AI_FILE' ) ) { + define( 'WOO_AI_FILE', __FILE__ ); +} + +/** + * Load text domain before all other code. + */ +function _woo_ai_load_textdomain(): void { + load_plugin_textdomain( 'woo-ai', false, basename( dirname( __FILE__ ) ) . '/languages' ); +} + +add_action( 'plugins_loaded', '_woo_ai_load_textdomain' ); + +/** + * Bootstrap plugin. + */ +function _woo_ai_bootstrap(): void { + + // Check if WooCommerce is enabled. + if ( ! class_exists( 'WooCommerce' ) ) { + include dirname( __FILE__ ) . '/includes/class-woo-ai-admin-notices.php'; + $notices = new Woo_AI_Admin_Notices(); + + add_action( 'admin_notices', array( $notices, 'woocoommerce_not_installed' ) ); + + // Stop here. + return; + } + + add_action( + 'before_woocommerce_init', + function() { + if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); + } + } + ); + + if ( class_exists( 'Automattic\Jetpack\Forms\ContactForm\Admin' ) ) { + remove_action( 'media_buttons', array( Automattic\Jetpack\Forms\ContactForm\Admin::init(), 'grunion_media_button' ), 999 ); + } + + // Check if Jetpack is enabled. + if ( ! class_exists( 'Jetpack' ) ) { + include dirname( __FILE__ ) . '/includes/class-woo-ai-admin-notices.php'; + $notices = new Woo_AI_Admin_Notices(); + + add_action( 'admin_notices', array( $notices, 'jetpack_not_installed' ) ); + + // Stop here. + return; + } + + if ( ! class_exists( 'Woo_AI' ) ) { + include dirname( __FILE__ ) . '/includes/class-woo-ai.php'; + + register_activation_hook( __FILE__, array( 'Woo_AI', 'activate' ) ); + + add_action( 'admin_init', array( 'Woo_AI', 'instance' ) ); + } + +} + +add_action( + 'wp_loaded', + function () { + require 'api/api.php'; + require_once dirname( __FILE__ ) . '/includes/exception/class-woo-ai-exception.php'; + require_once dirname( __FILE__ ) . '/includes/completion/class-completion-exception.php'; + require_once dirname( __FILE__ ) . '/includes/completion/interface-completion-service.php'; + require_once dirname( __FILE__ ) . '/includes/completion/class-jetpack-completion-service.php'; + require_once dirname( __FILE__ ) . '/includes/prompt-formatter/interface-prompt-formatter.php'; + require_once dirname( __FILE__ ) . '/includes/prompt-formatter/class-product-category-formatter.php'; + require_once dirname( __FILE__ ) . '/includes/prompt-formatter/class-product-attribute-formatter.php'; + require_once dirname( __FILE__ ) . '/includes/prompt-formatter/class-json-request-formatter.php'; + require_once dirname( __FILE__ ) . '/includes/product-data-suggestion/class-product-data-suggestion-exception.php'; + require_once dirname( __FILE__ ) . '/includes/product-data-suggestion/class-product-data-suggestion-request.php'; + require_once dirname( __FILE__ ) . '/includes/product-data-suggestion/class-product-data-suggestion-prompt-generator.php'; + require_once dirname( __FILE__ ) . '/includes/product-data-suggestion/class-product-data-suggestion-service.php'; + } +); + +add_action( 'plugins_loaded', '_woo_ai_bootstrap' ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a33443b71cb..a058bb6324b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2306,6 +2306,106 @@ importers: specifier: ^4.9.5 version: 4.9.5 + plugins/woo-ai: + dependencies: + '@emotion/react': + specifier: ^11.10.4 + version: 11.10.5(@babel/core@7.21.3)(@types/react@17.0.50)(react@17.0.2) + '@types/prop-types': + specifier: ^15.7.4 + version: 15.7.4 + '@types/react-outside-click-handler': + specifier: ^1.3.1 + version: 1.3.1 + '@woocommerce/components': + specifier: workspace:* + version: link:../../packages/js/components + '@woocommerce/tracks': + specifier: workspace:* + version: link:../../packages/js/tracks + '@wordpress/api-fetch': + specifier: wp-6.0 + version: 6.3.1 + '@wordpress/components': + specifier: wp-6.0 + version: 19.8.5(@babel/core@7.21.3)(@types/react@17.0.50)(react-dom@17.0.2)(react-with-direction@1.4.0)(react@17.0.2) + '@wordpress/compose': + specifier: wp-6.0 + version: 5.4.1(react@17.0.2) + '@wordpress/data': + specifier: wp-6.0 + version: 6.6.1(react@17.0.2) + '@wordpress/element': + specifier: wp-6.0 + version: 4.4.1 + '@wordpress/hooks': + specifier: wp-6.0 + version: 3.6.1 + '@wordpress/i18n': + specifier: wp-6.0 + version: 4.6.1 + '@wordpress/plugins': + specifier: wp-6.0 + version: 4.4.3(react@17.0.2) + debug: + specifier: ^4.3.3 + version: 4.3.4(supports-color@9.2.2) + prop-types: + specifier: ^15.8.1 + version: 15.8.1 + react: + specifier: ^17.0.2 + version: 17.0.2 + react-dom: + specifier: ^17.0.2 + version: 17.0.2(react@17.0.2) + devDependencies: + '@types/debug': + specifier: ^4.1.7 + version: 4.1.7 + '@types/jquery': + specifier: ^3.5.16 + version: 3.5.16 + '@types/react': + specifier: ^17.0.2 + version: 17.0.50 + '@types/react-dom': + specifier: ^17.0.2 + version: 17.0.17 + '@types/wordpress__components': + specifier: ^19.10.3 + version: 19.10.5(react-dom@17.0.2)(react@17.0.2) + '@woocommerce/dependency-extraction-webpack-plugin': + specifier: workspace:* + version: link:../../packages/js/dependency-extraction-webpack-plugin + '@woocommerce/eslint-plugin': + specifier: workspace:* + version: link:../../packages/js/eslint-plugin + '@wordpress/env': + specifier: ^8.0.0 + version: 8.0.0 + '@wordpress/prettier-config': + specifier: 2.17.0 + version: 2.17.0(wp-prettier@2.6.2) + '@wordpress/scripts': + specifier: ^19.2.4 + version: 19.2.4(@babel/core@7.21.3)(acorn@8.8.1)(debug@4.3.4)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(uglify-js@3.14.5) + eslint: + specifier: ^8.32.0 + version: 8.32.0 + prettier: + specifier: npm:wp-prettier@^2.6.2 + version: /wp-prettier@2.6.2 + ts-loader: + specifier: ^9.4.1 + version: 9.4.1(typescript@4.9.5)(webpack@5.76.3) + typescript: + specifier: ^4.9.5 + version: 4.9.5 + uglify-js: + specifier: ^3.5.3 + version: 3.14.5 + plugins/woocommerce: dependencies: '@wordpress/browserslist-config': @@ -3057,7 +3157,7 @@ importers: version: 2.17.0(wp-prettier@2.8.5) '@wordpress/scripts': specifier: ^19.2.4 - version: 19.2.4(@babel/core@7.21.3)(acorn@8.8.1)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(uglify-js@3.14.5) + version: 19.2.4(@babel/core@7.21.3)(acorn@8.8.1)(debug@4.3.4)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(uglify-js@3.14.5) eslint: specifier: ^8.32.0 version: 8.32.0 @@ -3318,7 +3418,7 @@ importers: version: 14.1.0 '@octokit/types': specifier: ^9.2.0 - version: 9.2.0 + version: 9.2.1 '@types/uuid': specifier: ^9.0.1 version: 9.0.1 @@ -3865,7 +3965,7 @@ packages: commander: 4.1.1 convert-source-map: 1.8.0 fs-readdir-recursive: 1.1.0 - glob: 7.2.3 + glob: 7.2.0 lodash: 4.17.21 make-dir: 2.1.0 slash: 2.0.0 @@ -3906,7 +4006,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.16 commander: 4.1.1 convert-source-map: 1.8.0 fs-readdir-recursive: 1.1.0 @@ -4085,7 +4185,7 @@ packages: resolution: {integrity: sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 @@ -4109,7 +4209,7 @@ packages: resolution: {integrity: sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 dev: true /@babel/helper-annotate-as-pure@7.18.6: @@ -4184,7 +4284,7 @@ packages: dependencies: '@babel/compat-data': 7.21.0 '@babel/core': 7.17.8 - '@babel/helper-validator-option': 7.18.6 + '@babel/helper-validator-option': 7.21.0 browserslist: 4.21.4 semver: 6.3.0 @@ -4196,7 +4296,7 @@ packages: dependencies: '@babel/compat-data': 7.21.0 '@babel/core': 7.12.9 - '@babel/helper-validator-option': 7.18.6 + '@babel/helper-validator-option': 7.21.0 browserslist: 4.21.4 lru-cache: 5.1.1 semver: 6.3.0 @@ -4455,13 +4555,6 @@ packages: dependencies: '@babel/types': 7.22.4 - /@babel/helper-function-name@7.19.0: - resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.20.7 - '@babel/types': 7.22.4 - /@babel/helper-function-name@7.21.0: resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} engines: {node: '>=6.9.0'} @@ -4491,7 +4584,7 @@ packages: resolution: {integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 dev: true /@babel/helper-module-imports@7.18.6: @@ -4512,7 +4605,7 @@ packages: dependencies: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.18.6 + '@babel/helper-simple-access': 7.20.2 '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.20.7 @@ -4532,7 +4625,7 @@ packages: '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.20.7 '@babel/traverse': 7.21.3 - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 transitivePeerDependencies: - supports-color @@ -4541,7 +4634,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 + '@babel/helper-module-imports': 7.21.4 '@babel/helper-simple-access': 7.20.2 '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 @@ -4569,10 +4662,6 @@ packages: resolution: {integrity: sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==} engines: {node: '>=6.9.0'} - /@babel/helper-plugin-utils@7.19.0: - resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} - engines: {node: '>=6.9.0'} - /@babel/helper-plugin-utils@7.20.2: resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} engines: {node: '>=6.9.0'} @@ -4597,7 +4686,7 @@ packages: dependencies: '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-wrap-function': 7.19.0 - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 transitivePeerDependencies: - supports-color dev: true @@ -4645,18 +4734,6 @@ packages: transitivePeerDependencies: - supports-color - /@babel/helper-replace-supers@7.19.1: - resolution: {integrity: sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-member-expression-to-functions': 7.21.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/traverse': 7.21.3 - '@babel/types': 7.22.4 - transitivePeerDependencies: - - supports-color - /@babel/helper-replace-supers@7.20.7: resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} engines: {node: '>=6.9.0'} @@ -4670,12 +4747,6 @@ packages: transitivePeerDependencies: - supports-color - /@babel/helper-simple-access@7.18.6: - resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - /@babel/helper-simple-access@7.20.2: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} @@ -4774,7 +4845,7 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 /@babel/parser@7.21.3: resolution: {integrity: sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==} @@ -4820,7 +4891,7 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.17.8): @@ -4830,7 +4901,7 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.21.3): @@ -4840,7 +4911,7 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.16.7(@babel/core@7.12.9): resolution: {integrity: sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==} @@ -4849,7 +4920,7 @@ packages: '@babel/core': ^7.13.0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 '@babel/plugin-proposal-optional-chaining': 7.18.9(@babel/core@7.12.9) dev: true @@ -4861,7 +4932,7 @@ packages: '@babel/core': ^7.13.0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 '@babel/plugin-proposal-optional-chaining': 7.18.9(@babel/core@7.17.8) dev: true @@ -4897,7 +4968,7 @@ packages: '@babel/core': ^7.13.0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 '@babel/plugin-proposal-optional-chaining': 7.18.9(@babel/core@7.17.8) dev: true @@ -4909,7 +4980,7 @@ packages: '@babel/core': ^7.13.0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 '@babel/plugin-proposal-optional-chaining': 7.18.9(@babel/core@7.21.3) @@ -4933,7 +5004,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.12.9) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.12.9) transitivePeerDependencies: @@ -4947,7 +5018,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.17.8) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.17.8) transitivePeerDependencies: @@ -4990,7 +5061,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.17.8) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.17.8) transitivePeerDependencies: @@ -5005,7 +5076,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.3) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.3) transitivePeerDependencies: @@ -5031,7 +5102,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-create-class-features-plugin': 7.17.6(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.18.9 + '@babel/helper-plugin-utils': 7.21.5 transitivePeerDependencies: - supports-color dev: true @@ -5056,7 +5127,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-create-class-features-plugin': 7.17.6(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.18.9 + '@babel/helper-plugin-utils': 7.21.5 transitivePeerDependencies: - supports-color dev: true @@ -5148,7 +5219,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.12.9) transitivePeerDependencies: - supports-color @@ -5162,7 +5233,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.17.8) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.17.8) transitivePeerDependencies: - supports-color @@ -5176,7 +5247,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.21.3) transitivePeerDependencies: - supports-color @@ -5259,7 +5330,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.12.9) dev: true @@ -5270,7 +5341,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.17.8) dev: true @@ -5281,7 +5352,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.3) /@babel/plugin-proposal-export-default-from@7.16.7(@babel/core@7.12.9): @@ -5365,7 +5436,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.12.9) dev: true @@ -5376,7 +5447,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.17.8) dev: true @@ -5387,7 +5458,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.21.3) /@babel/plugin-proposal-json-strings@7.16.0(@babel/core@7.12.9): @@ -5440,7 +5511,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.12.9) dev: true @@ -5451,7 +5522,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.17.8) dev: true @@ -5462,7 +5533,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.21.3) /@babel/plugin-proposal-logical-assignment-operators@7.16.0(@babel/core@7.12.9): @@ -5515,7 +5586,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.12.9) dev: true @@ -5526,7 +5597,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.17.8) dev: true @@ -5537,7 +5608,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.21.3) /@babel/plugin-proposal-nullish-coalescing-operator@7.16.0(@babel/core@7.12.9): @@ -5589,7 +5660,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.12.9) /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.17.8): @@ -5663,7 +5734,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.12.9) dev: true @@ -5674,7 +5745,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.17.8) dev: true @@ -5685,7 +5756,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.21.3) /@babel/plugin-proposal-object-rest-spread@7.12.1(@babel/core@7.12.9): @@ -5763,7 +5834,7 @@ packages: '@babel/compat-data': 7.21.0 '@babel/core': 7.12.9 '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.12.9) '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.12.9) @@ -5844,7 +5915,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.12.9) /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.17.8): @@ -5854,7 +5925,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.17.8) dev: true @@ -5865,7 +5936,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.21.3) /@babel/plugin-proposal-optional-chaining@7.16.0(@babel/core@7.12.9): @@ -6007,7 +6078,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 transitivePeerDependencies: - supports-color dev: true @@ -6044,9 +6115,9 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-annotate-as-pure': 7.16.7 - '@babel/helper-create-class-features-plugin': 7.17.6(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.12.9) + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.12.9) transitivePeerDependencies: - supports-color @@ -6074,9 +6145,9 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-annotate-as-pure': 7.16.7 - '@babel/helper-create-class-features-plugin': 7.17.6(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.21.3) + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.3) transitivePeerDependencies: - supports-color @@ -6106,7 +6177,7 @@ packages: '@babel/core': 7.17.8 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.17.8) - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.17.8) transitivePeerDependencies: - supports-color @@ -6121,7 +6192,7 @@ packages: '@babel/core': 7.21.3 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.3) transitivePeerDependencies: - supports-color @@ -6144,7 +6215,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 dev: true /@babel/plugin-proposal-unicode-property-regex@7.16.7(@babel/core@7.17.8): @@ -6155,7 +6226,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.17.8) - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 dev: true /@babel/plugin-proposal-unicode-property-regex@7.16.7(@babel/core@7.21.3): @@ -6177,7 +6248,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} @@ -6187,7 +6258,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.17.8) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.21.3): @@ -6198,7 +6269,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.12.9): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} @@ -6283,7 +6354,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.17.8): @@ -6293,7 +6364,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.21.3): @@ -6303,7 +6374,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-syntax-decorators@7.16.0(@babel/core@7.17.8): resolution: {integrity: sha512-nxnnngZClvlY13nHJAIDow0S7Qzhq64fQ/NlqS+VER3kjW/4F0jLhXjeL8jcwSwz6Ca3rotT5NJD2T9I7lcv7g==} @@ -6437,7 +6508,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.17.8): @@ -6447,7 +6518,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.21.3): @@ -6457,7 +6528,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.12.9): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} @@ -6536,17 +6607,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-jsx@7.16.7(@babel/core@7.21.3): - resolution: {integrity: sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.17.8): @@ -6675,7 +6736,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-plugin-utils': 7.20.2 /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.17.8): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} @@ -6683,7 +6744,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-plugin-utils': 7.20.2 dev: true /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.21.3): @@ -6692,7 +6753,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.19.0 + '@babel/helper-plugin-utils': 7.20.2 /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.12.9): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} @@ -6750,7 +6811,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.17.8): @@ -6760,7 +6821,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.21.3): @@ -6770,7 +6831,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.12.9): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} @@ -6882,7 +6943,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-arrow-functions@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} @@ -6924,7 +6985,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-module-imports': 7.16.7 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-remap-async-to-generator': 7.16.8 transitivePeerDependencies: - supports-color @@ -6952,7 +7013,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-module-imports': 7.16.7 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-remap-async-to-generator': 7.16.8 transitivePeerDependencies: - supports-color @@ -6978,8 +7039,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.17.8) transitivePeerDependencies: - supports-color @@ -6992,8 +7053,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.3) transitivePeerDependencies: - supports-color @@ -7044,7 +7105,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} @@ -7053,7 +7114,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.21.3): @@ -7063,7 +7124,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-block-scoping@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw==} @@ -7111,7 +7172,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-block-scoping@7.21.0(@babel/core@7.17.8): resolution: {integrity: sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==} @@ -7140,10 +7201,10 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-function-name': 7.19.0 + '@babel/helper-function-name': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-replace-supers': 7.20.7 '@babel/helper-split-export-declaration': 7.18.6 globals: 11.12.0 transitivePeerDependencies: @@ -7160,8 +7221,8 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-replace-supers': 7.20.7 '@babel/helper-split-export-declaration': 7.18.6 globals: 11.12.0 transitivePeerDependencies: @@ -7179,8 +7240,8 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-replace-supers': 7.20.7 '@babel/helper-split-export-declaration': 7.18.6 globals: 11.12.0 transitivePeerDependencies: @@ -7199,7 +7260,7 @@ packages: '@babel/helper-function-name': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-replace-supers': 7.20.7 '@babel/helper-split-export-declaration': 7.18.6 globals: 11.12.0 transitivePeerDependencies: @@ -7218,7 +7279,7 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-replace-supers': 7.20.7 '@babel/helper-split-export-declaration': 7.18.6 globals: 11.12.0 @@ -7310,7 +7371,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-computed-properties@7.18.9(@babel/core@7.17.8): resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} @@ -7319,7 +7380,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-computed-properties@7.18.9(@babel/core@7.21.3): @@ -7329,7 +7390,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-destructuring@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-Q7tBUwjxLTsHEoqktemHBMtb3NYwyJPTJdM+wDwb0g8PZ3kQUIzNvwD5lPaqW/p54TXBc/MXZu9Jr7tbUEUM8Q==} @@ -7449,7 +7510,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} @@ -7459,7 +7520,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.17.8) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.21.3): @@ -7470,7 +7531,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-duplicate-keys@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-LIe2kcHKAZOJDNxujvmp6z3mfN6V9lJxubU4fJIGoQCkKe3Ec2OcbdlYP+vW++4MpxwG0d1wSDOJtQW5kLnkZQ==} @@ -7518,7 +7579,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.17.8): @@ -7528,7 +7589,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.21.3): @@ -7538,7 +7599,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-exponentiation-operator@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-OwYEvzFI38hXklsrbNivzpO3fh87skzx8Pnqi4LoSYeav0xHlueSoCJrSgTPfnbyzopo5b3YVAJkFIcUpK2wsw==} @@ -7591,7 +7652,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} @@ -7690,7 +7751,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-for-of@7.18.8(@babel/core@7.17.8): resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} @@ -7718,7 +7779,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-function-name': 7.19.0 + '@babel/helper-function-name': 7.21.0 '@babel/helper-plugin-utils': 7.20.2 /@babel/plugin-transform-function-name@7.16.7(@babel/core@7.12.9): @@ -7730,7 +7791,7 @@ packages: '@babel/core': 7.12.9 '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.12.9) '@babel/helper-function-name': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-function-name@7.16.7(@babel/core@7.17.8): @@ -7742,7 +7803,7 @@ packages: '@babel/core': 7.17.8 '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.17.8) '@babel/helper-function-name': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-function-name@7.16.7(@babel/core@7.21.3): @@ -7777,7 +7838,7 @@ packages: '@babel/core': 7.17.8 '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.17.8) '@babel/helper-function-name': 7.21.0 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 dev: true /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.21.3): @@ -7789,7 +7850,7 @@ packages: '@babel/core': 7.21.3 '@babel/helper-compilation-targets': 7.20.7(@babel/core@7.21.3) '@babel/helper-function-name': 7.21.0 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 /@babel/plugin-transform-literals@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-gQDlsSF1iv9RU04clgXqRjrPyyoJMTclFt3K1cjLmTKikc0s/6vE3hlDeEVC71wLTRu72Fq7650kABrdTc2wMQ==} @@ -7837,7 +7898,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-literals@7.18.9(@babel/core@7.17.8): resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} @@ -7846,7 +7907,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-literals@7.18.9(@babel/core@7.21.3): @@ -7856,7 +7917,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-member-expression-literals@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-WRpw5HL4Jhnxw8QARzRvwojp9MIE7Tdk3ez6vRyUk1MwgjJN0aNpRoXainLR5SgxmoXx/vsXGZ6OthP6t/RbUg==} @@ -7904,7 +7965,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} @@ -7913,7 +7974,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.21.3): @@ -7923,7 +7984,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-modules-amd@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-rWFhWbCJ9Wdmzln1NmSCqn7P0RAD+ogXG/bd9Kg5c7PKWkJtkiXmYsMBeXjDlzHpVTJ4I/hnjs45zX4dEv81xw==} @@ -8001,7 +8062,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color dev: true @@ -8014,7 +8075,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 transitivePeerDependencies: - supports-color @@ -8027,7 +8088,7 @@ packages: '@babel/core': 7.12.9 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.18.6 + '@babel/helper-simple-access': 7.20.2 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: - supports-color @@ -8041,7 +8102,7 @@ packages: '@babel/core': 7.12.9 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.18.6 + '@babel/helper-simple-access': 7.20.2 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: - supports-color @@ -8056,7 +8117,7 @@ packages: '@babel/core': 7.17.8 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.18.6 + '@babel/helper-simple-access': 7.20.2 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: - supports-color @@ -8070,7 +8131,7 @@ packages: '@babel/core': 7.21.3 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.18.6 + '@babel/helper-simple-access': 7.20.2 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: - supports-color @@ -8097,7 +8158,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-simple-access': 7.20.2 transitivePeerDependencies: - supports-color @@ -8111,7 +8172,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-simple-access': 7.20.2 transitivePeerDependencies: - supports-color @@ -8140,7 +8201,7 @@ packages: '@babel/core': 7.12.9 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-validator-identifier': 7.19.1 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: @@ -8156,7 +8217,7 @@ packages: '@babel/core': 7.17.8 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-validator-identifier': 7.19.1 babel-plugin-dynamic-import-node: 2.3.3 transitivePeerDependencies: @@ -8203,7 +8264,7 @@ packages: '@babel/core': 7.17.8 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-validator-identifier': 7.19.1 transitivePeerDependencies: - supports-color @@ -8218,7 +8279,7 @@ packages: '@babel/core': 7.21.3 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-validator-identifier': 7.19.1 transitivePeerDependencies: - supports-color @@ -8243,7 +8304,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 transitivePeerDependencies: - supports-color dev: true @@ -8256,7 +8317,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 transitivePeerDependencies: - supports-color dev: true @@ -8282,7 +8343,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 transitivePeerDependencies: - supports-color dev: true @@ -8359,7 +8420,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.12.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-named-capturing-groups-regex@7.19.1(@babel/core@7.17.8): resolution: {integrity: sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==} @@ -8428,7 +8489,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.17.8): @@ -8438,7 +8499,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.21.3): @@ -8448,7 +8509,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-object-super@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-fds+puedQHn4cPLshoHcR1DTMN0q1V9ou0mUjm8whx9pGcNvDrVVrgw+KJzzCaiTdaYhldtrUps8DWVMgrSEyg==} @@ -8458,7 +8519,7 @@ packages: dependencies: '@babel/core': 7.12.9 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color @@ -8469,8 +8530,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color dev: true @@ -8482,8 +8543,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color dev: true @@ -8496,7 +8557,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color dev: true @@ -8508,7 +8569,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color @@ -8520,7 +8581,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color @@ -8533,7 +8594,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color @@ -8651,7 +8712,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} @@ -8660,7 +8721,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.21.3): @@ -8670,7 +8731,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-react-constant-elements@7.17.6(@babel/core@7.21.3): resolution: {integrity: sha512-OBv9VkyyKtsHZiHLoSfCn+h6yU7YKX8nrs32xUmOa1SRSk+t03FosB6fBZ0Yz4BpD1WV7l73Nsad+2Tz7APpqw==} @@ -8737,7 +8798,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/plugin-transform-react-jsx': 7.19.0(@babel/core@7.17.8) + '@babel/plugin-transform-react-jsx': 7.22.3(@babel/core@7.17.8) dev: true /@babel/plugin-transform-react-jsx-development@7.16.7(@babel/core@7.21.3): @@ -8747,7 +8808,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/plugin-transform-react-jsx': 7.19.0(@babel/core@7.21.3) + '@babel/plugin-transform-react-jsx': 7.22.3(@babel/core@7.21.3) dev: true /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.21.3): @@ -8831,11 +8892,11 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-annotate-as-pure': 7.16.7 - '@babel/helper-module-imports': 7.16.7 - '@babel/helper-plugin-utils': 7.18.9 - '@babel/plugin-syntax-jsx': 7.16.7(@babel/core@7.21.3) - '@babel/types': 7.17.0 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.21.3) + '@babel/types': 7.22.4 dev: true /@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.17.8): @@ -8878,6 +8939,20 @@ packages: '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.12.9) '@babel/types': 7.22.4 + /@babel/plugin-transform-react-jsx@7.22.3(@babel/core@7.17.8): + resolution: {integrity: sha512-JEulRWG2f04a7L8VWaOngWiK6p+JOSpB+DAtwfJgOaej1qdbNxqtK7MwTBHjUA10NeFcszlFNqCdbRcirzh2uQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.17.8 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.17.8) + '@babel/types': 7.22.4 + dev: true + /@babel/plugin-transform-react-jsx@7.22.3(@babel/core@7.21.3): resolution: {integrity: sha512-JEulRWG2f04a7L8VWaOngWiK6p+JOSpB+DAtwfJgOaej1qdbNxqtK7MwTBHjUA10NeFcszlFNqCdbRcirzh2uQ==} engines: {node: '>=6.9.0'} @@ -8981,7 +9056,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 regenerator-transform: 0.15.0 dev: true @@ -8992,7 +9067,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 regenerator-transform: 0.15.0 /@babel/plugin-transform-reserved-words@7.16.0(@babel/core@7.12.9): @@ -9041,7 +9116,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.17.8): @@ -9051,7 +9126,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.21.3): @@ -9061,7 +9136,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-runtime@7.16.4(@babel/core@7.12.9): resolution: {integrity: sha512-pru6+yHANMTukMtEZGC4fs7XPwg35v8sj5CIEmE+gEkFljFiVJxEWxx/7ZDkTK+iZRYo1bFXBtfIN95+K3cJ5A==} @@ -9087,9 +9162,9 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-module-imports': 7.16.0 - '@babel/helper-plugin-utils': 7.14.5 - babel-plugin-polyfill-corejs2: 0.3.0(@babel/core@7.21.3) + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-plugin-utils': 7.21.5 + babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.21.3) babel-plugin-polyfill-corejs3: 0.4.0(@babel/core@7.21.3) babel-plugin-polyfill-regenerator: 0.3.0(@babel/core@7.21.3) semver: 6.3.0 @@ -9175,7 +9250,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} @@ -9213,7 +9288,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 dev: true @@ -9224,7 +9299,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 dev: true @@ -9246,7 +9321,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-skip-transparent-expression-wrappers': 7.18.9 /@babel/plugin-transform-spread@7.19.0(@babel/core@7.17.8): @@ -9316,7 +9391,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.17.8): resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} @@ -9325,7 +9400,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.21.3): @@ -9335,7 +9410,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-template-literals@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-Rd4Ic89hA/f7xUSJQk5PnC+4so50vBoBfxjdQAdvngwidM8jYIBVxBZ/sARxD4e0yMXRbJVDrYf7dyRtIIKT6Q==} @@ -9383,7 +9458,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.17.8): resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} @@ -9392,7 +9467,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.21.3): @@ -9402,7 +9477,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-typeof-symbol@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-++V2L8Bdf4vcaHi2raILnptTBjGEFxn5315YU+e8+EqXIucA+q349qWngCLpUYqqv233suJ6NOienIVUpS9cqg==} @@ -9450,7 +9525,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.17.8): @@ -9460,7 +9535,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.21.3): @@ -9470,7 +9545,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-typescript@7.16.8(@babel/core@7.17.8): resolution: {integrity: sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==} @@ -9570,7 +9645,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.17.8): @@ -9580,7 +9655,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.17.8 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 dev: true /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.21.3): @@ -9590,7 +9665,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 /@babel/plugin-transform-unicode-regex@7.16.0(@babel/core@7.12.9): resolution: {integrity: sha512-jHLK4LxhHjvCeZDWyA9c+P9XH1sOxRd1RO9xMtDVRAOND/PczPqizEtVdx4TQF/wyPaewqpT+tgQFYMnN/P94A==} @@ -9653,7 +9728,7 @@ packages: dependencies: '@babel/core': 7.17.8 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.17.8) - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 dev: true /@babel/plugin-transform-unicode-regex@7.18.6(@babel/core@7.21.3): @@ -9664,7 +9739,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/helper-create-regexp-features-plugin': 7.19.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-plugin-utils': 7.20.2 /@babel/polyfill@7.12.1: resolution: {integrity: sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==} @@ -10346,7 +10421,7 @@ packages: '@babel/helper-plugin-utils': 7.21.5 '@babel/helper-validator-option': 7.21.0 '@babel/plugin-transform-react-display-name': 7.16.7(@babel/core@7.21.3) - '@babel/plugin-transform-react-jsx': 7.19.0(@babel/core@7.21.3) + '@babel/plugin-transform-react-jsx': 7.22.3(@babel/core@7.21.3) '@babel/plugin-transform-react-jsx-development': 7.16.7(@babel/core@7.21.3) '@babel/plugin-transform-react-pure-annotations': 7.16.7(@babel/core@7.21.3) dev: true @@ -10492,7 +10567,7 @@ packages: dependencies: '@babel/code-frame': 7.18.6 '@babel/parser': 7.21.3 - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 /@babel/template@7.20.7: resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} @@ -10509,7 +10584,7 @@ packages: '@babel/code-frame': 7.18.6 '@babel/generator': 7.21.3 '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 + '@babel/helper-function-name': 7.21.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 '@babel/parser': 7.21.3 @@ -10530,7 +10605,7 @@ packages: '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 '@babel/parser': 7.21.3 - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 debug: 4.3.4(supports-color@9.2.2) globals: 11.12.0 transitivePeerDependencies: @@ -12131,7 +12206,6 @@ packages: dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jridgewell/trace-mapping@0.3.17: resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} @@ -12549,16 +12623,16 @@ packages: resolution: {integrity: sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==} engines: {node: '>=12.0.0'} - /@octokit/app@13.1.2: - resolution: {integrity: sha512-Kf+h5sa1SOI33hFsuHvTsWj1jUrjp1x4MuiJBq7U/NicfEGa6nArPUoDnyfP/YTmcQ5cQ5yvOgoIBkbwPg6kzQ==} + /@octokit/app@13.1.3: + resolution: {integrity: sha512-qG3a3AddK/XLmtpQuB2eICbOUTwwdvqfdnyOzU6PlHhhhVapLfuutkbTOllHB/5OS/slUamIBD3zhOYpKsLFDQ==} engines: {node: '>= 14'} dependencies: '@octokit/auth-app': 4.0.9 '@octokit/auth-unauthenticated': 3.0.4 '@octokit/core': 4.0.5 - '@octokit/oauth-app': 4.2.0 + '@octokit/oauth-app': 4.2.1 '@octokit/plugin-paginate-rest': 6.0.0(@octokit/core@4.0.5) - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 '@octokit/webhooks': 10.9.1 transitivePeerDependencies: - encoding @@ -12570,9 +12644,9 @@ packages: dependencies: '@octokit/auth-oauth-app': 5.0.5 '@octokit/auth-oauth-user': 2.1.1 - '@octokit/request': 6.2.1 + '@octokit/request': 6.2.3 '@octokit/request-error': 3.0.3 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 '@types/lru-cache': 5.1.1 deprecation: 2.3.1 lru-cache: 6.0.0 @@ -12589,7 +12663,7 @@ packages: '@octokit/auth-oauth-device': 4.0.4 '@octokit/auth-oauth-user': 2.1.1 '@octokit/request': 6.2.1 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 '@types/btoa-lite': 1.0.0 btoa-lite: 1.0.0 universal-user-agent: 6.0.0 @@ -12603,7 +12677,7 @@ packages: dependencies: '@octokit/oauth-methods': 2.0.5 '@octokit/request': 6.2.3 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 universal-user-agent: 6.0.0 transitivePeerDependencies: - encoding @@ -12616,7 +12690,7 @@ packages: '@octokit/auth-oauth-device': 4.0.4 '@octokit/oauth-methods': 2.0.5 '@octokit/request': 6.2.1 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 btoa-lite: 1.0.0 universal-user-agent: 6.0.0 transitivePeerDependencies: @@ -12641,7 +12715,7 @@ packages: engines: {node: '>= 14'} dependencies: '@octokit/request-error': 3.0.3 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 dev: false /@octokit/core@3.5.1: @@ -12709,15 +12783,15 @@ packages: resolution: {integrity: sha512-sxmnewSwAixkP1TrLdE6yRG53eEhHhDTYUykUwdV9x8f91WcbhunIHk9x1PZLALdBZKRPUO2HRcm4kezZ79HoA==} engines: {node: '>= 14'} dependencies: - '@octokit/request': 6.2.3 + '@octokit/request': 6.2.1 '@octokit/types': 7.4.0 universal-user-agent: 6.0.0 transitivePeerDependencies: - encoding dev: false - /@octokit/oauth-app@4.2.0: - resolution: {integrity: sha512-gyGclT77RQMkVUEW3YBeAKY+LBSc5u3eC9Wn/Uwt3WhuKuu9mrV18EnNpDqmeNll+mdV02yyBROU29Tlili6gg==} + /@octokit/oauth-app@4.2.1: + resolution: {integrity: sha512-HtRWLzvAAizuFKJEoNlhWOktNNhfnLSXJXu2htt5+x2exhHibHupz/+1AAHU4xlBFtQLQh79OB/bQf+1GP5LBg==} engines: {node: '>= 14'} dependencies: '@octokit/auth-oauth-app': 5.0.5 @@ -12726,7 +12800,7 @@ packages: '@octokit/core': 4.0.5 '@octokit/oauth-authorization-url': 5.0.0 '@octokit/oauth-methods': 2.0.5 - '@types/aws-lambda': 8.10.114 + '@types/aws-lambda': 8.10.115 fromentries: 1.3.2 universal-user-agent: 6.0.0 transitivePeerDependencies: @@ -12745,7 +12819,7 @@ packages: '@octokit/oauth-authorization-url': 5.0.0 '@octokit/request': 6.2.3 '@octokit/request-error': 3.0.3 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 btoa-lite: 1.0.0 transitivePeerDependencies: - encoding @@ -12757,8 +12831,8 @@ packages: /@octokit/openapi-types@13.10.0: resolution: {integrity: sha512-wPQDpTyy35D6VS/lekXDaKcxy6LI2hzcbmXBnP180Pdgz3dXRzoHdav0w09yZzzWX8HHLGuqwAeyMqEPtWY2XA==} - /@octokit/openapi-types@17.1.2: - resolution: {integrity: sha512-OaS7Ol4Y+U50PbejfzQflGWRMxO04nYWO5ZBv6JerqMKE2WS/tI9VoVDDPXHBlRMGG2fOdKwtVGlFfc7AVIstw==} + /@octokit/openapi-types@17.1.1: + resolution: {integrity: sha512-/X7Gh/qWiWaooJmUnYD48SYy72fyrk2ceisOSe89JojK7r0j8YrTwYpDi76kI+c6QiqX1KSgdoBTMJvktsDkYw==} dev: false /@octokit/plugin-paginate-rest@2.21.3(@octokit/core@3.5.1): @@ -12787,7 +12861,7 @@ packages: '@octokit/core': '>=4' dependencies: '@octokit/core': 4.0.5 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 dev: false /@octokit/plugin-request-log@1.0.4(@octokit/core@3.5.1): @@ -12834,7 +12908,7 @@ packages: '@octokit/core': '>=3' dependencies: '@octokit/core': 4.0.5 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 deprecation: 2.3.1 dev: false @@ -12845,18 +12919,18 @@ packages: '@octokit/core': '>=3' dependencies: '@octokit/core': 4.0.5 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 bottleneck: 2.19.5 dev: false - /@octokit/plugin-throttling@5.1.1(@octokit/core@4.0.5): - resolution: {integrity: sha512-UlsdoW3ZOhhvjnK8S+OmQWOvB14kaKKdxseGFAxVHVggKZlgKO/ZtAb1AQoHXaQUCfO7uV/O5BR27o/wbKAzHg==} + /@octokit/plugin-throttling@5.2.0(@octokit/core@4.0.5): + resolution: {integrity: sha512-qWYvVIS1aRC3hN4a0ICWUp51IolHIn7E4iri2AKjbExJaovMDvRtae4nGoxG5pP6+WATk7JZ5epOJobFbGYV1w==} engines: {node: '>= 14'} peerDependencies: '@octokit/core': ^4.0.0 dependencies: '@octokit/core': 4.0.5 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 bottleneck: 2.19.5 dev: false @@ -12879,7 +12953,7 @@ packages: resolution: {integrity: sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==} engines: {node: '>= 14'} dependencies: - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 deprecation: 2.3.1 once: 1.4.0 dev: false @@ -12901,7 +12975,7 @@ packages: engines: {node: '>= 14'} dependencies: '@octokit/endpoint': 7.0.2 - '@octokit/request-error': 3.0.3 + '@octokit/request-error': 3.0.1 '@octokit/types': 7.4.0 is-plain-object: 5.0.0 node-fetch: 2.6.7 @@ -12916,7 +12990,7 @@ packages: dependencies: '@octokit/endpoint': 7.0.2 '@octokit/request-error': 3.0.3 - '@octokit/types': 9.2.0 + '@octokit/types': 9.2.1 is-plain-object: 5.0.0 node-fetch: 2.6.7 universal-user-agent: 6.0.0 @@ -12957,10 +13031,10 @@ packages: dependencies: '@octokit/openapi-types': 13.10.0 - /@octokit/types@9.2.0: - resolution: {integrity: sha512-xySzJG4noWrIBFyMu4lg4tu9vAgNg9S0aoLRONhAEz6ueyi1evBzb40HitIosaYS4XOexphG305IVcLrIX/30g==} + /@octokit/types@9.2.1: + resolution: {integrity: sha512-Vx4keMiD/CAiwVFasLcH0xBSVbKIHebIZke9i7ZbUWGNN4vJFWSYH6Nvga7UY9NIJCGa6x3QG849XTbi5wYmkA==} dependencies: - '@octokit/openapi-types': 17.1.2 + '@octokit/openapi-types': 17.1.1 dev: false /@octokit/webhooks-methods@3.0.2: @@ -13491,7 +13565,7 @@ packages: '@slack/types': 1.10.0 '@types/is-stream': 1.1.0 '@types/node': 16.18.21 - axios: 0.21.4 + axios: 0.21.4(debug@4.3.4) eventemitter3: 3.1.2 form-data: 2.5.1 is-stream: 1.1.0 @@ -14529,7 +14603,7 @@ packages: interpret: 2.2.0 json5: 2.2.3 lazy-universal-dotenv: 3.0.1 - picomatch: 2.3.1 + picomatch: 2.3.0 pkg-dir: 5.0.0 pretty-hrtime: 1.0.3 react: 17.0.2 @@ -15981,15 +16055,15 @@ packages: /@types/aria-query@4.2.2: resolution: {integrity: sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==} - /@types/aws-lambda@8.10.114: - resolution: {integrity: sha512-M8WpEGfC9iQ6V2Ccq6nGIXoQgeVc6z0Ngk8yCOL5V/TYIxshvb0MWQYLFFTZDesL0zmsoBc4OBjG9DB/4rei6w==} + /@types/aws-lambda@8.10.115: + resolution: {integrity: sha512-kCZuFXKLV3y8NjSoaD5+qKTpRWvPz3uh3W/u1uwlw3Mg+MtaStg1NWgjAwUXo/VJDb6n6KF1ljykFNlNwEJ53Q==} dev: false /@types/babel__core@7.1.16: resolution: {integrity: sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==} dependencies: '@babel/parser': 7.21.3 - '@babel/types': 7.21.3 + '@babel/types': 7.22.4 '@types/babel__generator': 7.6.3 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.14.2 @@ -16217,8 +16291,8 @@ packages: jest-matcher-utils: 27.5.1 pretty-format: 27.5.1 - /@types/jquery@3.5.14: - resolution: {integrity: sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==} + /@types/jquery@3.5.16: + resolution: {integrity: sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==} dependencies: '@types/sizzle': 2.3.3 dev: true @@ -16237,8 +16311,8 @@ packages: /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - /@types/jsonwebtoken@9.0.1: - resolution: {integrity: sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==} + /@types/jsonwebtoken@9.0.2: + resolution: {integrity: sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==} dependencies: '@types/node': 16.18.21 dev: false @@ -16405,6 +16479,12 @@ packages: dependencies: '@types/react': 17.0.50 + /@types/react-outside-click-handler@1.3.1: + resolution: {integrity: sha512-0BNan5zIIDyO5k9LFSG+60ZxQ/0wf+LTF9BJx3oOUdOaJlZk6RCe52jRB75mlvLLJx2YLa61+NidOwBfptWMKw==} + dependencies: + '@types/react': 17.0.50 + dev: false + /@types/react-router-dom@5.3.3: resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} dependencies: @@ -16512,7 +16592,7 @@ packages: /@types/tinymce@4.6.5: resolution: {integrity: sha512-C5gdEi85rUeYEXzXlwAm9MzvfMI8SooVbBMLLN/BQTeDnHWNtRWAkB6ON9s0lhWZYrmjSgLPrWSe86rjciACEQ==} dependencies: - '@types/jquery': 3.5.14 + '@types/jquery': 3.5.16 dev: true /@types/tough-cookie@4.0.2: @@ -16641,7 +16721,7 @@ packages: /@types/wordpress__data-controls@2.2.0: resolution: {integrity: sha512-arDQ6Sds47Lq3ZZwgCrG1QTQjBIJPhv0vpJhv8zWXSINkL/Ourus0k4y+WkgnNT1aSpTSdrISrDlAwwPuy6usw==} dependencies: - '@types/wordpress__data': 6.0.0 + '@types/wordpress__data': 6.0.2 '@wordpress/api-fetch': 5.2.6 dev: true @@ -17093,7 +17173,7 @@ packages: eslint: 8.32.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0(eslint@8.32.0) - semver: 7.5.0 + semver: 7.3.8 transitivePeerDependencies: - supports-color - typescript @@ -17667,6 +17747,7 @@ packages: /@wordpress/base-styles@4.3.1: resolution: {integrity: sha512-A/PpsWP5FSni2++v+cBaSoeBRw0Yv1oK5iBXKMATxdQmPfGVPauBl365U3IUPz0lxr5ckFIq/Ey+Ejww+Pe5sQ==} + dev: false /@wordpress/blob@3.19.0: resolution: {integrity: sha512-nw0oOg8bUgPaVcwfpdczY77ZO1Cy844DX5yXY5gKwVB9VHHfwhttVRr85GMxq9uQhH6rzkDerX+YzIGK8x4c+A==} @@ -19871,13 +19952,13 @@ packages: postcss-custom-properties: 10.0.0 dev: true - /@wordpress/postcss-plugins-preset@3.6.1(postcss@8.4.12): - resolution: {integrity: sha512-q/pTHuBaxwJQuT8sngj1X1R6/YETqTrc4UmWLuYJt0RDRh31NukEwbWHKEDqOOA7aEDxEBuyPA7EKiffGxYbrQ==} + /@wordpress/postcss-plugins-preset@3.10.0(postcss@8.4.12): + resolution: {integrity: sha512-vBXy+8e6BpUvmxcIFgldvFlTFA6kAlC+J86GcDEoIq/IFVoqSJlnX1s1QHXgG3CzTHjIlN/FNJxGxYinSMJhng==} engines: {node: '>=12'} peerDependencies: postcss: ^8.0.0 dependencies: - '@wordpress/base-styles': 4.3.1 + '@wordpress/base-styles': 4.25.0 autoprefixer: 10.4.4(postcss@8.4.12) postcss: 8.4.12 dev: true @@ -20222,7 +20303,7 @@ packages: - webpack-command dev: true - /@wordpress/scripts@19.2.4(@babel/core@7.21.3)(acorn@8.8.1)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(uglify-js@3.14.5): + /@wordpress/scripts@19.2.4(@babel/core@7.21.3)(acorn@8.8.1)(debug@4.3.4)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)(uglify-js@3.14.5): resolution: {integrity: sha512-klkfjBOPfr/RT/3Tvmx+gLbZ+dxq5L0dJQHCHxEURMRW/A8SfJJPtmC29L9sE1KhO3zUMWxrkn2L6HhSzbvQbA==} engines: {node: '>=12.13', npm: '>=6.9'} hasBin: true @@ -20234,7 +20315,7 @@ packages: '@wordpress/eslint-plugin': 9.3.0(@babel/core@7.21.3)(eslint@7.32.0)(typescript@4.9.5) '@wordpress/jest-preset-default': 7.1.3(@babel/core@7.21.3)(jest@26.6.3)(react-dom@17.0.2)(react@17.0.2) '@wordpress/npm-package-json-lint-config': 4.2.0(npm-package-json-lint@5.4.2) - '@wordpress/postcss-plugins-preset': 3.6.1(postcss@8.4.12) + '@wordpress/postcss-plugins-preset': 3.10.0(postcss@8.4.12) '@wordpress/prettier-config': 1.4.0(wp-prettier@2.2.1-beta-1) '@wordpress/stylelint-config': 19.1.0(stylelint@13.13.1) babel-jest: 26.6.3(@babel/core@7.21.3) @@ -20254,7 +20335,7 @@ packages: filenamify: 4.3.0 jest: 26.6.3 jest-circus: 26.6.3 - jest-dev-server: 5.0.3 + jest-dev-server: 5.0.3(debug@4.3.4) jest-environment-node: 26.6.2 markdownlint: 0.23.1 markdownlint-cli: 0.27.1 @@ -21262,7 +21343,7 @@ packages: dev: false /array-uniq@1.0.3: - resolution: {integrity: sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=} + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} engines: {node: '>=0.10.0'} dev: true @@ -21532,10 +21613,10 @@ packages: - supports-color dev: true - /axios@0.21.4: + /axios@0.21.4(debug@4.3.4): resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} dependencies: - follow-redirects: 1.14.7(debug@4.3.3) + follow-redirects: 1.14.7(debug@4.3.4) transitivePeerDependencies: - debug @@ -24562,7 +24643,7 @@ packages: - encoding /cross-spawn@5.1.0: - resolution: {integrity: sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=} + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} dependencies: lru-cache: 4.1.5 shebang-command: 1.2.0 @@ -24713,7 +24794,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.21) postcss-value-parser: 4.2.0 schema-utils: 3.1.1 - semver: 7.3.8 + semver: 7.5.0 webpack: 5.70.0(uglify-js@3.14.5)(webpack-cli@4.9.2) dev: true @@ -25222,18 +25303,6 @@ packages: ms: 2.1.2 dev: true - /debug@4.3.2: - resolution: {integrity: sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - /debug@4.3.3: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} @@ -25285,12 +25354,8 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - /decimal.js@10.3.1: - resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==} - /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: true /decode-uri-component@0.2.0: resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} @@ -25582,7 +25647,7 @@ packages: dev: false /discontinuous-range@1.0.0: - resolution: {integrity: sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=} + resolution: {integrity: sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==} /dns-equal@1.0.0: resolution: {integrity: sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==} @@ -25967,14 +26032,6 @@ packages: graceful-fs: 4.2.9 tapable: 2.2.1 - /enhanced-resolve@5.9.2: - resolution: {integrity: sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.9 - tapable: 2.2.1 - dev: true - /enquirer@2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} @@ -26304,7 +26361,7 @@ packages: eslint: '*' eslint-plugin-import: '*' dependencies: - debug: 4.3.3 + debug: 4.3.4(supports-color@9.2.2) eslint: 8.32.0 eslint-plugin-import: 2.25.4(@typescript-eslint/parser@5.54.0)(eslint-import-resolver-typescript@2.5.0)(eslint-import-resolver-webpack@0.13.2)(eslint@8.32.0) glob: 7.2.3 @@ -27498,7 +27555,7 @@ packages: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.4 + micromatch: 4.0.5 dev: true /fast-json-parse@1.0.3: @@ -27947,6 +28004,17 @@ packages: dependencies: debug: 4.3.3 + /follow-redirects@1.14.7(debug@4.3.4): + resolution: {integrity: sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dependencies: + debug: 4.3.4(supports-color@9.2.2) + /follow-redirects@1.5.10: resolution: {integrity: sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==} engines: {node: '>=4.0'} @@ -28043,7 +28111,7 @@ packages: vue-template-compiler: optional: true dependencies: - '@babel/code-frame': 7.16.7 + '@babel/code-frame': 7.18.6 '@types/json-schema': 7.0.9 chalk: 4.1.2 chokidar: 3.5.3 @@ -28055,7 +28123,7 @@ packages: memfs: 3.3.0 minimatch: 3.1.2 schema-utils: 2.7.0 - semver: 7.3.8 + semver: 7.5.0 tapable: 1.1.3 typescript: 4.9.5 webpack: 4.46.0(webpack-cli@3.3.12) @@ -28535,10 +28603,10 @@ packages: hasBin: true dependencies: foreground-child: 3.1.1 - jackspeak: 2.2.0 - minimatch: 9.0.0 - minipass: 6.0.1 - path-scurry: 1.9.1 + jackspeak: 2.2.1 + minimatch: 9.0.1 + minipass: 6.0.2 + path-scurry: 1.9.2 dev: false /glob@5.0.15: @@ -28582,7 +28650,6 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -28801,7 +28868,7 @@ packages: engines: {node: '>=0.6.0'} hasBin: true dependencies: - minimist: 1.2.5 + minimist: 1.2.8 dev: true /good-listener@1.2.2: @@ -28972,7 +29039,7 @@ packages: dependencies: chalk: 2.4.2 maxmin: 2.1.0 - uglify-js: 3.17.0 + uglify-js: 3.17.4 uri-path: 1.0.0 dev: true @@ -29152,7 +29219,7 @@ packages: engines: {node: '>=0.4.7'} hasBin: true dependencies: - minimist: 1.2.5 + minimist: 1.2.8 neo-async: 2.6.2 source-map: 0.6.1 wordwrap: 1.0.0 @@ -30571,7 +30638,7 @@ packages: has-tostringtag: 1.0.0 /is-subset@0.1.1: - resolution: {integrity: sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=} + resolution: {integrity: sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==} /is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} @@ -30911,8 +30978,8 @@ packages: iterate-iterator: 1.0.2 dev: true - /jackspeak@2.2.0: - resolution: {integrity: sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==} + /jackspeak@2.2.1: + resolution: {integrity: sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==} engines: {node: '>=14'} dependencies: '@isaacs/cliui': 8.0.2 @@ -31387,7 +31454,7 @@ packages: - supports-color dev: true - /jest-dev-server@5.0.3: + /jest-dev-server@5.0.3(debug@4.3.4): resolution: {integrity: sha512-aJR3a5KdY18Lsz+VbREKwx2HM3iukiui+J9rlv9o6iYTwZCSsJazSTStcD9K1q0AIF3oA+FqLOKDyo/sc7+fJw==} dependencies: chalk: 4.1.2 @@ -31396,7 +31463,7 @@ packages: prompts: 2.4.2 spawnd: 5.0.0 tree-kill: 1.2.2 - wait-on: 5.3.0 + wait-on: 5.3.0(debug@4.3.4) transitivePeerDependencies: - debug - supports-color @@ -31717,7 +31784,7 @@ packages: dependencies: chalk: 4.1.2 cwd: 0.10.0 - jest-dev-server: 5.0.3 + jest-dev-server: 5.0.3(debug@4.3.4) jest-environment-node: 27.5.1 merge-deep: 3.0.3 transitivePeerDependencies: @@ -32844,7 +32911,7 @@ packages: dependencies: '@babel/core': 7.21.3 '@babel/generator': 7.21.3 - '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.21.3) + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.3) '@babel/plugin-syntax-typescript': 7.18.6(@babel/core@7.21.3) '@babel/traverse': 7.21.3 '@babel/types': 7.22.4 @@ -33430,7 +33497,7 @@ packages: cssom: 0.4.4 cssstyle: 2.3.0 data-urls: 2.0.0 - decimal.js: 10.3.1 + decimal.js: 10.4.3 domexception: 2.0.1 escodegen: 2.0.0 form-data: 3.0.1 @@ -33438,11 +33505,11 @@ packages: http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.0 + nwsapi: 2.2.5 parse5: 6.0.1 saxes: 5.0.1 symbol-tree: 3.2.4 - tough-cookie: 4.0.0 + tough-cookie: 4.1.3 w3c-hr-time: 1.0.2 w3c-xmlserializer: 2.0.0 webidl-conversions: 6.1.0 @@ -33483,7 +33550,7 @@ packages: parse5: 7.1.2 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.1.2 + tough-cookie: 4.1.3 w3c-xmlserializer: 4.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 @@ -33550,7 +33617,7 @@ packages: resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} hasBin: true dependencies: - minimist: 1.2.5 + minimist: 1.2.8 /json5@2.2.0: resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==} @@ -34043,11 +34110,11 @@ packages: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} /lodash.differencewith@4.5.0: - resolution: {integrity: sha1-uvr7yRi1UVTheRdqALsK76rIVLc=} + resolution: {integrity: sha512-/8JFjydAS+4bQuo3CpLMBv7WxGFyk7/etOAsrQUCu0a9QVDemxv0YQ0rFyeZvqlUD314SERfNlgnlqqHmaQ0Cg==} dev: true /lodash.escape@4.0.1: - resolution: {integrity: sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=} + resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==} /lodash.find@3.2.1: resolution: {integrity: sha1-BG4xnzrOkSrGySRsf2g8XsB7Nq0=} @@ -34061,11 +34128,11 @@ packages: dev: false /lodash.flatten@4.4.0: - resolution: {integrity: sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=} + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: true /lodash.flattendeep@4.4.0: - resolution: {integrity: sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=} + resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} /lodash.isarguments@3.1.0: resolution: {integrity: sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=} @@ -34076,7 +34143,7 @@ packages: dev: false /lodash.isequal@4.5.0: - resolution: {integrity: sha1-QVxEePK8wwEgwizhDtMib30+GOA=} + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} /lodash.istypedarray@3.0.6: resolution: {integrity: sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=} @@ -34236,8 +34303,8 @@ packages: engines: {node: '>=12'} dev: true - /lru-cache@9.1.1: - resolution: {integrity: sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==} + /lru-cache@9.1.2: + resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==} engines: {node: 14 || >=16.14} dev: false @@ -34363,7 +34430,7 @@ packages: dev: true /map-values@1.0.1: - resolution: {integrity: sha1-douOecAJvytk/ugG4ip7HEGQyZA=} + resolution: {integrity: sha512-BbShUnr5OartXJe1GeccAWtfro11hhgNJg6G9/UtWKjVGvV5U4C09cg5nk8JUevhXODaXY+hQ3xxMUKSs62ONQ==} dev: true /map-visit@1.0.0: @@ -34607,7 +34674,7 @@ packages: resolution: {integrity: sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==} /mdurl@1.0.1: - resolution: {integrity: sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=} + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} dev: true /media-typer@0.3.0: @@ -35349,8 +35416,8 @@ packages: brace-expansion: 2.0.1 dev: true - /minimatch@9.0.0: - resolution: {integrity: sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==} + /minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 @@ -35435,8 +35502,8 @@ packages: yallist: 4.0.0 dev: true - /minipass@6.0.1: - resolution: {integrity: sha512-Tenl5QPpgozlOGBiveNYHg2f6y+VpxsXRoIHFUVJuSmTonXRAE6q9b8Mp/O46762/2AlW4ye4Nkyvx0fgWDKbw==} + /minipass@6.0.2: + resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==} engines: {node: '>=16 || 14 >=14.17'} dev: false @@ -35498,7 +35565,7 @@ packages: resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} hasBin: true dependencies: - minimist: 1.2.5 + minimist: 1.2.8 /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} @@ -35687,7 +35754,7 @@ packages: dependencies: carlo: 0.9.46 chokidar: 3.5.2 - debug: 4.3.2 + debug: 4.3.4(supports-color@9.2.2) isbinaryfile: 3.0.3 mime: 2.5.2 opn: 5.5.0 @@ -35952,7 +36019,7 @@ packages: engines: {node: '>=10'} dependencies: hosted-git-info: 4.0.2 - is-core-module: 2.8.0 + is-core-module: 2.10.0 semver: 7.3.8 validate-npm-package-license: 3.0.4 dev: true @@ -36139,9 +36206,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /nwsapi@2.2.0: - resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==} - /nwsapi@2.2.5: resolution: {integrity: sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==} @@ -36174,7 +36238,7 @@ packages: kind-of: 3.2.2 /object-filter@1.0.2: - resolution: {integrity: sha1-rwt5f/6+r4pSxmN87b6IFs/sG8g=} + resolution: {integrity: sha512-NahvP2vZcy1ZiiYah30CEPw0FpDcSkSePJBMpzl5EQgCmISijiGuJm3SPYp7U+Lf2TljyaIw3E5EgkEx/TNEVA==} dev: true /object-inspect@1.12.2: @@ -36342,14 +36406,14 @@ packages: resolution: {integrity: sha512-z6cgZBFxirpFEQ1La8Lg83GCs5hOV2EPpkYYdjsGNbfQMv8qUGjq294MiRBCbZqLufviakGsPUxaNKe3JrPmsA==} engines: {node: '>= 14'} dependencies: - '@octokit/app': 13.1.2 + '@octokit/app': 13.1.3 '@octokit/core': 4.0.5 - '@octokit/oauth-app': 4.2.0 + '@octokit/oauth-app': 4.2.1 '@octokit/plugin-paginate-rest': 6.0.0(@octokit/core@4.0.5) '@octokit/plugin-rest-endpoint-methods': 7.0.1(@octokit/core@4.0.5) '@octokit/plugin-retry': 4.1.3(@octokit/core@4.0.5) - '@octokit/plugin-throttling': 5.1.1(@octokit/core@4.0.5) - '@octokit/types': 9.2.0 + '@octokit/plugin-throttling': 5.2.0(@octokit/core@4.0.5) + '@octokit/types': 9.2.1 transitivePeerDependencies: - encoding dev: false @@ -36955,12 +37019,12 @@ packages: path-root-regex: 0.1.2 dev: true - /path-scurry@1.9.1: - resolution: {integrity: sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g==} + /path-scurry@1.9.2: + resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==} engines: {node: '>=16 || 14 >=14.17'} dependencies: - lru-cache: 9.1.1 - minipass: 6.0.1 + lru-cache: 9.1.2 + minipass: 6.0.2 dev: false /path-to-regexp@0.1.7: @@ -37054,14 +37118,14 @@ packages: engines: {node: '>=6'} /pinkie-promise@2.0.1: - resolution: {integrity: sha1-ITXW36ejWMBprJsXh3YogihFD/o=} + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} engines: {node: '>=0.10.0'} dependencies: pinkie: 2.0.4 dev: true /pinkie@2.0.4: - resolution: {integrity: sha1-clVrgM+g1IqXToDnckjoDtT3+HA=} + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} engines: {node: '>=0.10.0'} dev: true @@ -37451,7 +37515,7 @@ packages: loader-utils: 2.0.4 postcss: 8.4.21 schema-utils: 3.1.1 - semver: 7.5.0 + semver: 7.3.8 webpack: 5.76.3(uglify-js@3.14.5)(webpack-cli@4.9.2) dev: true @@ -38637,7 +38701,7 @@ packages: dev: true /pseudomap@1.0.2: - resolution: {integrity: sha1-8FKijacOYYkX7wqKw0wa5aaChrM=} + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true /psl@1.8.0: @@ -38826,7 +38890,7 @@ packages: dev: true /q@1.5.1: - resolution: {integrity: sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=} + resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} /qqjs@0.3.11: @@ -38886,7 +38950,6 @@ packages: /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - dev: true /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -38906,7 +38969,7 @@ packages: performance-now: 2.1.0 /railroad-diagrams@1.0.0: - resolution: {integrity: sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=} + resolution: {integrity: sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==} /ramda@0.21.0: resolution: {integrity: sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=} @@ -38970,7 +39033,7 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 dependencies: - loader-utils: 2.0.2 + loader-utils: 2.0.4 schema-utils: 3.1.1 webpack: 4.46.0(webpack-cli@3.3.12) dev: true @@ -39806,7 +39869,7 @@ packages: dev: true /read-pkg-up@1.0.1: - resolution: {integrity: sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=} + resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} engines: {node: '>=0.10.0'} dependencies: find-up: 1.1.2 @@ -39867,7 +39930,7 @@ packages: dev: true /read@1.0.7: - resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} + resolution: {integrity: sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=} engines: {node: '>=0.8'} dependencies: mute-stream: 0.0.8 @@ -40456,7 +40519,7 @@ packages: /resolve@1.20.0: resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==} dependencies: - is-core-module: 2.8.0 + is-core-module: 2.10.0 path-parse: 1.0.7 /resolve@1.22.1: @@ -40554,7 +40617,7 @@ packages: inherits: 2.0.4 /rst-selector-parser@2.2.3: - resolution: {integrity: sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=} + resolution: {integrity: sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==} dependencies: lodash.flattendeep: 4.4.0 nearley: 2.20.1 @@ -42360,7 +42423,7 @@ packages: colord: 2.9.2 cosmiconfig: 7.0.1 css-functions-list: 3.0.1 - debug: 4.3.3 + debug: 4.3.4(supports-color@9.2.2) execall: 2.0.0 fast-glob: 3.2.11 fastest-levenshtein: 1.0.12 @@ -42620,7 +42683,7 @@ packages: resolution: {integrity: sha512-kS7E53It6HA8S1FVFBWP7HDwgTiJtkmYk7TsowGlizzVrivR1Mf9mgjXHY1k7rOfozRVMZSfwjB3bevO4QEqpg==} dependencies: get-stdin: 4.0.1 - minimist: 1.2.5 + minimist: 1.2.8 dev: true /tannin@1.2.0: @@ -43105,23 +43168,14 @@ packages: punycode: 2.1.1 dev: true - /tough-cookie@4.0.0: - resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} - engines: {node: '>=6'} - dependencies: - psl: 1.8.0 - punycode: 2.1.1 - universalify: 0.1.2 - - /tough-cookie@4.1.2: - resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==} + /tough-cookie@4.1.3: + resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} dependencies: psl: 1.8.0 punycode: 2.1.1 universalify: 0.2.0 url-parse: 1.5.10 - dev: true /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -43278,8 +43332,8 @@ packages: webpack: ^5.0.0 dependencies: chalk: 4.1.2 - enhanced-resolve: 5.9.2 - micromatch: 4.0.4 + enhanced-resolve: 5.12.0 + micromatch: 4.0.5 semver: 7.3.8 typescript: 4.9.5 webpack: 5.76.3(uglify-js@3.14.5)(webpack-cli@4.9.2) @@ -43536,20 +43590,12 @@ packages: hasBin: true requiresBuild: true - /uglify-js@3.17.0: - resolution: {integrity: sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==} - engines: {node: '>=0.8.0'} - hasBin: true - requiresBuild: true - dev: true - /uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} hasBin: true requiresBuild: true dev: true - optional: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -43786,7 +43832,7 @@ packages: /universal-github-app-jwt@1.1.1: resolution: {integrity: sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==} dependencies: - '@types/jsonwebtoken': 9.0.1 + '@types/jsonwebtoken': 9.0.2 jsonwebtoken: 9.0.0 dev: false @@ -43800,7 +43846,6 @@ packages: /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} - dev: true /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} @@ -43818,7 +43863,7 @@ packages: engines: {node: '>= 0.8'} /unquote@1.1.1: - resolution: {integrity: sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=} + resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} /unset-value@1.0.0: resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} @@ -43978,7 +44023,6 @@ packages: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - dev: true /url@0.10.3: resolution: {integrity: sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==} @@ -44377,15 +44421,15 @@ packages: rx: 4.1.0 dev: true - /wait-on@5.3.0: + /wait-on@5.3.0(debug@4.3.4): resolution: {integrity: sha512-DwrHrnTK+/0QFaB9a8Ol5Lna3k7WvUR4jzSKmz0YaPBpuN2sACyiPVKVfj6ejnjcajAcvn3wlbTyMIn9AZouOg==} engines: {node: '>=8.9.0'} hasBin: true dependencies: - axios: 0.21.4 + axios: 0.21.4(debug@4.3.4) joi: 17.6.0 lodash: 4.17.21 - minimist: 1.2.5 + minimist: 1.2.8 rxjs: 6.6.7 transitivePeerDependencies: - debug @@ -44398,7 +44442,7 @@ packages: axios: 0.25.0 joi: 17.6.0 lodash: 4.17.21 - minimist: 1.2.5 + minimist: 1.2.8 rxjs: 7.8.0 transitivePeerDependencies: - debug @@ -44918,7 +44962,7 @@ packages: '@webassemblyjs/wasm-parser': 1.11.1 acorn: 8.8.1 acorn-import-assertions: 1.8.0(acorn@8.8.1) - browserslist: 4.19.3 + browserslist: 4.21.4 chrome-trace-event: 1.0.3 enhanced-resolve: 5.12.0 es-module-lexer: 0.9.3 @@ -45158,7 +45202,7 @@ packages: resolution: {integrity: sha512-6Guapw25yCmnQHyz62TEi1OvRnIzGfyj0sVaPBhwx19QoxeD6HI2zZHWeBIUXSauJK3BIyxWPYnxlwmnqHUskg==} dependencies: chalk: 2.4.2 - glob: 7.2.3 + glob: 7.2.0 moment: 2.29.1 php-parser: 3.0.3 text-table: 0.2.0