diff --git a/docs/the-basics/error-handling.md b/docs/the-basics/error-handling.md new file mode 100644 index 0000000..e191d83 --- /dev/null +++ b/docs/the-basics/error-handling.md @@ -0,0 +1,86 @@ +--- +title: Error Handling +description: Lumberjack provides a robust error handling system that displays detailed error pages in development and a generic error page in production. +sidebar_position: 13 +--- + +# Error Handling + +Lumberjack comes with a powerful error handling system powered by [Ignition](https://spatie.be/docs/ignition/v1/introduction), which provides beautiful, detailed error pages when you're in development. When in production, Lumberjack will display a simple, styled error page to avoid exposing sensitive information. + +## The Default Error Page + +When `APP_DEBUG` is set to `false` in your `.env` file, Lumberjack will catch any exceptions and display a generic error page. This prevents your site from showing a blank white page or a detailed error stack trace that could be a security risk. + +![Default Error Page](/img/error-page-screenshot.png) + +As you can see, it's a simple, clean error page that informs the user that something has gone wrong. + +## Customizing the Error Page + +While the default error page is a great starting point, you may want to create a custom error page that matches your site's branding. You can do this by extending the `Rareloop\Lumberjack\Exceptions\Handler` class and overriding the `renderDefaultErrorView` method. + +It's important to note that the expectation is that you will extend the exception handler to create your own custom error pages. + +Here's an example of how you might create a custom error handler: + +```php +// app/Exceptions/Handler.php +namespace App\Exceptions; + +use Exception; +use Psr\Http\Message\ResponseInterface; +use Rareloop\Lumberjack\Http\Responses\TimberResponse; +use Rareloop\Lumberjack\Exceptions\Handler as ExceptionHandler; + +class Handler extends ExceptionHandler +{ + protected function renderDefaultErrorView(Exception $e): ResponseInterface + { + $status = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500; + + return new TimberResponse('views/errors/error.twig', [ + 'statusCode' => $status, + ], $status); + } +} +``` + +In this example, we're telling Lumberjack to render the `views/errors/error.twig` template instead of the default one. You can now create a custom Twig file with your own branding. + +Once you have created your custom `Handler` class, you will need to update your `bootstrap/app.php` file to tell Lumberjack to use your custom handler instead of the default one. + +```php +// bootstrap/app.php +... +$app->singleton( + Rareloop\Lumberjack\Contracts\ExceptionHanlder::class, + App\Exceptions\Handler::class +); +... +``` + +## Configuring Ignition + +Lumberjack v8.3 introduces a new `Ignition` facade and `IgnitionServiceProvider` to make it easier to configure Ignition. You can now add solution providers, set themes, and more from any service provider. + +Here's an example of how you might add a custom solution provider to Ignition in your `AppServiceProvider`: + +```php +// app/Providers/AppServiceProvider.php +namespace App\Providers; + +use App\Solutions\MyCustomSolutionProvider; +use Rareloop\Lumberjack\Facades\Ignition; +use Rareloop\Lumberjack\Providers\ServiceProvider; + +class AppServiceProvider extends ServiceProvider +{ + public function boot() + { + Ignition::addSolutionProviders([ + MyCustomSolutionProvider::class, + ]); + } +} +``` diff --git a/docs/the-basics/wordpress-controllers.md b/docs/the-basics/wordpress-controllers.md index f9615d5..8b5a585 100644 --- a/docs/the-basics/wordpress-controllers.md +++ b/docs/the-basics/wordpress-controllers.md @@ -101,3 +101,49 @@ add_filter('lumberjack/password_protect_template', function() { return 'my-password-template.twig'; }); ``` + +## Dependency Injection in WordPress Controllers + +:::info +Available from v8.3.0, with full adoption in v9 +::: + +In newer versions of Lumberjack, we've introduced dependency injection typehints for your WordPress controllers - for example: + +```diff +class PageHomeController +{ +- public function handle() ++ public function handle(TimberContext $context, Post $post) + { +- $context = Timber::context(); +- $context['post'] = Timber::get_post(); ++ $context->set('post', $post); + + return new TimberResponse('home', $context); + } +} +``` + +This makes controllers much leaner, but critically, much more testable by de-coupling them from Timber. + +### Available Typehints + +Any object bound in the [Container](../container/using-the-container.md) can be typehinted, for example, `Application $app` or `\Rareloop\Lumberjack\LoggerInterface`. + +For each Lumberjack type, there's full support for child classes. For example, injecting a custom post type will respect your Timber classmap. + +| Typehint | Description | Timber Equivalent | +| ------------------------------------ | ------------------------------- | --------------------- | +| `\Rareloop\Lumberjack\TimberContext` | Get a Timber context singleton | `Timber::context()` | +| `\Rareloop\Lumberjack\PostQuery` | Get all the posts for the query | `Timber::get_posts()` | +| `\Rareloop\Lumberjack\Post` | Get the current Post object | `Timber::get_post()` | +| `\Your\Custom\PostType` | Get the current PostType | `Timber::get_post()` | +| `\Rareloop\Lumberjack\Term` | Get the current Term | `Timber::get_term()` | +| `\Your\Custom\CategoryTerm` | Get the current CategoryTerm | `Timber::get_term()` | +| `\Rareloop\Lumberjack\User` | Get the current User | `Timber::get_user()` | +| `\Your\Custom\AdminUser` | Get the current AdminUser | `Timber::get_user()` | + +:::note +For each of Lumberjack's Proxy objects, the upstream Timber classes/interfaces are also supported. For example, typehinting `\Timber\PostQuery` will return an instance of that class. +::: diff --git a/docs/upgrade-guide.md b/docs/upgrade-guide.md index 4ce49b3..de3ecfc 100644 --- a/docs/upgrade-guide.md +++ b/docs/upgrade-guide.md @@ -6,6 +6,16 @@ sidebar_position: 3 # Upgrade Guide +## Upgrading from v8.2 to v8.3 + +Estimated time for upgrade: 1 minute + +Lumberjack v8.3 is a minor release with no breaking changes. + +This release introduces a new default error page for production environments, provides an easier way to configure Ignition, and expands dependency injection support for WordPress controllers. + +See [Error Handling](./the-basics/error-handling) and [WordPress Controllers](./the-basics/wordpress-controllers.md#dependency-injection-in-wordpress-controllers). + ## Upgrading from v8 to v8.1 Estimated time for upgrade: 5 minutes diff --git a/docs/whats-new.md b/docs/whats-new.md index df2e2df..9e6a56a 100644 --- a/docs/whats-new.md +++ b/docs/whats-new.md @@ -6,6 +6,14 @@ sidebar_position: 1 # What's New +## What's new in v8.3 + +Lumberjack v8.3 is a minor release that introduces a styled default error page for production and refactors Ignition registration to improve extensibility. + +- **Production Error Page**: A clean, styled 'Lumberjack | status' fallback page is now displayed when debug mode is `false`, preventing blank white pages on errors. +- **Easier Ignition Configuration**: A new `Ignition` facade and `IgnitionServiceProvider` have been introduced to allow for easier configuration of Ignition. You can now easily add solution providers or set themes from any service provider. +- **Expanded dependency injection support for WordPress controllers**: New, streamlined, options to make controllers smaller, and more testable. + ## What's new in v8.2 Lumberjack v8.2 is a minor release with the following changes: diff --git a/package-lock.json b/package-lock.json index 8bdec44..33a3d69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,8 @@ "name": "lumberjack-docs", "version": "0.0.0", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/core": "^3.10.1", + "@docusaurus/preset-classic": "^3.10.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -17,10 +17,11 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@docusaurus/eslint-plugin": "^3.9.2", - "@docusaurus/module-type-aliases": "3.9.2", - "@docusaurus/tsconfig": "3.9.2", - "@docusaurus/types": "3.9.2", + "@docusaurus/eslint-plugin": "^3.10.1", + "@docusaurus/faster": "^3.10.1", + "@docusaurus/module-type-aliases": "^3.10.1", + "@docusaurus/tsconfig": "^3.10.1", + "@docusaurus/types": "^3.10.1", "@signalwire/docusaurus-plugin-llms-txt": "^1.2.2", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -34,117 +35,47 @@ "node": ">=20.0" } }, - "node_modules/@ai-sdk/gateway": { - "version": "2.0.24", - "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.24.tgz", - "integrity": "sha512-mflk80YF8hj8vrF9e1IHhovGKC1ubX+sY88pesSk3pUiXfH5VPO8dgzNnxjwsqsCZrnkHcztxS5cSl4TzSiEuA==", - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/provider": "2.0.1", - "@ai-sdk/provider-utils": "3.0.20", - "@vercel/oidc": "3.0.5" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "zod": "^3.25.76 || ^4.1.8" - } - }, - "node_modules/@ai-sdk/provider": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.1.tgz", - "integrity": "sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng==", - "license": "Apache-2.0", - "dependencies": { - "json-schema": "^0.4.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ai-sdk/provider-utils": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.20.tgz", - "integrity": "sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ==", - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/provider": "2.0.1", - "@standard-schema/spec": "^1.0.0", - "eventsource-parser": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "zod": "^3.25.76 || ^4.1.8" - } - }, - "node_modules/@ai-sdk/react": { - "version": "2.0.120", - "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-2.0.120.tgz", - "integrity": "sha512-x7Oa2LDRURc8uRnAdcEfydbHLSXGYjNaFlQrGuxZAMfqhLJQ+7x4K8Z6O5vnLt414mrPaVvgirfRqsP/nsxtnw==", - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/provider-utils": "3.0.20", - "ai": "5.0.118", - "swr": "^2.2.5", - "throttleit": "2.1.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1", - "zod": "^3.25.76 || ^4.1.8" - }, - "peerDependenciesMeta": { - "zod": { - "optional": true - } - } - }, "node_modules/@algolia/abtesting": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.2.tgz", - "integrity": "sha512-oWknd6wpfNrmRcH0vzed3UPX0i17o4kYLM5OMITyMVM2xLgaRbIafoxL0e8mcrNNb0iORCJA0evnNDKRYth5WQ==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.18.1.tgz", + "integrity": "sha512-aehCadlWOGvrT91KUIZpC0MbB8KBW9yUuvTJFd2xesR7le/IsT4nJUnjCCZ4ZqZCeTcPHPV5mo//fZ5oxcSVYw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/autocomplete-core": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", - "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", + "version": "1.19.8", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.8.tgz", + "integrity": "sha512-3YEorYg44niXcm7gkft3nXYItHd44e8tmh4D33CTszPgP0QWkaLEaFywiNyJBo7UL/mqObA/G9RYuU7R8tN1IA==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", - "@algolia/autocomplete-shared": "1.19.2" + "@algolia/autocomplete-plugin-algolia-insights": "1.19.8", + "@algolia/autocomplete-shared": "1.19.8" } }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", - "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", + "version": "1.19.8", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.8.tgz", + "integrity": "sha512-ZvJWO8ZZJDpc1LNM2TTBdmQsZBLMR4rU5iNR2OYvEeFBiaf/0ESnRSSLQbryarJY4SVxtoz6A2ZtDMNM+iQEAA==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-shared": "1.19.2" + "@algolia/autocomplete-shared": "1.19.8" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", - "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", + "version": "1.19.8", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.8.tgz", + "integrity": "sha512-h5hf2t8ejF6vlOgvLaZzQbWs5SyH2z4PAWygNAvvD/2RI29hdQ54ldUGwqVuj9Srs+n8XUKTPUqb7fvhBhQrnQ==", "license": "MIT", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -152,100 +83,100 @@ } }, "node_modules/@algolia/client-abtesting": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.2.tgz", - "integrity": "sha512-oRSUHbylGIuxrlzdPA8FPJuwrLLRavOhAmFGgdAvMcX47XsyM+IOGa9tc7/K5SPvBqn4nhppOCEz7BrzOPWc4A==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.52.1.tgz", + "integrity": "sha512-HmXOGBOAOJPounpBzBpuY0zDYeiCpxgHnQmuA7JO6ScukcBdGp3/XM9zJk5pJx/xNGD68mbPGXWpDxGtl6BwDQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-analytics": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.2.tgz", - "integrity": "sha512-EPBN2Oruw0maWOF4OgGPfioTvd+gmiNwx0HmD9IgmlS+l75DatcBkKOPNJN+0z3wBQWUO5oq602ATxIfmTQ8bA==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.52.1.tgz", + "integrity": "sha512-5oo4+I8iixie9vXhCyNFCzeIr8pqA3FQ//VsLHTDvZAV4ttYOPGvYHGQq5NSalrLx5Jc3dRro/5uDOlnUMcBJg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-common": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.2.tgz", - "integrity": "sha512-Hj8gswSJNKZ0oyd0wWissqyasm+wTz1oIsv5ZmLarzOZAp3vFEda8bpDQ8PUhO+DfkbiLyVnAxsPe4cGzWtqkg==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.52.1.tgz", + "integrity": "sha512-qCDoZfx5MpX7XQzvQ3bC4tSEMkQWQMaF/ABtLuoze03Y/flR563CCSws02qIJ23oX7lxl92LsilZjINVyTdtLw==", "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-insights": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.2.tgz", - "integrity": "sha512-6dBZko2jt8FmQcHCbmNLB0kCV079Mx/DJcySTL3wirgDBUH7xhY1pOuUTLMiGkqM5D8moVZTvTdRKZUJRkrwBA==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.52.1.tgz", + "integrity": "sha512-hnGs0/lsFJ2PWDxNBz7pxreXo/Xz7gxYRcfePBUjsH26ad0kU/sgnVZd9LwWBpsQv65z2jlb5dkyaB9WE9M9FQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.2.tgz", - "integrity": "sha512-1waE2Uqh/PHNeDXGn/PM/WrmYOBiUGSVxAWqiJIj73jqPqvfzZgzdakHscIVaDl6Cp+j5dwjsZ5LCgaUr6DtmA==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.52.1.tgz", + "integrity": "sha512-2VxxNc/uBysyKvGeBdSM5n9eIDKH8kWD7wd9/yqbJAiVwU4Yv6tU1LSJusHKrXV/aCu1KW7t9Gug9QyeEmtn/Q==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-query-suggestions": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.2.tgz", - "integrity": "sha512-EgOzTZkyDcNL6DV0V/24+oBJ+hKo0wNgyrOX/mePBM9bc9huHxIY2352sXmoZ648JXXY2x//V1kropF/Spx83w==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.52.1.tgz", + "integrity": "sha512-O6mPtsw3xEfNOe6gWFpYLeAZAIljNa4Hgna3bq15PwyN7nbjTY0wXJFRbzs/0YVf75Br+SbOQUmjKxXYjDiSiQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.2.tgz", - "integrity": "sha512-ZsOJqu4HOG5BlvIFnMU0YKjQ9ZI6r3C31dg2jk5kMWPSdhJpYL9xa5hEe7aieE+707dXeMI4ej3diy6mXdZpgA==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.52.1.tgz", + "integrity": "sha512-gA8oJOV1LnQQkDf91iebNnFInHuW0gRPEgLSOQ7EfipCEjYTHm5swm1DlH9H5RaRw4RrHuzHBegnlzc0MAstcg==", "license": "MIT", "peer": true, "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" @@ -258,93 +189,93 @@ "license": "MIT" }, "node_modules/@algolia/ingestion": { - "version": "1.46.2", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.2.tgz", - "integrity": "sha512-1Uw2OslTWiOFDtt83y0bGiErJYy5MizadV0nHnOoHFWMoDqWW0kQoMFI65pXqRSkVvit5zjXSLik2xMiyQJDWQ==", + "version": "1.52.1", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.52.1.tgz", + "integrity": "sha512-U9zZfc5xIu9wRxZkt+HceJUAD4VKHKbAyLSloJdEyMRmphXeibfrY9cxqIXBcmPeZzGhn3Imb35Dq8l19PkJhw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/monitoring": { - "version": "1.46.2", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.2.tgz", - "integrity": "sha512-xk9f+DPtNcddWN6E7n1hyNNsATBCHIqAvVGG2EAGHJc4AFYL18uM/kMTiOKXE/LKDPyy1JhIerrh9oYb7RBrgw==", + "version": "1.52.1", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.52.1.tgz", + "integrity": "sha512-a3SGNceHmkQfq77iG8Ka+w1pvwfZa/0lzEIgse30fL0kD+yKnd/dg0dQvSfFPAEt2f21DMcGkDSSeJlO3KdQjQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.2.tgz", - "integrity": "sha512-NApbTPj9LxGzNw4dYnZmj2BoXiAc8NmbbH6qBNzQgXklGklt/xldTvu+FACN6ltFsTzoNU6j2mWNlHQTKGC5+Q==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.52.1.tgz", + "integrity": "sha512-z98QEguCFDpxb4S/PyrUK1igqF8tPsdbqOUUO6ON91vJ58w+Gwa6ncrI0oNXSFcrkxA5EqPKPQ2A1PBCn08TYQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/client-common": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.2.tgz", - "integrity": "sha512-ekotpCwpSp033DIIrsTpYlGUCF6momkgupRV/FA3m62SreTSZUKjgK6VTNyG7TtYfq9YFm/pnh65bATP/ZWJEg==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.52.1.tgz", + "integrity": "sha512-CI7+/0I11QeZM59Uc8whd2or0kqzFVjpaPn9Qpwll/krHcBAxk24WkAQ6WX+IwDVMfpont4YGbKwAmCre3vE8Q==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2" + "@algolia/client-common": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-fetch": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.2.tgz", - "integrity": "sha512-gKE+ZFi/6y7saTr34wS0SqYFDcjHW4Wminv8PDZEi0/mE99+hSrbKgJWxo2ztb5eqGirQTgIh1AMVacGGWM1iw==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.52.1.tgz", + "integrity": "sha512-S6bDuw9byfOvm3T71cgdoZgrgnZq6hpdMLkx52Louh57nUAmvGQESz2aojOynQHjbTiV55smvAFbgn0qT4tJrg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2" + "@algolia/client-common": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.2.tgz", - "integrity": "sha512-ciPihkletp7ttweJ8Zt+GukSVLp2ANJHU+9ttiSxsJZThXc4Y2yJ8HGVWesW5jN1zrsZsezN71KrMx/iZsOYpg==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.52.1.tgz", + "integrity": "sha512-tqZXM+54rWo4mk5jL5Z/flE11nPmNEdXwFBM5py9DkOmbjeCNemfVd45FyM97XdzfZ0dl9uOJC6PYn1FpkeyQg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.2" + "@algolia/client-common": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -353,30 +284,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", "peer": true, "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -402,13 +333,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -430,12 +361,12 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", + "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -455,17 +386,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz", + "integrity": "sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.5", + "@babel/traverse": "^7.29.0", "semver": "^6.3.1" }, "engines": { @@ -511,16 +442,16 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" + "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -549,27 +480,27 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -591,9 +522,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -617,14 +548,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -674,39 +605,39 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2" + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -761,6 +692,22 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz", + "integrity": "sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", @@ -779,13 +726,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -819,12 +766,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -834,12 +781,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -849,12 +796,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -864,12 +811,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -910,14 +857,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -927,13 +874,13 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "engines": { @@ -959,12 +906,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -974,13 +921,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -990,13 +937,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1006,17 +953,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1026,13 +973,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1058,13 +1005,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1089,13 +1036,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1120,13 +1067,13 @@ } }, "node_modules/@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1136,12 +1083,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1199,12 +1146,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1229,12 +1176,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1275,13 +1222,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1291,15 +1238,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz", + "integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -1325,13 +1272,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1356,12 +1303,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1371,12 +1318,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1386,16 +1333,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1421,12 +1368,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1436,12 +1383,12 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { @@ -1467,13 +1414,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1483,14 +1430,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1545,16 +1492,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", - "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz", + "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-syntax-jsx": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1595,12 +1542,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1610,13 +1557,13 @@ } }, "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1641,13 +1588,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", - "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.0.tgz", + "integrity": "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", @@ -1685,12 +1632,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { @@ -1746,16 +1693,16 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", - "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz", + "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" + "@babel/plugin-syntax-typescript": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1780,13 +1727,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1812,13 +1759,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1828,80 +1775,81 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", - "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", + "version": "7.29.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.5.tgz", + "integrity": "sha512-/69t2aEzGKHD76DyLbHysF/QH2LJOB8iFnYO37unDTKBTubzcMRv0f3H5EiN1Q6ajOd/eB7dAInF0qdFVS06kA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/compat-data": "^7.29.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.28.0", - "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.29.0", + "@babel/plugin-transform-async-to-generator": "^7.28.6", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.5", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.4", - "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-dotall-regex": "^7.28.6", "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.28.5", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.29.4", "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.4", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.28.5", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.4", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.29.0", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "core-js-compat": "^3.43.0", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", "semver": "^6.3.1" }, "engines": { @@ -1911,6 +1859,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -1982,44 +1943,32 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz", - "integrity": "sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==", - "license": "MIT", - "dependencies": { - "core-js-pure": "^3.43.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -2027,9 +1976,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -2947,9 +2896,9 @@ } }, "node_modules/@csstools/postcss-normalize-display-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz", - "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.1.tgz", + "integrity": "sha512-TQUGBuRvxdc7TgNSTevYqrL8oItxiwPDixk20qCB5me/W8uF7BPbhRrAvFuhEoywQp/woRsUZ6SJ+sU5idZAIA==", "funding": [ { "type": "github", @@ -3379,9 +3328,9 @@ } }, "node_modules/@docsearch/core": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.4.0.tgz", - "integrity": "sha512-kiwNo5KEndOnrf5Kq/e5+D9NBMCFgNsDoRpKQJ9o/xnSlheh6b8AXppMuuUVVdAUIhIfQFk/07VLjjk/fYyKmw==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.6.3.tgz", + "integrity": "sha512-rUOujwIpxJRgD7+kicVsI3D5sqBvdiRTquzWBpTEXZs8ZXfGbfzpus5HqumaNYTppN2HvH8E2yNuRwYdHJeOlA==", "license": "MIT", "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", @@ -3401,25 +3350,20 @@ } }, "node_modules/@docsearch/css": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.4.0.tgz", - "integrity": "sha512-e9vPgtih6fkawakmYo0Y6V4BKBmDV7Ykudn7ADWXUs5b6pmtBRwDbpSG/WiaUG63G28OkJDEnsMvgIAnZgGwYw==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.6.3.tgz", + "integrity": "sha512-nlOwcXcsNAptQl4vlL4MA78qNJKO0Qlds5GuBjCoePgkebTXLSf8Qt1oyZ3YBshYupKXG9VRGEsk1zr23d+bzQ==", "license": "MIT" }, "node_modules/@docsearch/react": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.4.0.tgz", - "integrity": "sha512-z12zeg1mV7WD4Ag4pKSuGukETJLaucVFwszDXL/qLaEgRqxEaVacO9SR1qqnCXvZztlvz2rt7cMqryi/7sKfjA==", + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.6.3.tgz", + "integrity": "sha512-Bg2wdDsoQVlNCcEKuEJAU04tvHCqgx8rIu+uIoM4pRtcx3TBKJuXutJik3LTA8LRc9YEyHkrYUrmcC0D7BYf+g==", "license": "MIT", "dependencies": { - "@ai-sdk/react": "^2.0.30", "@algolia/autocomplete-core": "1.19.2", - "@docsearch/core": "4.4.0", - "@docsearch/css": "4.4.0", - "ai": "^5.0.30", - "algoliasearch": "^5.28.0", - "marked": "^16.3.0", - "zod": "^4.1.8" + "@docsearch/core": "4.6.3", + "@docsearch/css": "4.6.3" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", @@ -3442,10 +3386,42 @@ } } }, + "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-core": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", + "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", + "@algolia/autocomplete-shared": "1.19.2" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", + "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.19.2" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-shared": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", + "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, "node_modules/@docusaurus/babel": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.9.2.tgz", - "integrity": "sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.10.1.tgz", + "integrity": "sha512-DZzFO1K3v/GoEt1fx1DiYHF4en+PuhtQf1AkQJa5zu3CoeKSpr5cpQRUlz3jr0m44wyzmSXu9bVpfir+N4+8bg==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", @@ -3456,10 +3432,9 @@ "@babel/preset-react": "^7.25.9", "@babel/preset-typescript": "^7.25.9", "@babel/runtime": "^7.25.9", - "@babel/runtime-corejs3": "^7.25.9", "@babel/traverse": "^7.25.9", - "@docusaurus/logger": "3.9.2", - "@docusaurus/utils": "3.9.2", + "@docusaurus/logger": "3.10.1", + "@docusaurus/utils": "3.10.1", "babel-plugin-dynamic-import-node": "^2.3.3", "fs-extra": "^11.1.1", "tslib": "^2.6.0" @@ -3469,17 +3444,17 @@ } }, "node_modules/@docusaurus/bundler": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.9.2.tgz", - "integrity": "sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.10.1.tgz", + "integrity": "sha512-HIqQPvbqnnQRe4NsBd1774KRarjXqS6wHsWELtyuSs1gCfvixJO2jUGH/OEBtr1Gvzpw+ze5CjGMvSJ8UE1KUw==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", - "@docusaurus/babel": "3.9.2", - "@docusaurus/cssnano-preset": "3.9.2", - "@docusaurus/logger": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", + "@docusaurus/babel": "3.10.1", + "@docusaurus/cssnano-preset": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", "babel-loader": "^9.2.1", "clean-css": "^5.3.3", "copy-webpack-plugin": "^11.0.0", @@ -3497,7 +3472,7 @@ "tslib": "^2.6.0", "url-loader": "^4.1.1", "webpack": "^5.95.0", - "webpackbar": "^6.0.1" + "webpackbar": "^7.0.0" }, "engines": { "node": ">=20.0" @@ -3512,19 +3487,19 @@ } }, "node_modules/@docusaurus/core": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.9.2.tgz", - "integrity": "sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.10.1.tgz", + "integrity": "sha512-3pf2fXXw0eVk8WnC3T4LIigRDupcpvngpKo9Vy7mYyBhuddc0klDUuZAIfzMoK6z05pdlk6EFC/vBSX43+1O5w==", "license": "MIT", "peer": true, "dependencies": { - "@docusaurus/babel": "3.9.2", - "@docusaurus/bundler": "3.9.2", - "@docusaurus/logger": "3.9.2", - "@docusaurus/mdx-loader": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-common": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/babel": "3.10.1", + "@docusaurus/bundler": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/mdx-loader": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "boxen": "^6.2.1", "chalk": "^4.1.2", "chokidar": "^3.5.3", @@ -3536,7 +3511,7 @@ "escape-html": "^1.0.3", "eta": "^2.2.0", "eval": "^0.1.8", - "execa": "5.1.1", + "execa": "^5.1.1", "fs-extra": "^11.1.1", "html-tags": "^3.3.1", "html-webpack-plugin": "^5.6.0", @@ -3547,12 +3522,12 @@ "prompts": "^2.4.2", "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-loadable-ssr-addon-v5-slorber": "^1.0.3", "react-router": "^5.3.4", "react-router-config": "^5.1.1", "react-router-dom": "^5.3.4", "semver": "^7.5.4", - "serve-handler": "^6.1.6", + "serve-handler": "^6.1.7", "tinypool": "^1.0.2", "tslib": "^2.6.0", "update-notifier": "^6.0.2", @@ -3568,15 +3543,21 @@ "node": ">=20.0" }, "peerDependencies": { + "@docusaurus/faster": "*", "@mdx-js/react": "^3.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } } }, "node_modules/@docusaurus/cssnano-preset": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.9.2.tgz", - "integrity": "sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.10.1.tgz", + "integrity": "sha512-eNfHGcTKCSq6xmcavAkX3RRclHaE2xRCMParlDXLdXVP01/a2e/jKXMj/0ULnLFQSNwwuI62L0Ge8J+nZsR7UQ==", "license": "MIT", "dependencies": { "cssnano-preset-advanced": "^6.1.2", @@ -3589,9 +3570,9 @@ } }, "node_modules/@docusaurus/eslint-plugin": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/eslint-plugin/-/eslint-plugin-3.9.2.tgz", - "integrity": "sha512-LnCrmrR4EtzpSiq6aoSfiY0Lf8P0WslGbBFZJ0olKXJIMxey8dpKevT1K/+tN87Lbn2H/VrdGGSPGlfVKmihAQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/eslint-plugin/-/eslint-plugin-3.10.1.tgz", + "integrity": "sha512-GS0zphpvFMCHUWalNrklew1gJo/44YzCrHPNFoka0asJnjfgnQDLl+KxCjWUXvw3U34NaVhwlJQaieClez8o/A==", "dev": true, "license": "MIT", "dependencies": { @@ -3632,10 +3613,36 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/@docusaurus/faster": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/faster/-/faster-3.10.1.tgz", + "integrity": "sha512-XTZhE5C1gZ/DaYYMlSk02dwP5vhpQON5QHVz1s3892mSESAywgWanURpXEDAvt4GvGuq7s+XP8rTWHZvfaJmdQ==", + "devOptional": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@docusaurus/types": "3.10.1", + "@rspack/core": "^1.7.10", + "@swc/core": "^1.7.39", + "@swc/html": "^1.13.5", + "browserslist": "^4.24.2", + "lightningcss": "^1.27.0", + "semver": "^7.5.4", + "swc-loader": "^0.2.6", + "tslib": "^2.6.0", + "webpack": "^5.95.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + } + }, "node_modules/@docusaurus/logger": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.9.2.tgz", - "integrity": "sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.10.1.tgz", + "integrity": "sha512-oPjNFnfJsRCkePVjkGrxWGq4MvJKRQT0r9jOP0eRBTZ7Wr9FAbzdP/Gjs0I2Ss6YRkPoEgygKG112OkE6skvJw==", "license": "MIT", "dependencies": { "chalk": "^4.1.2", @@ -3646,14 +3653,14 @@ } }, "node_modules/@docusaurus/mdx-loader": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz", - "integrity": "sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.10.1.tgz", + "integrity": "sha512-GRmeb/wQ+iXRrFwcHBfgQhrJxGElgCsoTWZYDhccjsZVne1p8MK/EpQVIloXttz76TCe78kKD5AEG9n1xc1oxQ==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/logger": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "@mdx-js/mdx": "^3.0.0", "@slorber/remark-comment": "^1.0.0", "escape-html": "^1.0.3", @@ -3685,12 +3692,12 @@ } }, "node_modules/@docusaurus/module-type-aliases": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz", - "integrity": "sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.10.1.tgz", + "integrity": "sha512-YoOZKUdGlp8xSYhuAkGdSo5Ydkbq4V4eK3sD8v0a2hloxCWdQbNBhkc+Ko9QyjpESc0BYcIGM5iHVAy5hdFV6w==", "license": "MIT", "dependencies": { - "@docusaurus/types": "3.9.2", + "@docusaurus/types": "3.10.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -3704,20 +3711,21 @@ } }, "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz", - "integrity": "sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/logger": "3.9.2", - "@docusaurus/mdx-loader": "3.9.2", - "@docusaurus/theme-common": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-common": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.10.1.tgz", + "integrity": "sha512-mmkgE6Q2+K74tnkou7tXlpDLvoCU/qkSa2GSQ3XUiHWvcebCoDQzS670RR3tO8PmaWlIyWWISYWzZLuMfxunRA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/mdx-loader": "3.10.1", + "@docusaurus/theme-common": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "cheerio": "1.0.0-rc.12", + "combine-promises": "^1.1.0", "feed": "^4.2.2", "fs-extra": "^11.1.1", "lodash": "^4.17.21", @@ -3738,21 +3746,21 @@ } }, "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", - "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.1.tgz", + "integrity": "sha512-2jRVrtzjf8LClGTHQlwlwuD3wQXRx3WEoF7XUarJ8Ou+0onV+SLtejsyfY9JLpfUh9hPhXM4pbBGkyAY4Bi3HQ==", "license": "MIT", "peer": true, "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/logger": "3.9.2", - "@docusaurus/mdx-loader": "3.9.2", - "@docusaurus/module-type-aliases": "3.9.2", - "@docusaurus/theme-common": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-common": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/mdx-loader": "3.10.1", + "@docusaurus/module-type-aliases": "3.10.1", + "@docusaurus/theme-common": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "@types/react-router-config": "^5.0.7", "combine-promises": "^1.1.0", "fs-extra": "^11.1.1", @@ -3772,16 +3780,16 @@ } }, "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.9.2.tgz", - "integrity": "sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.10.1.tgz", + "integrity": "sha512-huJpaRPMl42nsFwuCXvV8bVDj2MazuwRJIUylI/RSlmZeJssVoZXeCjVf1y+1Drtpa9SKcdGn8yoJ76IRJijtw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/mdx-loader": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/mdx-loader": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "fs-extra": "^11.1.1", "tslib": "^2.6.0", "webpack": "^5.88.1" @@ -3795,15 +3803,15 @@ } }, "node_modules/@docusaurus/plugin-css-cascade-layers": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.9.2.tgz", - "integrity": "sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.10.1.tgz", + "integrity": "sha512-r//fn+MNHkE1wCof8T29VAQezt1enGCpsFxoziBbvLgBM4JfXN2P3rxrBaavHmvLvm7lYkpJeitcDthwnmWCTw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "tslib": "^2.6.0" }, "engines": { @@ -3811,14 +3819,14 @@ } }, "node_modules/@docusaurus/plugin-debug": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.9.2.tgz", - "integrity": "sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.10.1.tgz", + "integrity": "sha512-9KqOpKNfAyqGZykRb9LhIT/vyRF6sm/ykhjj/39JvaJahDS+jZJE0Z1Wfz9q3DUNDTMNN0Q7u/kk4rKKU+IJuA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", "fs-extra": "^11.1.1", "react-json-view-lite": "^2.3.0", "tslib": "^2.6.0" @@ -3832,14 +3840,14 @@ } }, "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz", - "integrity": "sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.10.1.tgz", + "integrity": "sha512-8o0P1KtmgdYQHH+oInitPpRWI0Of5XednAX4+DMhQNSmGSRNrsEEHg1ebv35m9AgRClfAytCJ5jA9KvcASTyuA==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "tslib": "^2.6.0" }, "engines": { @@ -3851,15 +3859,15 @@ } }, "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.9.2.tgz", - "integrity": "sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.10.1.tgz", + "integrity": "sha512-pu3xIUo5o/zCMLfUY9BO5KOwSH0zIsAGyFRPvXHayFSA5XIhCU/SFuB0g0ZNjFn9niZLCaNvoeAuOGFJZq0fdw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", - "@types/gtag.js": "^0.0.12", + "@docusaurus/core": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", + "@types/gtag.js": "^0.0.20", "tslib": "^2.6.0" }, "engines": { @@ -3871,14 +3879,14 @@ } }, "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.9.2.tgz", - "integrity": "sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.10.1.tgz", + "integrity": "sha512-f6fyGHiCm7kJHBtAisGQS5oNBnpnMTYQZxDXeVrnw/3zWU+LMA22pr6UHGYkBKDbN+qPC5QHG3NuOfzQLq3+Lw==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "tslib": "^2.6.0" }, "engines": { @@ -3890,17 +3898,17 @@ } }, "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz", - "integrity": "sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.10.1.tgz", + "integrity": "sha512-C26MbmmqgdjkDq1htaZ3aD7LzEDKFWXfpyQpt0EOUThuq5nV77zDaedV20yHcVo9p+3ey9aZ4pbHA0D3QcZTzg==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/logger": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-common": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "fs-extra": "^11.1.1", "sitemap": "^7.1.1", "tslib": "^2.6.0" @@ -3914,15 +3922,15 @@ } }, "node_modules/@docusaurus/plugin-svgr": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.9.2.tgz", - "integrity": "sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.10.1.tgz", + "integrity": "sha512-6SFxsmjWFkVLDmBUvFK6i72QjUwqyQFe4Ovz+SUJophJjOyVG3ZZG5IQpBC/kX/Gfv1yWeU9nWauH6F6Q7QX/Q==", "license": "MIT", "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "@svgr/core": "8.1.0", "@svgr/webpack": "^8.1.0", "tslib": "^2.6.0", @@ -3937,26 +3945,26 @@ } }, "node_modules/@docusaurus/preset-classic": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.9.2.tgz", - "integrity": "sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/plugin-content-blog": "3.9.2", - "@docusaurus/plugin-content-docs": "3.9.2", - "@docusaurus/plugin-content-pages": "3.9.2", - "@docusaurus/plugin-css-cascade-layers": "3.9.2", - "@docusaurus/plugin-debug": "3.9.2", - "@docusaurus/plugin-google-analytics": "3.9.2", - "@docusaurus/plugin-google-gtag": "3.9.2", - "@docusaurus/plugin-google-tag-manager": "3.9.2", - "@docusaurus/plugin-sitemap": "3.9.2", - "@docusaurus/plugin-svgr": "3.9.2", - "@docusaurus/theme-classic": "3.9.2", - "@docusaurus/theme-common": "3.9.2", - "@docusaurus/theme-search-algolia": "3.9.2", - "@docusaurus/types": "3.9.2" + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.10.1.tgz", + "integrity": "sha512-YO/FL8v1zmbxoTso6mjMz/RDjhaTJxb1UpFFTDdY5847LLDCeyYiYlrhyTbgN1RIN3xnkLKZ9Lj1x8hUzI4JOg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.1", + "@docusaurus/plugin-content-blog": "3.10.1", + "@docusaurus/plugin-content-docs": "3.10.1", + "@docusaurus/plugin-content-pages": "3.10.1", + "@docusaurus/plugin-css-cascade-layers": "3.10.1", + "@docusaurus/plugin-debug": "3.10.1", + "@docusaurus/plugin-google-analytics": "3.10.1", + "@docusaurus/plugin-google-gtag": "3.10.1", + "@docusaurus/plugin-google-tag-manager": "3.10.1", + "@docusaurus/plugin-sitemap": "3.10.1", + "@docusaurus/plugin-svgr": "3.10.1", + "@docusaurus/theme-classic": "3.10.1", + "@docusaurus/theme-common": "3.10.1", + "@docusaurus/theme-search-algolia": "3.10.1", + "@docusaurus/types": "3.10.1" }, "engines": { "node": ">=20.0" @@ -3967,26 +3975,27 @@ } }, "node_modules/@docusaurus/theme-classic": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz", - "integrity": "sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/logger": "3.9.2", - "@docusaurus/mdx-loader": "3.9.2", - "@docusaurus/module-type-aliases": "3.9.2", - "@docusaurus/plugin-content-blog": "3.9.2", - "@docusaurus/plugin-content-docs": "3.9.2", - "@docusaurus/plugin-content-pages": "3.9.2", - "@docusaurus/theme-common": "3.9.2", - "@docusaurus/theme-translations": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-common": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.10.1.tgz", + "integrity": "sha512-VU1RK0qb2pab0si4r7HFK37cYco8VzqLj3u1PspVipSr/z/GPVKHO4/HXbnePqHoWDk8urjyGSeatH0NIMBM1A==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/mdx-loader": "3.10.1", + "@docusaurus/module-type-aliases": "3.10.1", + "@docusaurus/plugin-content-blog": "3.10.1", + "@docusaurus/plugin-content-docs": "3.10.1", + "@docusaurus/plugin-content-pages": "3.10.1", + "@docusaurus/theme-common": "3.10.1", + "@docusaurus/theme-translations": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", "infima": "0.2.0-alpha.45", "lodash": "^4.17.21", "nprogress": "^0.2.0", @@ -4007,15 +4016,15 @@ } }, "node_modules/@docusaurus/theme-common": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz", - "integrity": "sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.10.1.tgz", + "integrity": "sha512-0YtmIeoNo1fIw65LO8+/1dPgmDV86UmhMkow37gzjytuiCSQm9xob6PJy0L4kuQEMTLfUOGvkXvZr7GPrHquMA==", "license": "MIT", "dependencies": { - "@docusaurus/mdx-loader": "3.9.2", - "@docusaurus/module-type-aliases": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-common": "3.9.2", + "@docusaurus/mdx-loader": "3.10.1", + "@docusaurus/module-type-aliases": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", @@ -4035,19 +4044,20 @@ } }, "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz", - "integrity": "sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==", - "license": "MIT", - "dependencies": { - "@docsearch/react": "^3.9.0 || ^4.1.0", - "@docusaurus/core": "3.9.2", - "@docusaurus/logger": "3.9.2", - "@docusaurus/plugin-content-docs": "3.9.2", - "@docusaurus/theme-common": "3.9.2", - "@docusaurus/theme-translations": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-validation": "3.9.2", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.10.1.tgz", + "integrity": "sha512-OTaARARVZj2GvkJQjB+1jOIxntRaXea+G+fMsNqrZBAU1O1vJKDW22R7kECOHW27oJCLFN9HKaZeRrfAUyviug==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-core": "^1.19.2", + "@docsearch/react": "^3.9.0 || ^4.3.2", + "@docusaurus/core": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/plugin-content-docs": "3.10.1", + "@docusaurus/theme-common": "3.10.1", + "@docusaurus/theme-translations": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", "algoliasearch": "^5.37.0", "algoliasearch-helper": "^3.26.0", "clsx": "^2.0.0", @@ -4066,9 +4076,9 @@ } }, "node_modules/@docusaurus/theme-translations": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz", - "integrity": "sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.10.1.tgz", + "integrity": "sha512-cLMyaKivjBVWKMJuWqyFVVgtqe8DPJNPkog0bn8W1MDVAKcPdxRFycBfC1We1RaNp7Rdk513bmtW78RR6OBxBw==", "license": "MIT", "dependencies": { "fs-extra": "^11.1.1", @@ -4079,16 +4089,16 @@ } }, "node_modules/@docusaurus/tsconfig": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.9.2.tgz", - "integrity": "sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.10.1.tgz", + "integrity": "sha512-rYvB7yqkdqWIpAbDzQljGfM4cDBkLTbhmagZBEcsyj6oPUsz47lmW2pYdN1j+7sGFgltbAmQH62xfbrij4Eh6Q==", "dev": true, "license": "MIT" }, "node_modules/@docusaurus/types": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.9.2.tgz", - "integrity": "sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.10.1.tgz", + "integrity": "sha512-XYMK8k1szDCFMw2V+Xyen0g7Kee1sP3dtFnl7vkGkZOkeAJ/oPDQPL8iz4HBKOo/cwU8QeV6onVjMqtP+tFzsw==", "license": "MIT", "dependencies": { "@mdx-js/mdx": "^3.0.0", @@ -4122,16 +4132,16 @@ } }, "node_modules/@docusaurus/utils": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.9.2.tgz", - "integrity": "sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.10.1.tgz", + "integrity": "sha512-3ojeJry9xBYdJO6qoyyzqeJFSJBVx2mXhyDzSdjwL2+URFQMf+h25gG38iswGImicK0ELjTd1EL2xzk8hf3QPw==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.9.2", - "@docusaurus/types": "3.9.2", - "@docusaurus/utils-common": "3.9.2", + "@docusaurus/logger": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils-common": "3.10.1", "escape-string-regexp": "^4.0.0", - "execa": "5.1.1", + "execa": "^5.1.1", "file-loader": "^6.2.0", "fs-extra": "^11.1.1", "github-slugger": "^1.5.0", @@ -4154,12 +4164,12 @@ } }, "node_modules/@docusaurus/utils-common": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.9.2.tgz", - "integrity": "sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.10.1.tgz", + "integrity": "sha512-5mFSgEADtnFxFH7RLw02QA5MpU5JVUCj0MPeIvi/aF4Fi45tQRIuTwXoXDqJ+1VfQJuYJGz3SI63wmGz4HvXzA==", "license": "MIT", "dependencies": { - "@docusaurus/types": "3.9.2", + "@docusaurus/types": "3.10.1", "tslib": "^2.6.0" }, "engines": { @@ -4167,14 +4177,14 @@ } }, "node_modules/@docusaurus/utils-validation": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz", - "integrity": "sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.10.1.tgz", + "integrity": "sha512-cRv1X69jwaWv47waglllgZVWzeBFLhl53XT/XED/83BerVBTC5FTP8WTcVl8Z6sZOegDSwitu/wpCSPCDOT6lg==", "license": "MIT", "dependencies": { - "@docusaurus/logger": "3.9.2", - "@docusaurus/utils": "3.9.2", - "@docusaurus/utils-common": "3.9.2", + "@docusaurus/logger": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", "fs-extra": "^11.2.0", "joi": "^17.9.2", "js-yaml": "^4.1.0", @@ -4185,20 +4195,54 @@ "node": ">=20.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" @@ -4726,6 +4770,78 @@ "react": ">=16" } }, + "node_modules/@module-federation/error-codes": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz", + "integrity": "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@module-federation/runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz", + "integrity": "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/runtime-core": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-core": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz", + "integrity": "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz", + "integrity": "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/webpack-bundler-runtime": "0.22.0" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz", + "integrity": "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz", + "integrity": "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", + "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@tybys/wasm-util": "^0.10.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4991,15 +5107,6 @@ "node": "^16.13.0 || >=18.0.0" } }, - "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -5071,6 +5178,196 @@ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "license": "MIT" }, + "node_modules/@rspack/binding": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.7.11.tgz", + "integrity": "sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q==", + "devOptional": true, + "license": "MIT", + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.7.11", + "@rspack/binding-darwin-x64": "1.7.11", + "@rspack/binding-linux-arm64-gnu": "1.7.11", + "@rspack/binding-linux-arm64-musl": "1.7.11", + "@rspack/binding-linux-x64-gnu": "1.7.11", + "@rspack/binding-linux-x64-musl": "1.7.11", + "@rspack/binding-wasm32-wasi": "1.7.11", + "@rspack/binding-win32-arm64-msvc": "1.7.11", + "@rspack/binding-win32-ia32-msvc": "1.7.11", + "@rspack/binding-win32-x64-msvc": "1.7.11" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.7.11.tgz", + "integrity": "sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.7.11.tgz", + "integrity": "sha512-a1+TtTE9ap6RalgFi7FGIgkJP6O4Vy6ctv+9WGJy53E4kuqHR0RygzaiVxCI/GMc/vBT9vY23hyrpWb3d1vtXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.7.11.tgz", + "integrity": "sha512-P0QrGRPbTWu6RKWfN0bDtbnEps3rXH0MWIMreZABoUrVmNQKtXR6e73J3ub6a+di5s2+K0M2LJ9Bh2/H4UsDUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.7.11.tgz", + "integrity": "sha512-6ky7R43VMjWwmx3Yx7Jl7faLBBMAgMDt+/bN35RgwjiPgsIByz65EwytUVuW9rikB43BGHvA/eqlnjLrUzNBqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.7.11.tgz", + "integrity": "sha512-cuOJMfCOvb2Wgsry5enXJ3iT1FGUjdPqtGUBVupQlEG4ntSYsQ2PtF4wIDVasR3wdxC5nQbipOrDiN/u6fYsdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.7.11.tgz", + "integrity": "sha512-CoK37hva4AmHGh3VCsQXmGr40L36m1/AdnN5LEjUX6kx5rEH7/1nEBN6Ii72pejqDVvk9anEROmPDiPw10tpFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-wasm32-wasi": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.7.11.tgz", + "integrity": "sha512-OtrmnPUVJMxjNa3eDMfHyPdtlLRmmp/aIm0fQHlAOATbZvlGm12q7rhPW5BXTu1yh+1rQ1/uqvz+SzKEZXuJaQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "1.0.7" + } + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.7.11.tgz", + "integrity": "sha512-lObFW6e5lCWNgTBNwT//yiEDbsxm9QG4BYUojqeXxothuzJ/L6ibXz6+gLMvbOvLGV3nKgkXmx8GvT9WDKR0mA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.7.11.tgz", + "integrity": "sha512-0pYGnZd8PPqNR68zQ8skamqNAXEA1sUfXuAdYcknIIRq2wsbiwFzIc0Pov1cIfHYab37G7sSIPBiOUdOWF5Ivw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.7.11.tgz", + "integrity": "sha512-EeQXayoQk/uBkI3pdoXfQBXNIUrADq56L3s/DFyM2pJeUDrWmhfIw2UFIGkYPTMSCo8F2JcdcGM32FGJrSnU0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.7.11.tgz", + "integrity": "sha512-rsD9b+Khmot5DwCMiB3cqTQo53ioPG3M/A7BySu8+0+RS7GCxKm+Z+mtsjtG/vsu4Tn2tcqCdZtA3pgLoJB+ew==", + "devOptional": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@module-federation/runtime-tools": "0.22.0", + "@rspack/binding": "1.7.11", + "@rspack/lite-tapable": "1.1.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.1.0.tgz", + "integrity": "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==", + "devOptional": true, + "license": "MIT" + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -5133,9 +5430,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", "license": "MIT" }, "node_modules/@sindresorhus/is": { @@ -5161,12 +5458,6 @@ "micromark-util-symbol": "^1.0.1" } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "license": "MIT" - }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", @@ -5295,134 +5586,628 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "license": "MIT", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@swc/core": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.33.tgz", + "integrity": "sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.26" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.33", + "@swc/core-darwin-x64": "1.15.33", + "@swc/core-linux-arm-gnueabihf": "1.15.33", + "@swc/core-linux-arm64-gnu": "1.15.33", + "@swc/core-linux-arm64-musl": "1.15.33", + "@swc/core-linux-ppc64-gnu": "1.15.33", + "@swc/core-linux-s390x-gnu": "1.15.33", + "@swc/core-linux-x64-gnu": "1.15.33", + "@swc/core-linux-x64-musl": "1.15.33", + "@swc/core-win32-arm64-msvc": "1.15.33", + "@swc/core-win32-ia32-msvc": "1.15.33", + "@swc/core-win32-x64-msvc": "1.15.33" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.33.tgz", + "integrity": "sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.33.tgz", + "integrity": "sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.33.tgz", + "integrity": "sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.33.tgz", + "integrity": "sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.33.tgz", + "integrity": "sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.33.tgz", + "integrity": "sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.33.tgz", + "integrity": "sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.33.tgz", + "integrity": "sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.33.tgz", + "integrity": "sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.33.tgz", + "integrity": "sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.33.tgz", + "integrity": "sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.33.tgz", + "integrity": "sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/html": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html/-/html-1.15.33.tgz", + "integrity": "sha512-PZIfmj5zYpAJ2eMptf0My2q9Bl8bkraW28+FD1pRnxOiYMrKrP5vL2tB2PdxMRjS0ziLFVM5HEuGFw8PxEDOaw==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@swc/html-darwin-arm64": "1.15.33", + "@swc/html-darwin-x64": "1.15.33", + "@swc/html-linux-arm-gnueabihf": "1.15.33", + "@swc/html-linux-arm64-gnu": "1.15.33", + "@swc/html-linux-arm64-musl": "1.15.33", + "@swc/html-linux-ppc64-gnu": "1.15.33", + "@swc/html-linux-s390x-gnu": "1.15.33", + "@swc/html-linux-x64-gnu": "1.15.33", + "@swc/html-linux-x64-musl": "1.15.33", + "@swc/html-win32-arm64-msvc": "1.15.33", + "@swc/html-win32-ia32-msvc": "1.15.33", + "@swc/html-win32-x64-msvc": "1.15.33" + } + }, + "node_modules/@swc/html-darwin-arm64": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-darwin-arm64/-/html-darwin-arm64-1.15.33.tgz", + "integrity": "sha512-zyO6uMBfLyCh55wundAxKX+8P/f98ecuyir4VX6nTmn6y7x37ndB8f01LUrd9Tiq6eEAvDXLiqEUvuGjEc7Pmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-darwin-x64": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-darwin-x64/-/html-darwin-x64-1.15.33.tgz", + "integrity": "sha512-MaGunsY/J5l7Rb5OmoztEWh+ikooydT7nWkjiDovj7UfkB9HLk5sLr9O7ZdNGJ2u9dD6FX89SzMdA0Psm9NJrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-arm-gnueabihf": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-linux-arm-gnueabihf/-/html-linux-arm-gnueabihf-1.15.33.tgz", + "integrity": "sha512-CrbUDjVl6/hQ1C5KPMiK4vxk/eOMjxkVELqwnOxsZ+aFVTv3L3YrGMaJ5H47vvIihkPhqiSOUPmMEFqxvqKmXg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-arm64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.15.33.tgz", + "integrity": "sha512-7tZ0IgmUslI9Extu/TpxJS0GjJoDx0j9zeq2cIidPdM/njSBpyRB7n4B292Q5WFVh7PcZl7WXqqqMczibQ27aA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-arm64-musl": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-linux-arm64-musl/-/html-linux-arm64-musl-1.15.33.tgz", + "integrity": "sha512-gYi2ainYZV2z+jwjp9UKuPVOf3c5q+NkH3QRDjqDrIPLagqDsYNjobi8p5oajGcPGFLNTcVw08VTcubJGChReA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-ppc64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-linux-ppc64-gnu/-/html-linux-ppc64-gnu-1.15.33.tgz", + "integrity": "sha512-6CfzyVQSdD8ezFdxFve4J/b6qTgXIwYFWEvSdaJvXSgwTy976uUV5Ff1LOF86mt2zWMhZJX9DqmkGyIhepbyWw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-s390x-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-linux-s390x-gnu/-/html-linux-s390x-gnu-1.15.33.tgz", + "integrity": "sha512-Msx1eniw95lhMHUSe3D5FXweKHtkHtzJLsHJDj920uL4Dm7UHqzwaCuZdCmzbkHnO96YjjQvAm266djg8wupmQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-x64-gnu": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.15.33.tgz", + "integrity": "sha512-JDNb4Uq+7g+23QuOtwWnP0/EqztWIHFFdQdeBIS5zx83YBG2dYRMdPAjnHJWh2YRZxdepd8q6S9MUIxpSrouAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10" } }, - "node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, + "node_modules/@swc/html-linux-x64-musl": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-linux-x64-musl/-/html-linux-x64-musl-1.15.33.tgz", + "integrity": "sha512-NSpZdbz4dj0pu1A0Z9l68Bll5HAzEMtBAeMe6jc4GEVfpIw6eeafQHm2/yMUEh09tgl8t9LzM9DycfdTZDjM4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=10" } }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, + "node_modules/@swc/html-win32-arm64-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-win32-arm64-msvc/-/html-win32-arm64-msvc-1.15.33.tgz", + "integrity": "sha512-w7iho3/zS3lCDqgUZMDLMBO0ElX7j+KgvMb8BOrKqLDOSTDDj3lY/BClNJ7vBpAliI2kPQs/mUikdZyzi4MBjQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=10" } }, - "node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, + "node_modules/@swc/html-win32-ia32-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-win32-ia32-msvc/-/html-win32-ia32-msvc-1.15.33.tgz", + "integrity": "sha512-6hJ2pBweSfZ38trYHXmzTBDpRNvqJgFl2PkIWdy4IXbV/Fv0v9Dqe0t9Gi2ZVEBpgI7PD6pF42AT4HmrNTVFyQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" + "node": ">=10" } }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, + "node_modules/@swc/html-win32-x64-msvc": { + "version": "1.15.33", + "resolved": "https://registry.npmjs.org/@swc/html-win32-x64-msvc/-/html-win32-x64-msvc-1.15.33.tgz", + "integrity": "sha512-eaY/vNE7rkPKluJYjhOiQOA1tto5VbJOoD1C1xFTBmr9t7WsqYUfbQhYQy5A26/z83NNgtDwELM85rkMB+/vWA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" + "node": ">=10" } }, - "node_modules/@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "license": "MIT", + "node_modules/@swc/types": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz", + "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==", + "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "@swc/counter": "^0.1.3" } }, "node_modules/@szmarczak/http-timer": { @@ -5437,13 +6222,15 @@ "node": ">=14.16" } }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "license": "ISC", - "engines": { - "node": ">=10.13.0" + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" } }, "node_modules/@types/body-parser": { @@ -5564,9 +6351,9 @@ } }, "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.20.tgz", + "integrity": "sha512-wwAbk3SA2QeU67unN7zPxjEHmPmlXwZXZvQEpbEUQuMCRGgKyE1m6XDuTUA9b6pCGb/GqJmdfMOY5LuDjJSbbg==", "license": "MIT" }, "node_modules/@types/hast": { @@ -6468,15 +7255,6 @@ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, - "node_modules/@vercel/oidc": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.5.tgz", - "integrity": "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==", - "license": "Apache-2.0", - "engines": { - "node": ">= 20" - } - }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -6756,24 +7534,6 @@ "node": ">=8" } }, - "node_modules/ai": { - "version": "5.0.118", - "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.118.tgz", - "integrity": "sha512-sKJHfhJkvAyq5NC3yJJ4R8Z3tn4pSHF760/jInKAtmLwPLWTHfGo293DSO4un8QUAgJOagHd09VSXOXv+STMNQ==", - "license": "Apache-2.0", - "dependencies": { - "@ai-sdk/gateway": "2.0.24", - "@ai-sdk/provider": "2.0.1", - "@ai-sdk/provider-utils": "3.0.20", - "@opentelemetry/api": "1.9.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "zod": "^3.25.76 || ^4.1.8" - } - }, "node_modules/ajv": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", @@ -6821,35 +7581,35 @@ } }, "node_modules/algoliasearch": { - "version": "5.46.2", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.2.tgz", - "integrity": "sha512-qqAXW9QvKf2tTyhpDA4qXv1IfBwD2eduSW6tUEBFIfCeE9gn9HQ9I5+MaKoenRuHrzk5sQoNh1/iof8mY7uD6Q==", + "version": "5.52.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.52.1.tgz", + "integrity": "sha512-fHA8+kXTbjagw3jkLiaS7KKrH8qe2DyOsiUhGlN4cdT77PEsfqXZl7ewDk1hsg+pJnPlnE50XtLxjR91iJOpmg==", "license": "MIT", "peer": true, "dependencies": { - "@algolia/abtesting": "1.12.2", - "@algolia/client-abtesting": "5.46.2", - "@algolia/client-analytics": "5.46.2", - "@algolia/client-common": "5.46.2", - "@algolia/client-insights": "5.46.2", - "@algolia/client-personalization": "5.46.2", - "@algolia/client-query-suggestions": "5.46.2", - "@algolia/client-search": "5.46.2", - "@algolia/ingestion": "1.46.2", - "@algolia/monitoring": "1.46.2", - "@algolia/recommend": "5.46.2", - "@algolia/requester-browser-xhr": "5.46.2", - "@algolia/requester-fetch": "5.46.2", - "@algolia/requester-node-http": "5.46.2" + "@algolia/abtesting": "1.18.1", + "@algolia/client-abtesting": "5.52.1", + "@algolia/client-analytics": "5.52.1", + "@algolia/client-common": "5.52.1", + "@algolia/client-insights": "5.52.1", + "@algolia/client-personalization": "5.52.1", + "@algolia/client-query-suggestions": "5.52.1", + "@algolia/client-search": "5.52.1", + "@algolia/ingestion": "1.52.1", + "@algolia/monitoring": "1.52.1", + "@algolia/recommend": "5.52.1", + "@algolia/requester-browser-xhr": "5.52.1", + "@algolia/requester-fetch": "5.52.1", + "@algolia/requester-node-http": "5.52.1" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/algoliasearch-helper": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.27.0.tgz", - "integrity": "sha512-eNYchRerbsvk2doHOMfdS1/B6Tm70oGtu8mzQlrNzbCeQ8p1MjCW8t/BL6iZ5PD+cL5NNMgTMyMnmiXZ1sgmNw==", + "version": "3.29.1", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.29.1.tgz", + "integrity": "sha512-6ck2YFudF2Pje7szQoPBiRFTGfd+1I+0I/WfLPGn0bj1kvrFoOQmNyedNiDxTk3/r4IfSLDYk+RA4G7u8H6+yA==", "license": "MIT", "dependencies": { "@algolia/events": "^4.0.1" @@ -6887,33 +7647,6 @@ "node": ">=8" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -6950,6 +7683,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansis": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -7000,9 +7742,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.23", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", - "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", + "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", "funding": [ { "type": "opencollective", @@ -7019,8 +7761,8 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.28.1", - "caniuse-lite": "^1.0.30001760", + "browserslist": "^4.28.2", + "caniuse-lite": "^1.0.30001787", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" @@ -7062,13 +7804,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", "semver": "^6.3.1" }, "peerDependencies": { @@ -7098,12 +7840,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" + "@babel/helper-define-polyfill-provider": "^0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -7126,12 +7868,15 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "version": "2.10.31", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz", + "integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==", "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/batch": { @@ -7281,9 +8026,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "funding": [ { "type": "opencollective", @@ -7301,11 +8046,11 @@ "license": "MIT", "peer": true, "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -7372,14 +8117,14 @@ } }, "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" }, "engines": { @@ -7462,9 +8207,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001762", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", - "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", "funding": [ { "type": "opencollective", @@ -7993,6 +8738,18 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "license": "MIT" }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.2.tgz", + "integrity": "sha512-T6SqyLd1iLuqPA90J5N4cTalrtovCySh58iiZDGJ6FGznbclKh4UI+FGacQSgFzwKG77W7XT5gwbVEbd9cIH1A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/copy-webpack-plugin": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", @@ -8072,29 +8829,18 @@ } }, "node_modules/core-js-compat": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", - "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", "license": "MIT", "dependencies": { - "browserslist": "^4.28.0" + "browserslist": "^4.28.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, - "node_modules/core-js-pure": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.47.0.tgz", - "integrity": "sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -8207,9 +8953,9 @@ } }, "node_modules/css-declaration-sorter": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.1.tgz", - "integrity": "sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.4.0.tgz", + "integrity": "sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==", "license": "ISC", "engines": { "node": "^14 || ^16 || >=18" @@ -8441,9 +9187,9 @@ } }, "node_modules/cssdb": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.6.0.tgz", - "integrity": "sha512-7ZrRi/Z3cRL1d5I8RuXEWAkRFP3J4GeQRiyVknI4KC70RAU8hT4LysUZDe0y+fYNOktCbxE8sOPUOhyR12UqGQ==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.9.0.tgz", + "integrity": "sha512-J8jOU/hLjaXcO1LldOLraJSQpfLXRKof0I7mtbRyOy2AAXgqst0x9rlgi2qXeD6d0ou3ZLqcPAMqYVbpCbrxEw==", "funding": [ { "type": "opencollective", @@ -8800,6 +9546,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -9015,9 +9771,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.360", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.360.tgz", + "integrity": "sha512-GkcBt6YYAw9SxFWn+xVar4cLVGlXVuswwtRLBozi2zp0GjXs4ZnOrqV4zbXzg35n7w81hCkyJNYicgXlVHAmBA==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -9806,15 +10562,6 @@ "node": ">=0.8.x" } }, - "node_modules/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -10045,31 +10792,7 @@ "xml-js": "^1.6.11" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" + "node": ">=0.4.0" } }, "node_modules/file-entry-cache": { @@ -10106,9 +10829,9 @@ } }, "node_modules/file-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", "peer": true, "dependencies": { @@ -10755,9 +11478,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -11710,12 +12433,12 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -12066,7 +12789,6 @@ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -12126,12 +12848,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -12244,6 +12960,267 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "devOptional": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -12424,18 +13401,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/marked": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", - "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 20" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -14765,9 +15730,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", - "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.2.tgz", + "integrity": "sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==", "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -14791,9 +15756,9 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -14860,9 +15825,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "funding": [ { "type": "github", @@ -14934,10 +15899,13 @@ } }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "license": "MIT" + "version": "2.0.45", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.45.tgz", + "integrity": "sha512-iIbHXV9eBB2nB0wa7oTsrrXq+qQt+9SIlx9AX3T96YgobtEQfis5n6TJ6vV+3QP8DwdriEAcGhARaFCu37peBg==", + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/nopt": { "version": "7.2.1", @@ -15097,9 +16065,9 @@ } }, "node_modules/null-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", "peer": true, "dependencies": { @@ -15648,9 +16616,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", "funding": [ { "type": "opencollective", @@ -15668,7 +16636,7 @@ "license": "MIT", "peer": true, "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -16810,9 +17778,9 @@ } }, "node_modules/postcss-preset-env": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.6.0.tgz", - "integrity": "sha512-+LzpUSLCGHUdlZ1YZP7lp7w1MjxInJRSG0uaLyk/V/BM17iU2B7xTO7I8x3uk0WQAcLLh/ffqKzOzfaBvG7Fdw==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.6.1.tgz", + "integrity": "sha512-yrk74d9EvY+W7+lO9Aj1QmjWY9q5NsKjK2V9drkOPZB/X6KZ0B3igKsHUYakb7oYVhnioWypQX3xGuePf89f3g==", "funding": [ { "type": "github", @@ -16850,7 +17818,7 @@ "@csstools/postcss-media-minmax": "^2.0.9", "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", "@csstools/postcss-nested-calc": "^4.0.0", - "@csstools/postcss-normalize-display-values": "^4.0.0", + "@csstools/postcss-normalize-display-values": "^4.0.1", "@csstools/postcss-oklab-function": "^4.0.12", "@csstools/postcss-position-area-property": "^1.0.0", "@csstools/postcss-progressive-custom-properties": "^4.2.1", @@ -17525,9 +18493,9 @@ } }, "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.3.tgz", + "integrity": "sha512-GXfh9VLwB5ERaCsU6RULh7tkemeX15aNh6wuMEBtfdyMa7fFG8TXrhXlx1SoEK2Ty/l6XIkzzYIQmyaWW3JgdQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.3" @@ -17778,9 +18746,9 @@ "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", - "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.1.0" @@ -18105,15 +19073,6 @@ "entities": "^2.0.0" } }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -18138,11 +19097,12 @@ "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "license": "MIT", "dependencies": { + "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" @@ -18305,10 +19265,13 @@ "license": "MIT" }, "node_modules/sax": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz", - "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==", - "license": "BlueOak-1.0.0" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, "node_modules/scheduler": { "version": "0.27.0", @@ -18465,15 +19428,15 @@ } }, "node_modules/serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz", + "integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==", "license": "MIT", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", "mime-types": "2.1.18", - "minimatch": "3.1.2", + "minimatch": "3.1.5", "path-is-inside": "1.0.2", "path-to-regexp": "3.3.0", "range-parser": "1.2.0" @@ -18751,9 +19714,9 @@ "license": "MIT" }, "node_modules/sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.3.tgz", + "integrity": "sha512-tAjEd+wt/YwnEbfNB2ht51ybBJxbEWwe5ki/Z//Wh0rpBFTCUSj46GnxUKEWzhfuJTsee8x3lybHxFgUMig2hw==", "license": "MIT", "dependencies": { "@types/node": "^17.0.5", @@ -19197,18 +20160,18 @@ "license": "MIT" }, "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz", + "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==", "license": "MIT", "dependencies": { - "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", - "picocolors": "^1.0.0" + "picocolors": "^1.0.0", + "sax": "^1.5.0" }, "bin": { "svgo": "bin/svgo" @@ -19230,17 +20193,18 @@ "node": ">= 10" } }, - "node_modules/swr": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.8.tgz", - "integrity": "sha512-gaCPRVoMq8WGDcWj9p4YWzCMPHzE0WNl6W8ADIx9c3JBEIdMkJGMzW+uzXvxHMltwcYACr9jP+32H8/hgwMR7w==", + "node_modules/swc-loader": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.7.tgz", + "integrity": "sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w==", + "devOptional": true, "license": "MIT", "dependencies": { - "dequal": "^2.0.3", - "use-sync-external-store": "^1.6.0" + "@swc/counter": "^0.1.3" }, "peerDependencies": { - "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "@swc/core": "^1.2.147", + "webpack": ">=2" } }, "node_modules/synckit": { @@ -19375,18 +20339,6 @@ "tslib": "^2" } }, - "node_modules/throttleit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz", - "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -20255,9 +21207,9 @@ } }, "node_modules/url-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", "peer": true, "dependencies": { @@ -20325,15 +21277,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/use-sync-external-store": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -20937,75 +21880,30 @@ } }, "node_modules/webpackbar": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", - "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-7.0.0.tgz", + "integrity": "sha512-aS9soqSO2iCHgqHoCrj4LbfGQUboDCYJPSFOAchEK+9psIjNrfSWW4Y0YEz67MKURNvMmfo0ycOg9d/+OOf9/Q==", "license": "MIT", "dependencies": { - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", + "ansis": "^3.2.0", "consola": "^3.2.3", - "figures": "^3.2.0", - "markdown-table": "^2.0.0", "pretty-time": "^1.1.0", - "std-env": "^3.7.0", - "wrap-ansi": "^7.0.0" + "std-env": "^3.7.0" }, "engines": { "node": ">=14.21.3" }, "peerDependencies": { + "@rspack/core": "*", "webpack": "3 || 4 || 5" - } - }, - "node_modules/webpackbar/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/webpackbar/node_modules/markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "license": "MIT", - "dependencies": { - "repeat-string": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/webpackbar/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpackbar/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/websocket-driver": { @@ -21295,16 +22193,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zod": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", - "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index ef802c3..12c2535 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "fix": "eslint . --fix" }, "dependencies": { - "@docusaurus/core": "3.9.2", - "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/core": "^3.10.1", + "@docusaurus/preset-classic": "^3.10.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -26,10 +26,11 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@docusaurus/eslint-plugin": "^3.9.2", - "@docusaurus/module-type-aliases": "3.9.2", - "@docusaurus/tsconfig": "3.9.2", - "@docusaurus/types": "3.9.2", + "@docusaurus/eslint-plugin": "^3.10.1", + "@docusaurus/faster": "^3.10.1", + "@docusaurus/module-type-aliases": "^3.10.1", + "@docusaurus/tsconfig": "^3.10.1", + "@docusaurus/types": "^3.10.1", "@signalwire/docusaurus-plugin-llms-txt": "^1.2.2", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", diff --git a/static/img/error-page-screenshot.png b/static/img/error-page-screenshot.png new file mode 100644 index 0000000..4adf513 Binary files /dev/null and b/static/img/error-page-screenshot.png differ diff --git a/versioned_docs/version-v8.3/README.md b/versioned_docs/version-v8.3/README.md new file mode 100644 index 0000000..91e6f8a --- /dev/null +++ b/versioned_docs/version-v8.3/README.md @@ -0,0 +1,72 @@ +--- +id: introduction +title: Introduction +description: Supercharge your WordPress Development +sidebar_position: 1 +--- + +# Introduction + +Lumberjack is a powerful MVC framework for the modern WordPress developer. Write better, more expressive and easier to maintain code. + +### Who is Lumberjack for? + +Coming from another PHP framework such as Laravel, have experience using Timber with WordPress but want more, or are just getting started with modern WordPress? Then Lumberjack is for you. + +Use as little or as much as you need, it's beginner friendly! + +### Beautiful code. Easy to maintain + +Object orientated and MVC patterns help keep your code structured and DRY. + +**index.php** + +```php +class IndexController +{ + public function handle() + { + $context = Timber::context(); + $context['posts'] = Post::builder() + ->whereStatus('publish') + ->limit(5) + ->get(); + + return new TimberResponse('index.twig', $context); + } +} +``` + +**index.twig** + +```twig +{% if posts is not empty %} +

Recent Articles

+ +{% endif %} +``` + +### You're in good company + +> Lumberjack is the deluxe version of what Modern WordPress should look like today. The team has done a great job of making it easy to build complicated custom applications while taking advantage of the best parts of WordPress. +> +> - _**Jared Novack - Timber creator**_ + +Standing on the shoulders of giants, Lumberjack proudly builds on the great work of other open source WordPress projects: + +- [Timber](https://www.upstatement.com/timber/) +- [Bedrock](https://roots.io/bedrock/) + +### Made by [Rareloop](https://rareloop.com) + +We're a Digital Product Studio based in Southampton (UK) with many years experience working on modern WordPress websites. We design and build digital products for a range of clients, take a look at what else we can do. + +[Find out more](https://www.rareloop.com/) diff --git a/versioned_docs/version-v8.3/container/_category_.json b/versioned_docs/version-v8.3/container/_category_.json new file mode 100644 index 0000000..bc83807 --- /dev/null +++ b/versioned_docs/version-v8.3/container/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Container", + "position": 6 +} diff --git a/versioned_docs/version-v8.3/container/facades.md b/versioned_docs/version-v8.3/container/facades.md new file mode 100644 index 0000000..91cf6de --- /dev/null +++ b/versioned_docs/version-v8.3/container/facades.md @@ -0,0 +1,110 @@ +--- +sidebar_position: 3 +--- + +# Facades + +Lumberjack provides a custom implementation of Facades, based on the now-deprecated [Blast Facades](https://github.com/phpthinktank/blast-facades) library. + +## Creating a Facade + +Facades provide a simple static API to an object that has been registered into the container. For example to setup a facade you would first use a Service Provider to register an instance of your class into the container: + +```php +namespace Rareloop\Lumberjack\Providers; + +use Monolog\Logger; +use Rareloop\Lumberjack\Application; + +class LogServiceProvider extends ServiceProvider +{ + public function register() + { + // Create object instance and bind into container + $this->app->bind('logger', new Logger('app')); + } +} +``` + +Then create a Facade subclass and tell it which key to use to retrieve your class instance: + +```php +namespace Rareloop\Lumberjack\Facades; + +use Rareloop\Lumberjack\Facades\AbstractFacade; + +class Log extends AbstractFacade +{ + protected static function accessor() + { + return 'logger'; + } +} +``` + +## Available Facades + +Lumberjack comes with a handful of useful Facades. Below you can see which class the Facade references and what it is bound to the container under. + +| Facade | Class Reference | Container binding | +| :------ | :------------------------------------------- | :---------------- | +| Config | `Rareloop\Lumberjack\Config` | `config` | +| Log | `Monolog\Logger` | `logger` | +| Router | `Rareloop\Lumberjack\Http\Route` | `router` | +| Session | `Rareloop\Lumberjack\Session\SessionManager` | `session` | + +### Example usage + +All of Lumberjack's Facades live under the `Rareloop\Lumberjack\Facades` namespace. + +#### Config + +The `Config` facade allows you to get and set values from your config. + +```php +use Rareloop\Lumberjack\Facades\Config; + +Config::set('app.debug', false); + +$value = Config::get('app.debug'); +``` + +Config is also available as a [Helper](/the-basics/helpers#config) + +#### Log + +The `Log` facade allows you to use the [PSR-3](https://www.php-fig.org/psr/psr-3/) Logger [Monolog](https://github.com/Seldaek/monolog). + +```php +use Rareloop\Lumberjack\Facades\Log; + +$value = Log::warning('Oops! Something went wrong'); +``` + +#### Router + +The `Router` facade allows you to create custom routes or get the URLs for your routes. + +```php +use Rareloop\Lumberjack\Facades\Router; + +Router::get('posts/all', function () {})->name('posts.index'); + +$url = Router::url('posts.index'); +``` + +See [Creating Routes](/the-basics/routing#creating-routes) for more information. + +#### Session + +The `Session` facade allows you to retrieve and store data in the current session. + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::put('name', 'Chris'); + +$name = Session::get('name'); +``` + +Session is also available as a [Helper](/the-basics/helpers#session) diff --git a/versioned_docs/version-v8.3/container/service-providers.md b/versioned_docs/version-v8.3/container/service-providers.md new file mode 100644 index 0000000..24a7510 --- /dev/null +++ b/versioned_docs/version-v8.3/container/service-providers.md @@ -0,0 +1,90 @@ +--- +sidebar_position: 2 +--- + +# Service Providers + +## Introduction + +When Lumberjack bootstraps it creates an Application Container, which is responsible for resolving concrete classes that have been **bound** to the container in one way or another. This binding happens via Service Providers. + +A Service Provider needs to be registered with Lumberjack. This can be done in `config/app.php` under the `providers` array. + +Let's look at how to create a new Service Provider and register it to the container. + +## Creating Service Providers + +Service Providers can live anywhere within the `app/` directory, or even as packages that you bring in via composer. Let's create a new file within `app/Providers` called `PaymentGatewayProvider.php`. + +This file must extend `Rareloop\Lumberjack\Providers\ServiceProvider`. This gives you access to the container via `$this->app`. There are 2 methods that Lumberjack looks for on a Service Providers: `register()` and `boot()`. + +### Register + +The `register` method should only be used to bind things to the container. You cannot rely on Lumberjack registering service providers in any order, so you should always assume no other provider had been registered. + +You should not attempt to do anything other than binding things to the container in `register`. Do not try and add WordPress filters/actions, register routes, configure WordPress etc here. This is to prevent you from accidentally using a service provider which has not been loaded yet. + +```php +namespace App\Providers; + +use Rareloop\Lumberjack\Providers\ServiceProvider; + +class PaymentGatewayProvider extends ServiceProvider +{ + public function register() + { + $this->app->bind('\App\PaymentGateway', '\App\StripePaymentGateway'); + } +} +``` + +Now, whenever we need to use a payment gateway in our application we can resolve it from the container. This, in theory, makes it really easy to swap out Stripe with another payment gateway. + +#### Binding to the container + +There are a number of different ways to bind things to the container. Head over to ['Using the Container'](using-the-container.md) for more information. + +### Boot + +Once all service providers have been registered, Lumberjack then attempts to call the `boot` method on each one. This means that you have access to everything that has been bound to the container and can access it using [dependency injection](using-the-container.md#dependency-injection) on the `boot` method. + +```php +namespace App\Providers; + +use Rareloop\Lumberjack\Providers\ServiceProvider; +use Rareloop\Lumberjack\Config; + +/** + * Add Option Pages to WP using the config, using ACF + */ +class OptionPagesProvider extends ServiceProvider +{ + // Dependency inject Config from the container + public function boot(Config $config) + { + $optionPages = $config->get('option-pages'); + + if (!is_array($optionPages)) { + return; + } + + foreach ($optionPages as $optionPage) { + acf_add_options_page($optionPage); + } + } +} +``` + +### Register Service Providers with Lumberjack + +Once you have your service provider ready to go, you need to add the name of the class to the `providers` array in `config/app.php`. + +```php +return [ + 'providers' => [ + // ... + + App\Providers\TwitterProvider::class, + ], +]; +``` diff --git a/versioned_docs/version-v8.3/container/using-the-container.md b/versioned_docs/version-v8.3/container/using-the-container.md new file mode 100644 index 0000000..0d966e4 --- /dev/null +++ b/versioned_docs/version-v8.3/container/using-the-container.md @@ -0,0 +1,368 @@ +--- +sidebar_position: 1 +--- + +# Using the Container + +## Introduction + +:::info +Lumberjack features a PSR11 compatible container, powered by the popular open source [PHPDI](http://php-di.org/). If this is a new term for you checkout this [great intro](http://php-di.org/doc/understanding-di.html) and don't worry, you don't have to make use of it if you don't want to. + +Having a deeper understanding of Lumberjack's dependency injection container will help you build maintainable, scalable and robust themes. +::: + +There are many ways in which you can interact with the container. Primarily it's used for dependency injection. You can either inject classes that Lumberjack has bound, or bind something yourself. This is a great way of managing class dependencies within your theme. + +**The following examples will be using the** `app()` **global helper. If you do not have it enabled, you can use the** `Helpers` **class. For example:** + +```php +app()->bind('key', 'value'); +``` + +Would become: + +```php +use Rareloop\Lumberjack\Helpers; +Helpers::app()->bind('key', 'value'); +``` + +## Accessing the container + +In the default Lumberjack `functions.php` you'll find the following code: + +```php +$app = new Application(__DIR__); +``` + +This creates the Application and the `$app` variable becomes your reference to the container. + +There are a couple of ways you can access the container throughout your application. Let's take a look at them. + +#### Within Service Providers + +The container can be accessed within a service provider by referencing `$this->app`. + +```php +namespace App\Providers; + +use Rareloop\Lumberjack\Providers\ServiceProvider; +use App\PaymentGateway; +use App\StripePaymentGateway; + +class PaymentGatewayServiceProvider extends ServiceProvider +{ + public function register() + { + $this->app->bind(PaymentGateway::class, StripePaymentGateway::class); + } +} +``` + +:::warning +You should only ever bind to the container within a service provider's `register()` method. +::: + +#### Everywhere else + +You can access the container from anywhere in your theme by using the `app()` helper. + +```php +use Rareloop\Lumberjack\Helpers; +$app = Helpers::app(); +``` + +[Check out the "Helpers" documentation](../the-basics/helpers.md#app) for more information on using this helper. + +## Retrieving entries from the container + +To resolve an entry from the container you can use `get()`. + +```php +$value = app()->get('key'); + +// Or, using the helper's convenient shorthand +$value = app('key'); +``` + +You can use the container to create an object from any class that your application can autoload using `get()`, for example: + +```php +use \MyNamespace\Comment; + +$comment = app->get(Comment::class); + +// Or using the helper's convenient shorthand: +$comment = app(Comment::class); +``` + +When creating an object using `get`, all the dependencies required by it's `__construct()` function will be automatically resolved from the container using type hinting. + +```php +namespace App; + +class Comment +{ + public function __construct(ClassInContainer $resolvable) + { + $this->resolvable = $resolvable; + } +} + +... +use App\Comment; + +$comment = app(Comment::class); +``` + +#### Make + +If your object requires additional parameters that can not resolved by type hinting then you should use the `make` method, and pass them as a second param. + +:::warning +`make()` will always create a new instance and ignore any singleton binding. +::: + +For example: + +```php +namespace App; + +class Comment +{ + public function __construct(ClassInContainer $resolvable, $param1, $param2) {} +} + +... + +use App\Comment; + +$comment = app()->make(Comment::class, [ + 'param1' => 123, + 'param2' => 'abc', +]); +``` + +## Setting entries in the container + +To add something to the container you simply call `bind()`. In this example, `value` is bound to the container under `key`. + +```php +app()->bind('key', 'value'); +``` + +You can bind pretty much anything you like to the container. Let's take a look at some other examples. Understanding the difference in behaviour is vital in using the container effectively. + +### Objects + +```php +use App\Comment; + +app()->bind('comment', new Comment); +``` + +Whenever you resolve `comment` from the container, the same `Comment` object is returned. This is important, as it means **state** **is maintained automatically**. + +```php +use App\Comment; + +app()->bind('comment', new Comment); + +$commentA = app('comment'); // resolves the 'Comment' object + +// Update the comment +$commentA->author = 'Adam'; + +$commentB = app('comment'); // resolves the exact same 'Comment' object + +$commentB->author; // 'Adam' +``` + +### Closures + +Binding objects is useful, however it requires you to create an object before binding. This isn't always ideal, as it means that object has to be instantiated before being bound even if it is never used. + +You can _lazy-load_ dependencies, where they are only created at the point they are needed, by passing in a closure to the container: + +```php +use App\Comment; + +app()->bind('comment', function () { + return new Comment; +}); +``` + +In this example, the `Comment` object is never created as nothing is trying to resolve `comment` from the container. + +Now lets look at what happens when we try and resolve comment from the container: + +```php +use App\Comment; + +app()->bind('comment', function () { + return new Comment; +}); + +$commentA = app('comment'); // Calls the closure and creates a new Comment object + +// Update the comment +$commentA->author = 'Adam'; + +$commentB = app('comment'); // Calls the closure and creates a new Comment object + +$commentB->author; // Throws an error, undefined property! +``` + +Here you can see that `$commentB->author` throws an error. **This is because closures will always create a new instance.** + +If you need to persist state, you should bind using `singleton`**:** + +```php +use App\Comment; + +app()->singleton('comment', function () { + return new Comment; +}); +``` + +Now, if we revisit our example above `$commentB` will now be the same object as `$commentA`, and we won't get any errors. + +```php +use App\Comment; + +app()->singleton('comment', function () { + return new Comment; +}); + +$commentA = app('comment'); // Calls the closure and creates a new Comment object + +// Update the comment +$commentA->author = 'Adam'; + +$commentB = app('comment'); // resolves the exact same 'Comment' object + +$commentB->author; // 'Adam' +``` + +### **Class names** + +If you would like to resolve a class (like our example `Comment` class), you can use the class name when binding: + +```php +use App\Comment; + +app()->bind('comment', Comment::class); // Comment::class simply outputs to '\App\Comment' +``` + +By using a class name, the container behaves exactly the same as closures. **The container will only create the class when it gets used & it will resolve a new instance of the class every time**. For example: + +```php +use App\Comment; + +app()->bind('comment', Comment::class); + +$commentA = app('comment'); // Creates a new instance of Comment + +// Update the comment +$commentA->author = 'Adam'; + +$commentB = app('comment'); // Creates a new instance of Comment + +$commentB->author; // Throws an error, undefined property! +``` + +However, you also get the added benefit of being able to inject dependencies into your classes `__construct()` method. See ["Retrieving entries from the container"](using-the-container.md#retrieving-entries-from-the-container) for more information on this. + +Singletons work in the same way with class names as they do with closures. When you bind using `singleton()`, the same class instance is always resolved, and therefore its state is maintained. + +```php +use App\Comment; + +app()->singleton('comment', Comment::class); + +$commentA = app('comment'); // Creates a new instance of Comment + +// Update the comment +$commentA->author = 'Adam'; + +$commentB = app('comment'); // resolves the exact same instance of Comment + +$commentB->author; // 'Adam' +``` + +### Set concrete implementations for interfaces + +You can also tell the container what concrete class to use when resolving a certain type hinted interface. This allows you to write your app code against contracts and then use the container to switch in the correct implementation at runtime. + +Lets walk through a quick example. First, lets create an interface (or contract) which states that payment gateways should be able to charge. + +```php +namespace App; + +interface PaymentGateway +{ + public function charge($amount); +} +``` + +Any implementation of this contract has to have a `charge` method that accepts an `$amount`. Lets add a Stripe implementation of the interface: + +```php +namespace App; + +class StripePaymentGateway implements PaymentGateway +{ + public function charge($amount) + { + // Charge using stripe... + } +} +``` + +Within our application, we want to ask the container for `PaymentGateway`. This is because our application doesn't care which implementation to use, it just wants to be able to charge people. We can tell the container to resolve `StripePaymentGateway` whenever we ask for `PaymentGateway`, like so: + +```php +app()->bind(PaymentGateway::class, StripePaymentGateway::class); + +app(PaymentGateway::class); // resolves an instance of StripePaymentGateway +``` + +The same applies when dependency injecting: + +```php +class MyController +{ + public function __construct(PaymentGateway $paymentGateway) + { + // $paymentGateway will be an instance of StripePaymentGateway + // We can safely call 'charge' because our Stripe implementation has to adhere to the interface/contract + $paymentGateway->charge(100); + } +} +``` + +## Dependency Injection + +Rather than manually resolving something from the container, you can type hint dependencies in the constructor of classes that are resolved by Lumberjack's container. These include: **controllers** and **service providers**. + +If we have the following bound to the container: + +```php +use App\MyClass; + +app()->bind(MyClass::class, new MyClass); +``` + +You can type hint the `MyClass` class in a controller's constructor and the container will resolve it for you automatically: + +```php +class MyController +{ + public function __construct(MyClass $myClass) + { + + } +} +``` + +Generally, this is how most of your objects should be resolved from the container. diff --git a/versioned_docs/version-v8.3/getting-started/_category_.json b/versioned_docs/version-v8.3/getting-started/_category_.json new file mode 100644 index 0000000..4bd4025 --- /dev/null +++ b/versioned_docs/version-v8.3/getting-started/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Getting Started", + "position": 4 +} diff --git a/versioned_docs/version-v8.3/getting-started/configuration.md b/versioned_docs/version-v8.3/getting-started/configuration.md new file mode 100644 index 0000000..96a42ff --- /dev/null +++ b/versioned_docs/version-v8.3/getting-started/configuration.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 2 +--- + +# Configuration + +Lumberjack comes with a selection of config files out-of-the-box. These live in the `config/` directory and are simple `.php` files that return an `array`. + +## Accessing Configuration Values + +Let's take a look at `config/app.php`: + +```php +return [ + /** + * The current application environment + */ + 'environment' => getenv('WP_ENV'), + + // ...etc +]; +``` + +Here we are proxying an environment variable defined in the `.env` file that Bedrock provides. We'd recommend following this pattern, where you should only see `getenv` called in your config files. + +You can easily access the environment variable using the `Rareloop\Lumberjack\Facades\Config` facade. + +```php +use Rareloop\Lumberjack\Facades\Config; + +$env = Config::get('app.environment'); +``` + +You can provide a default value too, incase the configuration option does not exist. + +```php +$env = Config::get('app.environment', 'production'); +``` + +If you need to update a config option, you can use the `set` method, like so: + +```php +Config::set('app.debug', false); +``` + +You can check whether an item exists in the config: + +```php +if (Config::has('app.mySetting')) { + // ... +} +``` + +:::warning +**Note that the `has` method only checks whether the config item exists, regardless of its value**. + +If you set `app.mySetting` to an empty value such as `false` or `null`, `has('app.mySetting')` will return `true`. +::: + +## Adding your own config files + +Chances are, you're going to need to add your own config files at some point. All you need to do is create a new `.php` file in the `config/` directory, and have it return an array. + +This works because Lumberjack will look for all files in the `config/` directory that have a `.php` extension and automatically registers all the data to the application's config. diff --git a/versioned_docs/version-v8.3/getting-started/installation.md b/versioned_docs/version-v8.3/getting-started/installation.md new file mode 100644 index 0000000..5585045 --- /dev/null +++ b/versioned_docs/version-v8.3/getting-started/installation.md @@ -0,0 +1,114 @@ +--- +sidebar_position: 1 +--- + +# Installation + +## Requirements + +- PHP >=8.3 +- [Composer](https://getcomposer.org) + +:::warning +_Currently, using a child-theme to extend a Lumberjack theme is unsupported._ +::: + +## Using the Installer (Recommended) + +This is the recommended way to create a new site and assumes you want to build on top of [Bedrock](https://roots.io/bedrock). If you're new to using WordPress with Composer this is the simplest (and quickest) way to get up and running as the installer will do all the heavy lifting for you. + +### Pre-requisites + +Download the Lumberjack Bedrock Installer with Composer _(you only need to do this the first time)_: + +```bash +composer global require rareloop/lumberjack-bedrock-installer +``` + +Make sure that Composer's global `vendor` bin directory is in your `$PATH` so that the installer can be used. + +### Create a new site + +Once the installer is available on your computer you can create a new Lumberjack/Bedrock site using: + +```bash +lumberjack-bedrock new my-site +``` + +This will create a new folder `my-site` in the current working directory, install the latest version of Bedrock, add the `lumberjack-core` dependency and download the most recent Lumberjack starter theme. + +To complete the install do the following: + +1. Edit the `.env` file and update environment variables: + - `DB_NAME` - Database name + - `DB_USER` - Database user + - `DB_PASSWORD` - Database password + - `DB_HOST` - Database host + - `WP_ENV` - Set to environment (`development`, `staging`, `production`) + - `WP_HOME` - Full URL to WordPress home (e.g. [http://example.com](http://example.com)) + - `WP_SITEURL` - Full URL to WordPress including subdirectory (e.g. [http://example.com/wp](http://example.com/wp)) + - `AUTH_KEY`, `SECURE_AUTH_KEY`, `LOGGED_IN_KEY`, `NONCE_KEY`, `AUTH_SALT`, `SECURE_AUTH_SALT`, `LOGGED_IN_SALT`, `NONCE_SALT` - Generate with [wp-cli-dotenv-command](https://github.com/aaemnnosttv/wp-cli-dotenv-command) or from the [Roots WordPress Salt Generator](https://cdn.roots.io/salts.html) +2. Set your site vhost document root to `/path/to/my-site/web/` +3. Access WP admin at `http://example.com/admin` and activate the Lumberjack theme. + +### Additional Options + +For more information on additional installer options, please see the [Lumberjack Installer](https://github.com/Rareloop/lumberjack-bedrock-installer) package on GitHub. + +## Manual Installation + +If you don't plan to use Bedrock and have another Composer based setup for WordPress, you can do the following: + +1. Download the [Lumberjack Starter Theme](https://github.com/Rareloop/lumberjack) and add it to your WordPress theme directory. +2. Now add the Lumberjack Core dependency via Composer: + + ```bash + composer require rareloop/lumberjack-core + ``` + +3. If your setup doesn't include your Composer `vendor/autoload.php` file outside of the theme, you'll need to add the following to the top of the themes `functions.php`: + + ```php + require_once('path/to/composer/vendor/autoload.php'); + ``` + +## Add to existing theme + +Lumberjack can be added to an existing theme as long as Composer is being used as part of your setup. You're able to use as little or as much as you need and the framework will play nicely alongside more traditional WordPress code. + +1. Add the Lumberjack Core dependency via Composer: + + ```bash + composer require rareloop/lumberjack-core + ``` + +2. Copy the following directories from the [Lumberjack Starter Theme](https://github.com/Rareloop/lumberjack) into your theme: + - `app` + - `bootstrap` + - `config` + - `views` +3. Create an empty `routes.php` file at the root of your theme directory. +4. Add the following to the top of your `functions.php` file: + + ```php + use App\Http\Lumberjack; + + // Create the Application Container + $app = require_once('bootstrap/app.php'); + + // Bootstrap Lumberjack from the Container + $lumberjack = $app->make(Lumberjack::class); + $lumberjack->bootstrap(); + + // Import our routes file + require_once('routes.php'); + + // Set global params in the Timber context + add_filter('timber_context', [$lumberjack, 'addToContext']); + ``` + +5. If your setup doesn't include your Composer `vendor/autoload.php` file outside of the theme, you'll need to also add the following to the top of the themes `functions.php`: + + ```php + require_once('path/to/composer/vendor/autoload.php'); + ``` diff --git a/versioned_docs/version-v8.3/misc/_category_.json b/versioned_docs/version-v8.3/misc/_category_.json new file mode 100644 index 0000000..7626d8b --- /dev/null +++ b/versioned_docs/version-v8.3/misc/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Misc", + "position": 7 +} diff --git a/versioned_docs/version-v8.3/misc/code-of-conduct.md b/versioned_docs/version-v8.3/misc/code-of-conduct.md new file mode 100644 index 0000000..b9c4827 --- /dev/null +++ b/versioned_docs/version-v8.3/misc/code-of-conduct.md @@ -0,0 +1,49 @@ +--- +sidebar_position: 3 +--- + +# Code of Conduct + +## Contributor Code of Conduct + +### Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +### Our Standards + +Examples of behaviour that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behaviour by participants include: + +- The use of sexualised language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +### Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behaviour and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behaviour. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviours that they deem inappropriate, threatening, offensive, or harmful. + +### Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported by contacting the project team at [info@rareloop.com](mailto:info@rareloop.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html) diff --git a/versioned_docs/version-v8.3/misc/contributing.md b/versioned_docs/version-v8.3/misc/contributing.md new file mode 100644 index 0000000..c3210d8 --- /dev/null +++ b/versioned_docs/version-v8.3/misc/contributing.md @@ -0,0 +1,29 @@ +--- +sidebar_position: 1 +--- + +# Contributing + +Contributions are **welcome** and will be fully **credited**. + +We accept contributions via Pull Requests on [Github](https://github.com/Rareloop/lumberjack). + +## Pull Requests + +- [**PSR-2 Coding Standard**](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer). +- **Add tests** - Your patch likely will not be accepted if it doesn't have tests. +- **Create feature branches** - Don't ask us to pull from your master branch. +- **One pull request per feature or fix** - If you want to do more than one thing, send multiple pull requests. +- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. We follow the advice of Chris Beams on [How to write good commit messages](https://chris.beams.io/posts/git-commit/). + +## Running Tests + +```bash +$ vendor/bin/phpunit +``` + +## Linting against PSR2 Coding Standards + +```bash +$ vendor/bin/phpcs --standard=PSR2 ./src +``` diff --git a/versioned_docs/version-v8.3/misc/notable-mentions.md b/versioned_docs/version-v8.3/misc/notable-mentions.md new file mode 100644 index 0000000..c4e7a7b --- /dev/null +++ b/versioned_docs/version-v8.3/misc/notable-mentions.md @@ -0,0 +1,19 @@ +--- +sidebar_position: 2 +--- + +# Notable Mentions + +We just want to say thanks to a handful of projects, without which we wouldn't have been able to build Lumberjack. + +## Rareloop + +A lot of blood, sweat and tears (of joy) went into building Lumberjack. We have spent years working with WordPress and always strived to write maintainable code quickly. We're genuinely excited about the future of Lumberjack! + +## Laravel + +We use [Laravel](https://laravel.com) an awful lot at [Rareloop](https://rareloop.com), and basically wanted something that felt like Laravel but in WordPress. Rather than re-inventing the wheel we were heavily inspired by how Laravel works under the hood as well as all the awesome features they have aimed at rapid application development (RAD). + +## Timber + +We love [Timber](https://www.upstatement.com/timber/#whats-timber). It took away a lot of the pain of working with WordPress and is a great base for us to build Lumberjack on. diff --git a/versioned_docs/version-v8.3/the-basics/_category_.json b/versioned_docs/version-v8.3/the-basics/_category_.json new file mode 100644 index 0000000..97c08d0 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "The Basics", + "position": 5 +} diff --git a/versioned_docs/version-v8.3/the-basics/collections.md b/versioned_docs/version-v8.3/the-basics/collections.md new file mode 100644 index 0000000..f450be5 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/collections.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 12 +description: Collections are a thin wrapper around arrays that make them much easier to work with. +--- + +# Collections + +You can create a collection in a couple of ways: + +```php +use Illuminate\Support\Collection; + +$data = new Collection(['Jayne', 'Milo']); + +// or using the global helper +$data = collect(['Jayne', 'Milo']); +``` + +If you are used to working with arrays, you can continue using them in the same way. + +```php +$data = collect(['Jayne', 'Milo']); + +// Get the first name, or if it doesn't exist set the value to null +$firstName = $data[0] ?? null; +``` + +However, collections come with a huge assortment of handy functions that can make your life easier. + +```php +$data = collect(['Jayne', 'Milo']); + +// Get the first name, or if it doesn't exist set the value to null +$firstName = $data->first(); +``` + +For a list of the available methods, please refer to their documentation: [https://laravel.com/docs/9.x/collections#available-methods](https://laravel.com/docs/9.x/collections#available-methods) + +:::info +Note: Laravel's collections may change over time as they add/remove features etc. Make sure you are always referring to the correct version of their documentation. +::: + +### Extending collections + +Similar to post types and the query builder, you can add your own methods to the collection class using macros. For more information about this, please refer to Laravel's documentation: + +[https://laravel.com/docs/9.x/collections#extending-collections](https://laravel.com/docs/9.x/collections#extending-collections) diff --git a/versioned_docs/version-v8.3/the-basics/error-handling.md b/versioned_docs/version-v8.3/the-basics/error-handling.md new file mode 100644 index 0000000..e191d83 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/error-handling.md @@ -0,0 +1,86 @@ +--- +title: Error Handling +description: Lumberjack provides a robust error handling system that displays detailed error pages in development and a generic error page in production. +sidebar_position: 13 +--- + +# Error Handling + +Lumberjack comes with a powerful error handling system powered by [Ignition](https://spatie.be/docs/ignition/v1/introduction), which provides beautiful, detailed error pages when you're in development. When in production, Lumberjack will display a simple, styled error page to avoid exposing sensitive information. + +## The Default Error Page + +When `APP_DEBUG` is set to `false` in your `.env` file, Lumberjack will catch any exceptions and display a generic error page. This prevents your site from showing a blank white page or a detailed error stack trace that could be a security risk. + +![Default Error Page](/img/error-page-screenshot.png) + +As you can see, it's a simple, clean error page that informs the user that something has gone wrong. + +## Customizing the Error Page + +While the default error page is a great starting point, you may want to create a custom error page that matches your site's branding. You can do this by extending the `Rareloop\Lumberjack\Exceptions\Handler` class and overriding the `renderDefaultErrorView` method. + +It's important to note that the expectation is that you will extend the exception handler to create your own custom error pages. + +Here's an example of how you might create a custom error handler: + +```php +// app/Exceptions/Handler.php +namespace App\Exceptions; + +use Exception; +use Psr\Http\Message\ResponseInterface; +use Rareloop\Lumberjack\Http\Responses\TimberResponse; +use Rareloop\Lumberjack\Exceptions\Handler as ExceptionHandler; + +class Handler extends ExceptionHandler +{ + protected function renderDefaultErrorView(Exception $e): ResponseInterface + { + $status = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500; + + return new TimberResponse('views/errors/error.twig', [ + 'statusCode' => $status, + ], $status); + } +} +``` + +In this example, we're telling Lumberjack to render the `views/errors/error.twig` template instead of the default one. You can now create a custom Twig file with your own branding. + +Once you have created your custom `Handler` class, you will need to update your `bootstrap/app.php` file to tell Lumberjack to use your custom handler instead of the default one. + +```php +// bootstrap/app.php +... +$app->singleton( + Rareloop\Lumberjack\Contracts\ExceptionHanlder::class, + App\Exceptions\Handler::class +); +... +``` + +## Configuring Ignition + +Lumberjack v8.3 introduces a new `Ignition` facade and `IgnitionServiceProvider` to make it easier to configure Ignition. You can now add solution providers, set themes, and more from any service provider. + +Here's an example of how you might add a custom solution provider to Ignition in your `AppServiceProvider`: + +```php +// app/Providers/AppServiceProvider.php +namespace App\Providers; + +use App\Solutions\MyCustomSolutionProvider; +use Rareloop\Lumberjack\Facades\Ignition; +use Rareloop\Lumberjack\Providers\ServiceProvider; + +class AppServiceProvider extends ServiceProvider +{ + public function boot() + { + Ignition::addSolutionProviders([ + MyCustomSolutionProvider::class, + ]); + } +} +``` diff --git a/versioned_docs/version-v8.3/the-basics/helpers.md b/versioned_docs/version-v8.3/the-basics/helpers.md new file mode 100644 index 0000000..7a0512e --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/helpers.md @@ -0,0 +1,279 @@ +--- +sidebar_position: 11 +--- + +# Helpers + +## Introduction + +Lumberjack provides a handful of helpful functions that should make your life a little easier. + +By default they are available as static methods on the `\Rareloop\Lumberjack\Helpers` class, so that the global namespace isn't getting polluted. You can safely use these methods without fear of function names clashing. + +You can tell Lumberjack to create global functions for you if you do not mind about adding these functions to the global namespace. + +If you are building packages or plugins specifically for Lumberjack, you cannot rely on the global helper functions as the theme may not have made them available. + +## Adding Global Helpers + +In order to use the global helper functions, all you need to do it tell composer to autoload `vendor/rareloop/lumberjack-core/src/functions.php`. + +Add the following to your top-level `composer.json` file: + +```javascript +"autoload": { + "files": [ + "vendor/rareloop/lumberjack-core/src/functions.php" + ] +} +``` + +Then, tell composer to regenerate its list of autoloaded files by running `composer dump-autoload`. + +## Available Helpers + +- [app](#app) +- [config](#config) +- [view](#view) +- [route](#route) +- [redirect](#redirect) +- [session](#session) +- [request](#request) +- [back](#back) +- [report](#report) +- [logger](#logger) + +### app + +The `app` helper returns the current reference to the container. + +```php +$app = \Rareloop\Lumberjack\Helpers::app(); + +// Global function +$app = app(); +``` + +You can resolve objects from the container by passing in the class name or reference into `app()`. + +```php +$gateway = \Rareloop\Lumberjack\Helpers::app(\App\PaymentGateway::class); + +// Global function +$gateway = app(\App\PaymentGateway::class); +``` + +### config + +The `config` helper allows you to get values from your config. + +```php +$value = \Rareloop\Lumberjack\Helpers::config('app.environment'); + +// Global function +$value = config('app.environment'); +``` + +By passing in an array to the `config` helper you can set config values. + +```php +\Rareloop\Lumberjack\Helpers::config(['app.logs.enabled' => false]); + +// Global function +config(['app.logs.enabled' => false]); +``` + +### view + +The `view` helper returns a new `Rareloop\Lumberjack\Http\Responses\TimberResponse`. + +```php +return \Rareloop\Lumberjack\Helpers::view('templates/posts.twig', $context, 200, $headers); + +// Global function +return view('templates/posts.twig', $context, 200, $headers); +``` + +### route + +The `route` helper generates a URL from a named route. + +```php +$url = \Rareloop\Lumberjack\Helpers::route('posts.index'); + +// Global function +$url = route('posts.index'); +``` + +If the route requires parameters you can be pass an associative array as a second parameter: + +```php +$url = \Rareloop\Lumberjack\Helpers::route('posts.show', ['id' => 123]); + +// Global function +$url = route('posts.show', ['id' => 123]); +``` + +### redirect + +The `redirect` helper returns a new `Zend\Diactoros\Response\RedirectResponse`, which redirects the user to a given URL. + +```php +$url = \Rareloop\Lumberjack\Helpers::redirect('/auth/login', 200, $headers); + +// Global function +$url = redirect('/auth/login', 200, $headers); +``` + +### session + +You can use the `session` helper to retrieve and store data in the current session. Passing in 1 (string) argument will get the value of that item from the session. Passing in an array of key/value pairs will add each pair to the session. + +```php +// Get a value from the session +$name = \Rareloop\Lumberjack\Helpers::session('name'); + +// Get a value from the session, with a default +$name = \Rareloop\Lumberjack\Helpers::session('name', 'default'); + +// Set a value to the session +\Rareloop\Lumberjack\Helpers::session(['key' => 'value']); + +// Call any method on a session +\Rareloop\Lumberjack\Helpers::session()->forget('key'); +``` + +And using the global function instead: + +```php +// Get a value from the session +$name = session('name'); + +// Get a value from the session, with a default +$name = session('name', 'default'); + +// Store a value to the session +session(['key' => 'value']); + +// Call any method on a session +session()->forget('key'); +``` + +### request + +The `request` helper returns the current `ServerRequest` object, which means you get access to [all these available methods](http-requests#usage). + +```php +$request = \Rareloop\Lumberjack\Helpers::request(); + +// Global function +$request = request(); +``` + +For example, to get the current url: + +```php +$currentUrl = request()->url(); // e.g. http://test.com/path +``` + +For more information, see the [HTTP Requests documentation](http-requests). + +### back + +Returns a RedirectResponse, which will redirect the user to the previous URL. + +```php +return \Rareloop\Lumberjack\Helpers::back(); + +// Global function +return back(); +``` + +If you need to pass any data back to the previous page, you can flash items to the session using `with()`: + +```php +// Chain 'with' multiple times +return \Rareloop\Lumberjack\Helpers::back() + ->with('key', 'value') + ->with('foo', 'bar'); + +// Or use an array with key/value pairs +return \Rareloop\Lumberjack\Helpers::back()->with([ + 'key' => 'value', + 'foo' => 'bar', +]); + +// Global function +return back() + ->with('key', 'value') + ->with('foo', 'bar'); + +// Or use an array with key/value pairs +return back()->with([ + 'key' => 'value', + 'foo' => 'bar', +]); +``` + +### report + +Calls the `report` method on the Exception Handler, to ensure that an exception is reported. + +```php +\Rareloop\Lumberjack\Helpers::report($exception); + +// Global function +report($exception); +``` + +This is particularly useful if your theme needs to _swallow_ any exceptions so they do not break the site, but you still wish to have the error logged. For example: + +```php +try { + // This may throw an exception... + $comment = Comment::add($data); + + return JsonResponse($comment, 200); +} catch (Exception $exception) { + // Report the exception + report($exception); + + // Swallow the exception, and instead return a response + return JsonResponse([], 400); +} +``` + +"Swallowing" here simply means that the exception is unable to bubble all the way up to the Exception Handler where it normally gets reported. + +### logger + +:::info +Available in `v4.3.0` and above +::: + +The `logger` helper can be used to write **debug** messages to your logs. + +```php +\Rareloop\Lumberjack\Helpers::logger('Example message'); + +// Global function +logger('Example message'); +``` + +You can also pass in an array of additional data alongside your message. + +```php +\Rareloop\Lumberjack\Helpers::logger('Product added to basket', ['id' => $product->id]); + +// Global function +logger('Product added to basket', ['id' => $product->id]); +``` + +If you need to access the logger class itself, to log different types of errors for example, you can use the `logger` function with no arguments. This will get you an instance of the PSR3 compliant logger that is bound to the container. By default Lumberjack uses `Monolog\Logger`. + +```php +\Rareloop\Lumberjack\Helpers::logger()->warning('Example warning'); + +// Global function +logger()->warning('Example warning'); +``` diff --git a/versioned_docs/version-v8.3/the-basics/http-requests.md b/versioned_docs/version-v8.3/the-basics/http-requests.md new file mode 100644 index 0000000..144dee0 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/http-requests.md @@ -0,0 +1,105 @@ +--- +sidebar_position: 7 +--- + +# HTTP Requests + +## Accessing the Request Instance + +To access the current Request object you can inject it into your Controller by using the `Rareloop\Lumberjack\Http\ServerRequest` type hint, e.g. + +```php +use Rareloop\Lumberjack\Http\ServerRequest; + +class MyController +{ + public function show(ServerRequest $request) + { + + } +} +``` + +You can also use the `request()` [helper](helpers#adding-global-helpers) to access the request from anywhere in your theme: + +```php +use Rareloop\Lumberjack\Helpers; + +$request = Helpers::request(); + +// Or if you have global helpers enabled: +$request = request(); +``` + +## Usage + +### Get the method + +```php +$request->getMethod(); // e.g. GET +$request->isMethod('GET'); // e.g. true +``` + +### Get the path + +```php +$request->path(); // e.g. /path +``` + +### Get the URL + +```php +$request->url(); // e.g. http://test.com/path +$request->fullUrl(); // e.g. http://test.com/path?foo=bar +``` + +### Get all query params + +```php +$request->query(); +``` + +### Get a specific query param + +```php +$request->query('name'); +$request->query('name', 'Jane'); // Defaults to "Jane" if not set +``` + +### Get all post params + +```php +$request->post(); +``` + +### Get a specific post param + +```php +$request->post('name'); +$request->post('name', 'Jane'); // Defaults to "Jane" if not set +``` + +### Get all input params + +```php +$request->input(); +``` + +### Get a specific input param + +```php +$request->input('name'); +$request->input('name', 'Jane'); // Defaults to "Jane" if not set +``` + +### Does the request have a specific input key? + +```php +if ($request->has('name')) { + // do something +} + +if ($request->has(['name', 'age'])) { + // do something if both 'name' and 'age' are present +} +``` diff --git a/versioned_docs/version-v8.3/the-basics/http-responses.md b/versioned_docs/version-v8.3/the-basics/http-responses.md new file mode 100644 index 0000000..53450d8 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/http-responses.md @@ -0,0 +1,145 @@ +--- +sidebar_position: 8 +--- + +# HTTP Responses + +## Introduction + +All of your WordPress and Router controllers should return a PSR7 compliant response to be sent back to the user's browser. Lumberjack provides a number of Response types which should cover the majority of cases. + +:::info +If your Controller returns a string it will be automatically converted to an `HtmlResponse` object with a `200` status code. +::: + +## Available Response Objects + +### Timber Response + +The most common use-case will be to render a Twig view with some associated data. Using Timber on it's own, your code would look like this: + +```php +use Timber\Timber; + +... + +return Timber::render('home.twig', $context); +``` + +In Lumberjack, you should take advantage of the `Rareloop\Lumberjack\Http\Responses\TimberResponse` object to achieve the same thing: + +```php +use Rareloop\Lumberjack\Http\Responses\TimberResponse; + +... + +return new TimberResponse('home.twig', $context); +``` + +#### Context Flattening + +When passing context data to TimberResponse, any objects that implement the `Rareloop\Lumberjack\Contracts\Arrayable` contract will automatically be flattened to a standard PHP array. This means that it is safe to use objects such as `Collection` and `ViewModel` in your data without it causing issues with Twig. + +For more information, see the [View Models](view-models) and [Collections](collections) documentation. + +### Redirect Response + +Redirecting to a different URL can be done by returning an instance of `Rareloop\Lumberjack\Http\Responses\RedirectResponse`. + +```php +use Rareloop\Lumberjack\Http\Responses\RedirectResponse; + +... + +return new RedirectResponse('/another/page'); +``` + +#### Adding Flash Data + +If you want to redirect to a URL and also flash some data to the session, you can use the `with()` method. + +```php +return new RedirectResponse('/another/page') + ->with('error', 'Something went wrong'); +``` + +### Diactoros Responses + +Lumberjack also includes the fantastic [Zend Diactoros](https://github.com/zendframework/zend-diactoros) package which provides additional PSR7 compliant Response Objects. + +```php +// Check out their documentation for further details and examples: +// https://zendframework.github.io/zend-diactoros/ +$response = new Zend\Diactoros\Response\TextResponse('Hello world!'); +$response = new Zend\Diactoros\Response\HtmlResponse($htmlContent); +$response = new Zend\Diactoros\Response\XmlResponse($xml); +$response = new Zend\Diactoros\Response\JsonResponse($data); +$response = new Zend\Diactoros\Response\EmptyResponse(); // Basic 204 response: +``` + +## Adding Status Code & Headers + +One of the benefits of using Response Objects is that they make it easier to control the HTTP status code & headers. + +All the Response Objects bundled with Lumberjack let you set both the status code and headers in their constructor. + +```php +use Zend\Diactoros\Response\JsonResponse; + +return new JsonResponse($data, 422, ['X-Total-Validation-Errors' => 2]); +``` + +Or if you prefer, you can use the `withStatus` and `withHeader` methods instead. + +```php +use Zend\Diactoros\Response\JsonResponse; + +return (new JsonResponse($data, 422)) + ->withStatus(422) + ->withHeader('X-Total-Validation-Errors', 2); +``` + +## Responsable Objects + +In addition to supporting PSR7 compliant responses, Controllers can also return an object that implements the `Rareloop\Router\Responsable` interface. These objects provide a `toResponse()` method that will return an instance of a PSR7 Response. + +```php +// app/Http/Controllers/TestController.php +namespace App\Http\Controllers; + +use App\Exceptions\TestException; + +class TestController +{ + public function show() + { + return new TestException('Hello World'); + } +} + +// app/Exceptions/TestException.php +namespace App\Exceptions; + +use Rareloop\Router\Responsable; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; +use Zend\Diactoros\Response\JsonResponse; + +class TestException extends \Exception implements Responsable +{ + protected $reason; + + public function __construct($reason) + { + $this->reason = $reason; + parent::__construct(); + } + + public function toResponse(RequestInterface $request) : ResponseInterface + { + return new JsonResponse([ + 'error' => $this->reason, + ], 400); + } +} +``` diff --git a/versioned_docs/version-v8.3/the-basics/lifecycle.md b/versioned_docs/version-v8.3/the-basics/lifecycle.md new file mode 100644 index 0000000..e2eb56c --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/lifecycle.md @@ -0,0 +1,61 @@ +--- +sidebar_position: 1 +--- + +# Lifecycle + +## Introduction + +Understanding how Lumberjack works and fits into WordPress's lifecycle will help demystify some of the 'magic'. It can also be important to know the order in which things happen so your application doesn't have unexpected behaviour. + +## Starting at the beginning + +As WordPress uses a front controller, all requests will go through the `index.php` file. This then bootstraps WordPress, runs your `functions.php`, finds which template to load in your theme and then renders some HTML. + +Lumberjack is initialised within your `functions.php` file, meaning it bootstraps and runs before any pages in the [template hierarchy](http://pressupinc.com/blog/2013/08/understanding-wordpress-template-hierarchy/). + +## Service Providers + +Service providers are fundamental to bootstrapping the rest of the framework and all of its various parts. Within your theme's `config/app.php` file you have an item for `providers`. These are all the core components that make up Lumberjack. + +```php +/** + * List of providers to initialise during app boot + */ +'providers' => [ + Rareloop\Lumberjack\Providers\RouterServiceProvider::class, + Rareloop\Lumberjack\Providers\WordPressControllersServiceProvider::class, + Rareloop\Lumberjack\Providers\TimberServiceProvider::class, + Rareloop\Lumberjack\Providers\ImageSizesServiceProvider::class, + Rareloop\Lumberjack\Providers\CustomPostTypesServiceProvider::class, + Rareloop\Lumberjack\Providers\MenusServiceProvider::class, + Rareloop\Lumberjack\Providers\LogServiceProvider::class, + Rareloop\Lumberjack\Providers\ThemeSupportServiceProvider::class, + Rareloop\Lumberjack\Providers\LogServiceProvider::class, +], +``` + +By having them defined in your theme, you can remove or modify any of the core behaviour. Do this with caution though. This also means you can add your own service providers too and power up Lumberjack in your own way! + +Lumberjack loops through this array twice. The first time it calls the `register()` method on all of the service providers. Then after they are all register it calls the `boot()` method on each one. You can read more about service providers here: + +For more information, see the [Service Providers documentation](../container/service-providers). + +## Processing The Request + +The first service provider that runs is quite a fundamental one. The `RouterServiceProvider` has 2 important roles, which both trigger when WordPress had finished instantiating all plugins and the theme (during the [`wp_loaded` action](https://codex.wordpress.org/Plugin_API/Action_Reference/wp_loaded)). + +First, it transforms the HTTP request into a PSR7 compliant `ServerRequest` object. Read more about what that means here: + +For more information, see the [HTTP Requests documentation](http-requests). + +Next, it checks to see if any custom routes (from your theme's `routes.php` file) match the current URL. If it find a match, the request is handled and a response is returned. Otherwise the request carries on and gets handled by WordPress normally later. + +**That means any custom routes will always supersede any WordPress content with the same URL.** + +### WordPress routes + +Lumberjack doesn't interfere with how WordPress handles the request or how it decides which template to load (via the template hierarchy). + +`WordPressControllersServiceProvider` does however tweak the behaviour around _how_ the template is included. It hooks into `template_include` to check if the file has a controller class with the correct name. If it finds one, it calls the `handle()` method. Otherwise that file is treated as per normal. +This means that you don't have to use controllers if you don't want to. diff --git a/versioned_docs/version-v8.3/the-basics/middleware.md b/versioned_docs/version-v8.3/the-basics/middleware.md new file mode 100644 index 0000000..141fb13 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/middleware.md @@ -0,0 +1,263 @@ +--- +sidebar_position: 9 +--- + +# Middleware + +Lumberjack supports PSR-15/7 Middleware. Middleware can be added via the [Router](routing) to individual routes or route groups or via [WordPress Controllers](wordpress-controllers). + +## **Adding Middleware to a route** + +At it's simplest, adding Middleware to a route can be done by passing an object to the `middleware()` function: + +```php +$middleware = new AddHeaderMiddleware('X-Key1', 'abc'); + +Router::get('route/uri', '\MyNamespace\TestController@testMethod')->middleware($middleware); +``` + +Multiple middleware can be added by passing more params to the `middleware()` function: + +```php +$header = new AddHeaderMiddleware('X-Key1', 'abc'); +$auth = new AuthMiddleware(); + +Router::get('route/uri', '\MyNamespace\TestController@testMethod')->middleware($header, $auth); +``` + +Or alternatively, you can also pass an array of middleware: + +```php +$header = new AddHeaderMiddleware('X-Key1', 'abc'); +$auth = new AuthMiddleware(); + +Router::get('route/uri', '\MyNamespace\TestController@testMethod')->middleware([$header, $auth]); +``` + +## **Adding Middleware to a group** + +Middleware can also be added to a group. To do so you need to pass an array as the first parameter of the `group()`function instead of a string. + +```php +$header = new AddHeaderMiddleware('X-Key1', 'abc'); + +Router::group(['prefix' => 'my-prefix', 'middleware' => $header]), function ($group) { + $group->get('route1', function () {}); // GET `/my-prefix/route1` + $group->get('route2', function () {}); // GET `/my-prefix/route2` +}); +``` + +You can also pass an array of middleware if you need more than one: + +```php +$header = new AddHeaderMiddleware('X-Key1', 'abc'); +$auth = new AuthMiddleware(); + +Router::group(['prefix' => 'my-prefix', 'middleware' => [$header, $auth]]), function ($group) { + $group->get('route1', function () {}); // GET `/my-prefix/route1` + $group->get('route2', function () {}); // GET `/my-prefix/route2` +}); +``` + +## **Defining Middleware on Controllers** + +You can also apply Middleware on a Controller class too, either for use with the [Router](routing) or as a [WordPress Controller](wordpress-controllers). In order to do this your Controller must extend the `App\Http\Controllers\Controller` base class. + +Middleware is added by calling the `middleware()` function in your Controller's `__constructor()`. + +```php +use App\Http\Controllers\Controller; + +class MyController extends Controller +{ + public function __construct() + { + // Add one at a time + $this->middleware(new AddHeaderMiddleware('X-Key1', 'abc')); + $this->middleware(new AuthMiddleware()); + + // Add multiple with one method call + $this->middleware([ + new AddHeaderMiddleware('X-Key1', 'abc'), + new AuthMiddleware(), + ]); + } +} +``` + +By default all Middleware added via a Controller will affect all methods on that class. To limit what methods Middleware applies to you can use `only()` and `except()`: + +```php +use App\Http\Controllers\Controller; + +class MyController extends Controller +{ + public function __construct() + { + // Only apply to `send()` method + $this->middleware(new AddHeaderMiddleware('X-Key1', 'abc'))->only('send'); + + // Apply to all methods except `show()` method + $this->middleware(new AuthMiddleware())->except('show'); + + // Multiple methods can be provided in an array to both methods + $this->middleware(new AuthMiddleware())->except(['send', 'show']); + } +} +``` + +## Middleware Aliases + +:::info +Available in `v4.3.0` and above +::: + +Creating new instances of middleware in your routes or controllers can have a couple of negative outcomes: + +1. The objects are instantiated and take up memory whether they're used or not +2. Your route definitions can become less readable + +These issues can both be addressed using Middleware Aliases. Instead of creating instances in your code, you register a string alias that can be used instead. + +### Registering a Middleware Alias + +To register an alias you can use the `MiddlewareAliases` facade. It is recommended that you use this in the `boot()` method of the `AppServiceProvider` class. + +There are 3 ways to define your middleware alias: + +- A closure factory _(recommended - always creates a new instance when used)_ +- A class name _(always resolves a new instance from the Container when used)_ +- A previously instantiated object _(you don't get the benefits of lazy loading)_ + +:::info +_See "[\_Setting entries in the container_](../container/using-the-container#setting-entries-in-the-container)_" for more information about the differences between these. While only the class name uses the container, principally they behave in the same way with regards to lazy-loading and object instantiation_. +::: + +#### Using a closure factory (recommended) + +It is recommended that the alias is registered using a closure that acts as a factory, like so: + +```php +namespace App\Providers; + +use Rareloop\Lumberjack\Facades\MiddlewareAliases; + +class AppServiceProvider +{ + function boot() + { + // Create from closure factory + MiddlewareAliases::set('auth', function() { + return new AuthMiddleware; + }); + } +} +``` + +#### Using a class name + +```php +// Create from class name +MiddlewareAliases::set('cors', \My\Middleware\Cors::class); + +// Or +MiddlewareAliases::set('cors', '\My\Middleware\Cors'); +``` + +#### Using a previously instantiated object + +When using this method, you do not get the benefits of lazy loading. i.e. The object will be created whether or not it is needed for the current request. + +```php +// Create from existing object +MiddlewareAliases::set('addheader', new \My\Middleware\AddHeader()); +``` + +### Using a Middleware Alias + +Middleware Aliases can be used anywhere middleware can normally be used, both in the Router and through Controllers. + +If, for example, an Alias had been registered for an `AuthMiddleware` with the key `auth` like so: + +```php +MiddlewareAliases::set('auth', function() { + return new AuthMiddleware; +}); +``` + +You could use this in your route definition like this: + +```php +Router::get( + 'route/uri', + '\App\Http\Controllers\TestController@testMethod' +)->middleware('auth'); +``` + +### Middleware Alias Parameters + +You can register Middleware Aliases which accept parameters. It is advised if you're doing this to use the Closure Factory registration technique. + +```php +// Register in AppServiceProvider::boot() +MiddlewareAliases::set('addheader', function($key, $value) { + return new AddHeader($key, $value); +}); + +// Use in routes.php +Router::get( + 'hello-world', + 'MyController@hello' +)->middleware('addheader:X-Key:HeaderValue'); +``` + +In this example, `$key` will have the value `X-Key` and `$value` will have the value of `HeaderValue`. + +## Creating custom Middleware + +While you can use any PSR 15/7 Middleware, sometimes you need to write your own. In this example, we will create custom middleware that adds the response header `X-Foo`. + +First, create the class in `app/Http/Middleware/ExampleMiddleware.php` (create the folder if it doesn't exist) with the following content: + +```php +handle($request); + + return $response; + } +} +``` + +In our example, we want to modify the **response**. Below we add the `X-Foo` header to the response: + +```php +return $response->withHeader('X-Foo', 'Bar'); +``` + +If you need to modify the request before it gets passed to your application, you can do so before `$handler->handle($request)` gets called: + +```php +public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface +{ + // Chance to modify the request here before passing it into your application + + // Pass the request on (to the next middleware or your application) + $response = $handler->handle($request); + + // Chance to modify the response here before sending it back + + return $response; +} +``` diff --git a/versioned_docs/version-v8.3/the-basics/post-types.md b/versioned_docs/version-v8.3/the-basics/post-types.md new file mode 100644 index 0000000..96df783 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/post-types.md @@ -0,0 +1,182 @@ +--- +sidebar_position: 4 +--- + +# Post Types + +## Introduction + +Typically in WordPress when you're querying posts you get [`WP_Post`](https://codex.wordpress.org/Class_Reference/WP_Post) objects back. Timber have taken this a step further and return a `Timber/Post` object instead. This [has a ton of great helper methods and properties](https://timber.github.io/docs/reference/timber-post/) which makes it easier and more expressive to use. + +```php +$post = Timber::get_post(1); // \Rareloop\Lumberjack\Post +$posts = Timber::get_posts($wpQueryArray); // \Timber\PostQuery +``` + +:::info Note on Timber v2 +Timber v2 deprecated direct instantiation in favour of the `Timber::get_post()` factory implementation. When you call `get_post()`, Timber uses the Class Map to return the correct class for that post. + +**Lumberjack automatically registers your custom post types with the Timber Class Map** + +See: [Timber: Class Maps](https://timber.github.io/docs/v2/guides/class-maps/#the-post-class-map) +::: + +Lumberjack post types provide a static `query` method to make this simpler. + +```php +use Rareloop\Lumberjack\Post; + +$collection = Post::query($wpQueryArray); +``` + +This becomes especially powerful when you start registering **Custom Post Types**. + +```php +use App\PostTypes\Product; + +$collection = Product::query($wpQueryArray); +``` + +In this example `$collection` contains `App\PostType\Product` objects. That allows you to add your own methods to a product and encapsulate logic in one place. + +```php +use App\PostTypes\Product; + +$collection = Product::query($wpQueryArray); + +foreach ($collection as $product) { + echo $product->price(); +} +``` + +```php +namespace App\PostTypes; + +use Rareloop\Lumberjack\Post; + +class Product extends Post +{ + // ... + + public function price() + { + // Get the price from the ACF field for this product + return get_field('price', $this->id); + } +} +``` + +_If collections are new to you, be sure the check out the [Collections documentation](collections)._ + +## Register Custom Post Types + +First, create a new file in `app/PostTypes/`. We recommend using singular names. For this example, lets add a `Product.php` file there. + +You can use this boilerplate to get you started: + +```php +namespace App\PostTypes; + +use Rareloop\Lumberjack\Post; + +class Product extends Post +{ + /** + * Return the key used to register the post type with WordPress + * First parameter of the `register_post_type` function: + * https://codex.wordpress.org/Function_Reference/register_post_type + * + * @return string + */ + public static function getPostType() + { + return 'products'; + } + + /** + * Return the config to use to register the post type with WordPress + * Second parameter of the `register_post_type` function: + * https://codex.wordpress.org/Function_Reference/register_post_type + * + * @return array|null + */ + protected static function getPostTypeConfig() + { + return [ + 'labels' => [ + 'name' => __('Products'), + 'singular_name' => __('Product'), + 'add_new_item' => __('Add New Product'), + ], + 'public' => true, + ]; + } +} +``` + +Lumberjack will handle the registering of the post type for you. In order to do that, it requires 2 methods (documented above): + +- `getPostType()` +- `getPostTypeConfig()` + +In order for Lumberjack to register your post type, you need to add the class name to the `config/posttypes.php` config file. + +```php +return [ + /** + * List all the sub-classes of Rareloop\Lumberjack\Post in your app that you wish to + * automatically register with WordPress as part of the bootstrap process. + */ + 'register' => [ + App\PostTypes\Product::class, + ], +]; +``` + +And that's it! You can now start using your new Custom Post Type. + +:::info +**Tip**: Try and avoid using ACF's `get_field` outside of a Post Type class where possible. This will help make your application easy to change. +::: + +```php +$product = Timber::get_post(); + +// Bad +echo get_field('price', $product->id); + +// Good: The knowledge of how to get the price is encapsulated within the Product class +echo $product->price(); +``` + +## Available Methods for `Rareloop\Lumberjack\Post` + +Lumberjack's `Post` class extends `Timber\Post`, and adds some convenient methods for you: + +```php +use Rareloop\Lumberjack\Post; +use App\PostTypes\Product; + +// Get all published posts, with 10 per page, ordered ascending by title +$posts = Post::all(10, 'title', 'asc'); + +// Accepts the WP_Query args as an array. By default it will filter by published posts for the correct post type too +$products = Product::query(['s' => 'Toy Car']); +``` + +## Extending Post Types + +The Lumberjack `Post` class can be extended with custom functionality at runtime (the class is "macroable"). The following example adds an `acf` method to the `Post` class that can be used to access Advanced Custom Field (ACF) field values: + +```php +use Rareloop\Lumberjack\Post; + +// Add custom function +Post::macro('acf', function ($field) { + return get_field($field, $this->id); +}); + +// Use the functionality +$post = new Post; +$value = $post->acf('custom_field_name'); +``` diff --git a/versioned_docs/version-v8.3/the-basics/query-builder.md b/versioned_docs/version-v8.3/the-basics/query-builder.md new file mode 100644 index 0000000..2a46b40 --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/query-builder.md @@ -0,0 +1,593 @@ +--- +sidebar_position: 5 +--- + +# Query Builder + +Lumberjack has a built-in query builder which provides an expressive, fluent and explicit way of querying data in WordPress. It can be used instead of [WP_Query](https://codex.wordpress.org/Class_Reference/WP_Query) to query posts (of any type) and means you do not have to worry about "the loop". + +There are 2 ways in which you can use the query builder. Either on a [Post Type](post-types): + +```php +use App\PostTypes\Project; + +$projects = Project::builder() + ->orderBy('date', 'asc') + ->get(); +``` + +Or by using the query builder directly: + +```php +use App\PostTypes\Project; +use App\PostTypes\CaseStudy; +use Rareloop\Lumberjack\QueryBuilder; + +$posts = (new QueryBuilder)->wherePostType([ + Project::getPostType(), + CaseStudy::getPostType(), +]) +->orderBy('date', 'asc') +->get(); +``` + +## Using the query builder on a Post Type + +This is the most common way to use the query builder. You can start querying posts simply by using the `Rareloop\Lumberjack\Post` class. To start a query, use the `builder()` method. + +```php +Post::builder(); +``` + +This creates an instance of `Rareloop\Lumberjack\ScopedQueryBuilder`. This class does a couple of important things: + +### Returns the correct post objects + +When querying a post type, you will always get the same post object back in your results rather than `WP_Post` objects. + +For example, if you have a custom post type called `Employee`, when you query employees you will always get `Employee` objects back as results. Lets see what this looks like: + +```php +use App\PostTypes\Employee; + +$employees = Employee::builder()->get(); + +dump($employees); + +/* + Collection { + #items: array:2 [ + 0 => App\PostTypes\Employee, + 1 => App\PostTypes\Employee, + ] + } +*/ +``` + +The collection contains instances of the `Employee` class. This is extremely powerful as you now have access to all the behaviours that come with employees, as defined in your post type class. In this case, you may have a `photoUrl()` method on an `Employee` that knows (encapsulates) how to get the correct size image from the featured image: + +```php +class Employee extends Post +{ + ... + + public function photoUrl() : string + { + $thumbnail = $this->thumbnail(); + + if (empty($thumbnail)) { + return null; + } + + return $thumbnail->src('large'); + } +} +``` + +And when iterating through your results, you can safely use this `photoUrl()` method: + +```php +use App\PostTypes\Employee; + +$employees = Employee::builder()->get(); + +$employee = $employees->first(); + +// This will echo out the featured image url if there is one +echo $employee->photoUrl(); +``` + +:::info +All post types extend [Timber's Post object](https://timber.github.io/docs/reference/timber-post/), so you get access to all of their behaviour out of the box. + +The example above is making use of Timber's `thumbnail()` method on a [Post](https://timber.github.io/docs/reference/timber-post/), and `src()` method on an [Image](https://timber.github.io/docs/reference/timber-image/). +::: + +_If collections are new to you, be sure the check out the [Collections documentation](collections)._ + +### Query scopes + +Sometimes you will need to perform the same filter on a query in multiple places within your theme. + +```php +// Get all featured posts, newest first +$featuredPostIds = [1, 2]; + +$posts = Post::whereIdIn($featuredPostIds) + ->orderBy('date', 'desc') + ->get(); + +... + +// Get the latest 3 featured posts +$featuredPostIds = [1, 2]; + +$posts = Post::whereIdIn($featuredPostIds) + ->orderBy('date', 'desc') + ->limit(3) + ->get(); +``` + +In this example, we are scoping the query to only show featured images. However there's 2 issues with this: + +1. We doing it twice, without reusing any code +2. It can be unclear as to what you are doing + +Instead, We can encapsulate the knowledge about how to find featured posts by creating a **query scope** on our post type: + +```php +namespace App\PostTypes; + +use Rareloop\Lumberjack\Post as LumberjackPost; + +class Post extends LumberjackPost +{ + ... + + public function scopeFeatured($query) + { + $featuredPostIds = [1, 2]; + + return $query->whereIdIn($featuredPostIds); + } +} +``` + +Now we have a query scope, we can refactor our previous queries, making them more declarative and easier to change: + +```php +// Get all featured posts, newest first +$posts = Post::featured() + ->orderBy('date', 'desc') + ->get(); + +... + +// Get the latest 3 featured posts +$posts = Post::featured() + ->orderBy('date', 'desc') + ->limit(3) + ->get(); +``` + +:::info +Query scopes must start with the word `scope`, and must follow with the name of the method you want available to the builder. The method should also be defined in `CamelCase`. For example: + +`scopeFoo()` will allow you to call `foo()` on a query. + +`scopeFooBar()` will allow you to call `fooBar()` on a query. +::: + +You can also pass through parameters into the query scope: + +```php +namespace App\PostTypes; + +use Rareloop\Lumberjack\Post as LumberjackPost; + +class Post extends LumberjackPost +{ + ... + + public function scopeExclude($query, $postId) + { + return $query->whereIdNotIn([$postId]); + } +} + +... + +// Get all featured posts, newest first, excluding post id 1 +$posts = Post::exclude(1) + ->orderBy('date', 'desc') + ->get(); +``` + +## Available methods + +All the available methods can be chained, with the exclusion of `getParameters` and `get`. + +- [getParameters](#getparameters) +- [wherePostType](#whereposttypeposttype) +- [whereIdIn](#whereidinarray-ids) +- [whereIdNotIn](#whereidnotinarray-ids) +- [whereStatus](#wherestatus) +- [whereMeta](#wheremetakey-value-compare---type--null) +- [whereMetaRelationshipIs](#wheremetarelationshipisstring-relation) +- [limit](#limitlimit) +- [offset](#offsetoffset) +- [orderBy](#orderbyorderby-order--asc) +- [get](#get) +- [first](#first) +- [as](#aspostclass) +- [clone](#clone) + +### getParameters + +**returns**: `array` + +Get the current state of the query builder, as an array. These parameters can be directly fed into WP_Query as arguments. + +For example: + +```php +$parameters = Post::builder() + ->limit(3) + ->orderBy('date', 'desc') + ->getParameters(); + +// $parameters would look like this: +// [ +// "post_type" => "post" +// "posts_per_page" => 3 +// "orderby" => "date" +// "order" => "DESC" +// ] +``` + +This can be useful if you need to add your own arguments that the query builder does not support. + +```php +$parameters = Post::builder() + ->limit(3) + ->orderBy('date', 'desc') + ->getParameters(); + +$parameters['author_name'] = 'Adam'; + +$query = new WP_Query($parameters); +``` + +_Alternatively, you can add your own methods to the query builder using macros. See_ [_Extending the Query Builder_](#extending-the-query-builder)_._ + +### wherePostType($postType) + +| Parameter | Type | Description | +| :---------- | :------------------ | :------------------ | +| `$postType` | `string` \| `array` | e.g. 'post', 'page' | + +Scope the query to a particular post type, or post types. + +Populates `post_type` in `WP_Query`. + +```php +// Single +$query->wherePostType('page'); + +// Multiple +$query->wherePostType (['page', 'jobs']): +``` + +When using the query builder from a post type, the query is automatically scoped to the correct post type. + +```php +// This automatically sets the post type on the query to the Job post type +$jobs = Job::builder()->get(); +``` + +_Reference:_ [_WP_Query - Type Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Type_Parameters) + +### whereIdIn(array $ids) + +| Parameters | Type | Description | +| :--------- | :------ | :------------------- | +| `$ids` | `array` | An array of post IDs | + +Scope the query to only look for specific post IDs. + +Sets the `post__in` argument in `WP_Query`. + +_Reference:_ [_WP_Query - Post & Page Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Post_.26_Page_Parameters) + +### whereIdNotIn(array $ids) + +| Parameters | Type | Description | +| :--------- | :------ | :------------------- | +| `$ids` | `array` | An array of post IDs | + +Scope the query to exclude specific post IDs. + +Sets the `post__not_in` argument in `WP_Query`. + +_Reference:_ [_WP_Query - Post & Page Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Post_.26_Page_Parameters) + +### whereStatus() + +This method can either take an array of statuses, or multiple parameters for each status: + +**Array of statuses:** + +| Parameters | Type | Description | +| :---------- | :------ | :---------------------------------------------- | +| `$statuses` | `array` | An array of statuses. e.g. `publish` or `draft` | + +```php +$query->whereStatus(['publish', 'draft']); +``` + +**Multiple parameters:** + +| Parameters | Type | Description | +| :--------- | :------- | :---------------------------------- | +| `$status` | `string` | A status. e.g. `publish` or `draft` | +| `$status` | `string` | A status. e.g. `publish` or `draft` | +| ... | ... | ... | + +```php +$query->whereStatus('publish', 'draft'); +``` + +Scope the query to only include posts with the given status. By default WordPress will only look for published posts, so you only need to use this method if you need to get posts with other statuses. + +Sets the `post_status` argument in `WP_Query`. + +_Reference:_ [_WP_Query - Status Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters) + +### whereMeta($key, $value, $compare = '=', $type = null) + +| Parameters | Type | Description | +| :--------- | :----------------- | :-------------------------------------------------------------------------------------------------- | +| `$key` | `string` | The meta key | +| `$value` | `string` | The meta value | +| `$compare` | `string` | Optional. Defaults to `=` | +| `$type` | `string` \| `null` | Optional. Defaults to `null`. Pass in a value here to define the custom field type. e.g. `numeric`. | + +Scope posts that have the specified custom meta fields. + +Adds an array of meta query arguments to the array of `meta_query` arguments on `WP_Query`. + +```php +'meta_query' => [ + [ + 'key' => 'lead', + 'value' => 'Lorem ipsum %', + 'compare' = 'LIKE', + ] +] +``` + +:::info +**Note:** `meta_query` takes an **array** of meta query arguments **arrays** (it takes an array of arrays) +::: + +The above example can be written like so: + +```php +$query->whereMeta('lead', 'Lorem ipsum %', 'LIKE'); +``` + +You can also add multiple meta queries. + +```php +$query->whereMeta('lead', 'Lorem ipsum %', 'LIKE') + ->whereMeta('price', [20, 100], 'BETWEEN', 'numeric'); +``` + +This will yield the following parameters: + +```php +'meta_query' => [ + [ + 'key' => 'lead', + 'value' => 'Lorem ipsum %', + 'compare' = 'LIKE', + ], + [ + 'key' => 'price', + 'value' => [20, 100], + 'compare' = 'BETWEEN', + 'type' => 'numeric', + ] +] +``` + +_Reference:_ [_WP_Query - Custom Field Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters) + +### whereMetaRelationshipIs(string $relation) + +| Parameters | Type | Description | +| :---------- | :------- | :------------------------------------------------------------------ | +| `$relation` | `string` | The type of relationship between meta queries. Accepts `and` & `or` | + +Sets the `relation` field for your meta queries, for `WP_Query`. + +```php +$query->whereMeta('lead', 'Lorem ipsum %', 'LIKE') + ->whereMeta('price', [20, 100], 'BETWEEN', 'numeric') + ->whereMetaRelationshipIs('or'); +``` + +This will yield the following parameters, adding the `'relation' => 'or'` to the meta query. + +```php +'meta_query' => [ + 'relation' => 'or', + [ + 'key' => 'lead', + 'value' => 'Lorem ipsum %', + 'compare' = 'LIKE', + ], + [ + 'key' => 'price', + 'value' => [20, 100], + 'compare' = 'BETWEEN', + 'type' => 'numeric', + ] +] +``` + +_Reference:_ [_WP_Query - Custom Field Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters) + +### limit($limit) + +| Parameter | Type | Description | +| :-------- | :---- | :---------- | +| `$limit` | `int` | e.g. 25 | + +Set the number of results to get back from the query. + +Sets the `posts_per_page` argument in `WP_Query`. + +_Reference:_ [_WP_Query - Pagination Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters) + +### offset($offset) + +| Parameter | Type | Description | +| :-------- | :---- | :---------- | +| `$offset` | `int` | e.g. 50 | + +Set the number of results to displace or pass over. + +Sets the `offset` argument in `WP_Query`. + +_Reference:_ [_WP_Query - Pagination Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters) + +### orderBy($orderBy, $order = 'asc') + +| Parameter | Type | Description | +| :--------- | :------- | :-------------------------------------- | +| `$orderBy` | `string` | e.g. 'menu_order' | +| `$order` | `string` | Optional. Defaults to 'asc' (ascending) | + +Sort retrieved posts by parameter, e.g. date, title, menu_order. + +Sets the `orderby` and `order` arguments in `WP_Query`. + +```php +$query->orderBy('title', 'asc'); +``` + +_Reference:_ [_WP_Query - Order & Orderby Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters) + +### orderByMeta($metaKey, $order = 'asc', $type = null) + +| Parameter | Type | Description | +| :--------- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `$metaKey` | `string` | The meta key to order by | +| `$order` | `string` | Optional. Defaults to 'asc' (ascending) | +| `$type` | `string` | Optional. Defaults to null. Sorting will be alphabetical for strings. When dealing with numbers, you can get some unexpected results (e.g. 1, 3, 34, 4, 56, 6, etc, rather than 1, 3, 4, 6, 34, 56 as you might naturally expect). Pass in 'numeric' here if you plan on sorting numbers. | + +Sets the `orderby` argument for `WP_Query` to `meta_value` when ordering strings, and `meta_value_num` when ordering numbers. + +_Reference:_ [_WP_Query - Order & Orderby Parameters_](https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters) + +### as($postClass) + +| Parameters | Type | Description | +| :----------- | :------- | :------------------------------------------------------------------ | +| `$postClass` | `string` | The name of the post class that you want the results transformed to | + +When using `WP_Query`, you get an array of `WP_Post` objects back. The query builder will instead return an array of `Rareloop\Lumberjack\Post` objects back. + +You can use this method to change what object is returned from the query builder. + +```php +use App\PostTypes\Event; + +// Get an array of Event objects back +$query->wherePostType('event') + ->as(Event::class) + ->get(); +``` + +:::info +Note: When using the query builder on a post type, this conversion is done automatically. For example: + +```php +// Get an array of Event object +$events = Event::get(); +``` + +::: + +_Reference:_ [_Timber - get_posts()_](https://timber.github.io/docs/reference/timber/#get-posts) + +### get() + +Execute the query and return a `Collection` of post objects. + +```php +$posts = $query->whereMeta('price', 100, '>', 'numeric') + ->get(); +``` + +### first() + +Execute the query and return the first post object. Returns `null` if there are no results. + +```php +$post = $query->whereMeta('price', 100, '>', 'numeric') + ->first(); +``` + +### clone() + +Duplicates a new instance of the query builder with all the current parameters. You can modify this query builder instance separately to the original. + +This can be useful if you have similar queries with subtle differences, as it saves you duplicating the commonalities between them. + +```php +$baseQuery = (new QueryBuilder) + ->wherePostType(Announcement::getPostType()) + ->forCurrentUser(); // Some custom Query Scope, for example + +$counts = [ + 'all' => $baseQuery->clone()->whereStatus('publish', 'draft', 'pending')->get()->count(), + 'publish' => $baseQuery->clone()->whereStatus('publish')->get()->count(), + 'draft' => $baseQuery->clone()->whereStatus('draft')->get()->count(), + 'pending' => $baseQuery->clone()->whereStatus('pending')->get()->count(), +]; +``` + +## Extending the query builder + +The Lumberjack `QueryBuilder` class can be extended with custom functionality at runtime (the class is "macroable"). The following example adds a `search` method to the `QueryBuilder` class that can be used to filter results based on a keyword search: + +```php +use Rareloop\Lumberjack\QueryBuilder; + +// Add custom function +QueryBuilder::macro('search', function ($term) { + $this->params['s'] = $term; + + return $this; +}); + +QueryBuilder::macro('writtenByCurrentUser', function () { + $this->params['author'] = get_current_user_id(); + + return $this; +}); + +// Use the functionality +$posts = (new QueryBuilder()) + ->search('Elephant') + ->writtenByCurrentUser() + ->get(); + +// Or on a post type +$posts = Post::builder() + ->search('Elephant') + ->writtenByCurrentUser() + ->get(); +``` diff --git a/versioned_docs/version-v8.3/the-basics/routing.md b/versioned_docs/version-v8.3/the-basics/routing.md new file mode 100644 index 0000000..3ad3acf --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/routing.md @@ -0,0 +1,292 @@ +--- +sidebar_position: 2 +--- + +# Routing + +## Introduction + +Sometimes you may want to create a page on your website but not need/want it editable in WordPress. That's when the custom Lumberjack router comes into play. It can also be used to make AJAX endpoints. + +:::warning +If you set up a custom route that has the same URL as a WordPress page, the router takes priority. +::: + +:::info +Route closures and controller functions are automatically dependency injected from the container. +::: + +## Creating Routes + +Routing is handled by using the `Rareloop\Lumberjack\Facades\Router` Facade. The convention is to create your Routes in the `routes.php` file at the base of your theme. + +Typically, you only need to allow one HTTP verb for a route (e.g. `POST` or `GET`). To create a route, use the HTTP verb as the method name. The first parameter is the URI and the second is the code you wish to execute when that route is matched. + +```php +Router::get('test/route', function () {}); +Router::post('test/route', function () {}); +Router::put('test/route', function () {}); +Router::patch('test/route', function () {}); +Router::delete('test/route', function () {}); +Router::options('test/route', function () {}); +``` + +:::info +WordPress doesn't know anything about custom routes, so you may need to manually handle things like the page meta (e.g. title). Generally it is best to use WordPress where you can and use custom routes for anything non-standard. + +Some good candidates for a custom route could include: + +- An AJAX endpoint +- An endpoint to POST a form to (which could send an email) +- A custom e-commerce checkout workflow (e.g. basket, checkout, confirmation pages) + ::: + +### Setting the page title for custom routes + +If you need to set the page title for your custom route, you can manually call the `wp_title` filter. For example: + +```php +namespace App\Http\Controllers; + +class TestController +{ + public function __construct() + { + add_filter('wp_title', function ($title) { + return 'My Custom Title'; + }); + } + + public function show() + { + return 'Hello World'; + } +} +``` + +If your controller has multiple methods, then you could do something like this: + +```php +namespace App\Http\Controllers; + +class TestController +{ + protected $pageTitle; + + public function __construct() + { + add_filter('wp_title', function ($title) { + if (!empty($this->pageTitle)) { + return $this->pageTitle; + } + + return $title; + }); + } + + protected function setPageTitle(string $title) { + $this->pageTitle = $title; + } + + public function basket() + { + $this->setPageTitle('Basket'); + + return 'Basket...'; + } + + public function checkout() + { + $this->setPageTitle('Checkout'); + + return 'Checkout...'; + } +} +``` + +## Route Parameters + +Parameters can be defined on routes using the `{keyName}` syntax. When a route that contains parameters is matched, those parameters are available as injectable parameters in your callback/controller. + +**The name of the route parameter and the controller parameter must be the same.** + +```php +Router::get('posts/{id}', function($id) { + +}); +``` + +As the parameters are injected by name, it doesn't matter which order you have the parameters in your callback: + +```php +// /posts/123/comments/1 +Router::get('posts/{postId}/comments/{commentId}', function($commentId, $postId) { + echo $commendId; // 1 + echo $postId; // 123 +}); +``` + +Or controller: + +```php +// routes.php +Router::get('posts/{postId}/comments/{commentId}', 'TestController@show'); + +// app/Http/Controllers/TestController.php +namespace App\Http\Controllers; + +class TestController +{ + public function show($postId, $commentId) + { + return 'Hello World'; + } +} +``` + +### Parameter Constraints + +By default, all parameters will match against all non `/` characters. You can make the match more specific by supplying a regular expression: + +```php +Router::get('posts/{id}', function () {})->where('id', '[0-9]+'); + +// Will match /posts/123 +// Won't match /posts/abc +``` + +## Named Routes + +Routes can be named so that their URL can be generated programatically: + +```php +Router::get('posts/all', function () {})->name('posts.index'); + +$url = Router::url('posts.index'); +``` + +If the route requires parameters you can be pass an associative array as a second parameter: + +```php +Router::get('posts/{id}', function () {})->name('posts.show'); + +$url = Router::url('posts.show', ['id' => 123]); +``` + +## Route Groups + +It is common to group similar routes behind a common prefix. This can be achieved using Route Groups: + +```php +Router::group('prefix', function ($group) { + $group->get('route1', function () {}); // `/prefix/route1` + $group->get('route2', function () {}); // `/prefix/route2` +}); +``` + +## Route Controllers + +If you'd rather use a class to group related route actions together you can pass a Controller String instead of a closure. + +The string takes the format `{name of class}@{name of method}`. The Router will be default look for classes in the `App\Controllers` namespace, so you don't need to include this prefix in the Controller String. + +```php +// routes.php +Router::get('route/uri', 'TestController@show'); + +// app/Http/Controllers/TestController.php +namespace App\Http\Controllers; + +class TestController +{ + public function show() + { + return 'Hello World'; + } +} +``` + +If you want to reference a Controller in another namespace you'll need to append the complete namespace to the classname: + +```php +// routes.php +Router::get('route/uri', '\My\Namespace\TestController@show'); + +// My/Namespace/TestController.php +namespace My\Namespace; + +class TestController +{ + public function show() + { + return 'Hello World'; + } +} +``` + +### **Map** + +If you need match a URL for multiple HTTP methods, you can use the `map` method and pass in an array of HTTP methods to match. + +```php +use Rareloop\Lumberjack\Facades\Router; + +// Creates a route that matches the uri `/posts/list` both GET +// and POST requests. +Router::map(['GET', 'POST'], 'posts/list', function () { + return 'Hello World'; +}); +``` + +`map()` takes 3 parameters: + +- `methods` (array): list of matching HTTP methods, valid values: + - `GET` + - `POST` + - `PUT` + - `PATCH` + - `DELETE` + - `OPTIONS` +- `uri` (string): The URI to match against +- `action` (function|string): Either a closure or a Controller string + +## Extending the Router + +The Lumberjack `Router` class can be extended with custom functionality at runtime (the class is "macroable"). The following example adds an `redirect` method to the `Router` class that can be used to easily declare redirect routes, without needing to handle the response logic yourself: + +```php +use Rareloop\Lumberjack\Facades\Router; + +// Add the custom functionality +Router::macro('redirect', function ($inputUrl, $outputUrl) { + $this->get($inputUrl, function () use ($outputUrl) { + return new RedirectResponse($outputUrl); + }); +}); + +// Use the custom functionality +Router::redirect('/old/url', '/new/url'); +``` + +It is also possible to extend the `Route` class too, this can be useful for encapsulating common route behaviour in a more fluent API. + +```php +use Rareloop\Lumberjack\Facades\Router; +use Rareloop\Router\Route; + +// Add the custom functionality +Route::macro('adminOnly', function () { + $this->middleware(new App\AdminMiddlewareOne); + $this->middleware(new App\AdminMiddlewareTwo); + $this->middleware(new App\AdminMiddlewareThree); + + return $this; +}); + +// Use the custom functionality +Router::get('route/uri', 'AdminController@action')->adminOnly(); +``` + +:::warning +Remember to `return $this` in your custom `Route` macro extensions so that the API remains chainable. +::: diff --git a/versioned_docs/version-v8.3/the-basics/session.md b/versioned_docs/version-v8.3/the-basics/session.md new file mode 100644 index 0000000..564e86a --- /dev/null +++ b/versioned_docs/version-v8.3/the-basics/session.md @@ -0,0 +1,259 @@ +--- +sidebar_position: 10 +--- + +# Sessions + +The HTTP protocol is inherently stateless. If you want to maintain some data between requests, you will need to use the Session. + +## Configuration + +The Session is configured using the `config/session.php` file. By default Lumberjack is configured to store all session data as files on the disk. + +## Usage + +:::info +If you're using the [global helpers](helpers#session), you can use the `session()` helper function instead of the `Session` facade. For example: + +```php +$value = session('key', 'default'); +``` + +::: + +### Retrieving Data + +The primary way to work with session data is via the `Session` Facade: + +```php +use Rareloop\Lumberjack\Facades\Session; + +$value = Session::get('key'); +``` + +You can also pass an optional second parameter to use as a default in the instance the requested key doesn't exist: + +```php +use Rareloop\Lumberjack\Facades\Session; + +$value = Session::get('key', 'default'); +``` + +#### Retrieving All Session Data + +You can use the `all()` function if you wish to retrieve all the session data: + +```php +use Rareloop\Lumberjack\Facades\Session; + +$data = Session::all(); +``` + +#### Determine If An Item Exists In The Session + +You can check if a specific key is stored in the session using the `has()` function: + +```php +use Rareloop\Lumberjack\Facades\Session; + +if (Session::has('key')) { + // Do something +} +``` + +#### Retrieve and remove + +If you wish to remove an item from the session but also retrieve it's current value, you can use the `pull()` function: + +```php +use Rareloop\Lumberjack\Facades\Session; + +$value = Session::pull('key'); +``` + +### Storing Data + +To store data into the session you use the `put()` function: + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::put('key', 'value'); +``` + +You can pass in an array of key/value pairs to add multiple items. + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::put([ + 'key' =>'value', + 'foo' => 'bar', +]); +``` + +#### Adding items to an array + +If you have an array in your session, you can add new data to it by using the `push()` function: + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::push('key', 'value'); + +Session::all(); // [ 'key' => ['value'] ] + +Session::push('key', 'another'); + +Session::all(); // [ 'key' => ['value', 'another] ] +``` + +### Flash Data + +There are times when you only want to keep session data for the next request, e.g. form values when a validation error occurs. + +You can achieve this easily in Lumberjack using the `flash()` function: + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::flash('key', 'value'); +``` + +You can pass in an array of key/value pairs to flash multiple items. + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::flash([ + 'key' =>'value', + 'foo' => 'bar', +]); +``` + +If you later decide that you need the data to persist in the session you can do this in two ways. Use the `keep()` to select specific keys to retain or `reflash()` to store all flash data for an additional request. + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::keep('key'); + +// or + +Session::reflash(); +``` + +### Deleting Data + +To remove a specific item from the session you use the `forget()` method. + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::forget('key'); +``` + +To remove multiple items from the session you can pass an array of keys into the `forget()` method. + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::forget(['key1', 'key2']); +``` + +To remove all items from the session, you can use the `flush()` method. + +```php +use Rareloop\Lumberjack\Facades\Session; + +Session::flush(); +``` + +## Adding Custom Storage Drivers + +Lumberjack is capable of using multiple different drivers for session storage. The default and only driver provided in the core is the `file` driver, which saves all session data to disk. + +It is simple to implement and register a new driver though. + +### Implement the driver + +Start by creating a class that implements the standard PHP [SessionHandlerInterface](http://php.net/manual/en/class.sessionhandlerinterface.php) that provides the storage functionality you require: + +```php +namespace App\Session\Drivers; + +class DatabaseSessionDriver implements \SessionHandlerInterface +{ + /** + * Perform and opening/initialisation required for this driver + * Note: In most cases this can be empty + */ + public function open ($save_path, $session_name) {} + + /** + * Perform and closing/shutdown required for this driver + * Note: In most cases this can be empty + */ + public function close () {} + + /** + * Return a string of the data associated with $session_id + */ + public function read ($session_id) {} + + /** + * Save the provided string data against $session_id + */ + public function write ($session_id, $session_data) {} + + /** + * Remove any data associated with $session_id + */ + public function destroy ($session_id) {} + + /** + * Remove all session data that is older than $maxlifetime + * Note: $maxlifetime is provided as a Unix timestamp + */ + public function gc ($maxlifetime) {} +} +``` + +### Register the driver + +To register the new driver you need to use a Service Provider. If you don't want to create a new provider you can use the `AppServiceProvider` which can be found in `app\Providers\AppServiceProvider.php`. + +Registration is done by calling `extend()` on the Session facade: + +```php +post_date); + + $context['card'] = [ + 'title' => $post->title, + 'description' => wp_trim_words($post->content, 3), + 'published' => $date->format('Y-m-d'), + ]; + + return new TimberResponse('single.twig', $context); + } +} + +``` + +## Creating a View Model + +First, create a View Model. With the example above, we want to transform a `Post` object to an array that has the following keys: + +- `title` +- `description` +- `published` + +First off, lets create an empty view model. + +```php +post = $post; + } +} +``` + +View models are automatically converted to arrays when passed into a `twig` template. **Public methods are used as keys in this array, and the method is executed to get the value.** + +Below we have added 3 public methods (`title`, `description` and `published`). These are the keys that our view needs. + +```php +post = $post; + } + + public function title(): string + { + return $this->post->title(); + } + + public function description(): string + { + return wp_trim_words($this->post->content, 3); + } + + public function published(): string + { + $date = new \DateTime($this->post->post_date); + return $date->format('Y-m-d'); + } +} +``` + +Now we can refactor our controller to use our view model instead: + +```php + [ + 'title' => 'Post Title', + 'description' => 'Lorem ipsum dolor...', + 'published' => '2019-02-23', + ], +] +``` + +:::info +Remember: All view models (and collections) in the context are automatically flattened to arrays before being passed to `twig` views. +::: + +### Manually converting view models to arrays + +If you need to convert a view model to an array before it gets passed into a view, then you can use the `toArray()` method. + +```php +$mediaCard = new MediaCardViewModel($post); + +$context['card'] = $mediaCard->toArray(); +$context['card']['link'] = $post->link(); +``` + +### Changing behaviour of array conversion + +There may be times where the automatic array conversion doesn't do quite what you need. For example, if your view needed the following data: + +```php +$context['cards'] = [ + [ + 'title' => 'Post Title', + 'description' => 'Lorem ipsum dolor...', + 'published' => '2019-02-23', + ], + [ + 'title' => 'Post Title 2', + 'description' => 'Lorem ipsum dolor...', + 'published' => '2019-02-26', + ], +]; +``` + +This can be achieved by writing your own `toArray` method on your view model. + +```php +posts = $posts; + } + + public function cards() + { + // Create a MediaCardViewModel for each post + return $this->posts->map(function (Post $post) { + return new MediaCardViewModel($post); + }); + } + + /** + * Overwrite the toArray method to return array of view models, with no key + */ + public function toArray(): array + { + return $this->cards()->toArray(); + } +} +``` + +## Keeping view models reusable + +When writing a view model, the `__construct()` should accept all the data it needs in order to do the transformation. + +For example, if you had a testimonial that has a quote and a citation, the view model could look something like this: + +```php +quote = $quote; + $this->citation = $citation; + } + + public function quote() + { + return $this->quote; + } + + + public function citation() + { + return $this->citation; + } +} +``` + +Now your view model is really generic, and does not care about where the data is coming from. If you give it a quote and a citation, it will make sure the `twig` view has the correct data. + +#### Named Constructors + +If your view model does not know about how to get data, then you will have to fetch that data in each controller that uses the view model. For example: + +```php +id); + $citation = get_field('testimonial_citation', $post->id); + + $context['testimonial'] = new TestimonialViewModel($quote, $citation); + + return new TimberResponse('mytemplate.twig', $context); + } +} +``` + +**In order to keep your view models generic, and your controllers light (and DRY) you can create something called a "named constructor" on your view model.** + +This is simply a `static` method on your view model that constructs the view model _for a specific use case_. + +In our example, we are creating a testimonial from a `Post` object. So we can add the following method to our view model: + +```php +id); + $citation = get_field('testimonial_citation', $post->id); + + // Create a new instance of this class + return new static($quote, $citation); + } + + public function __construct($quote, $citation) + { + $this->quote = $quote; + $this->citation = $citation; + } + + public function quote() + { + return $this->quote; + } + + + public function citation() + { + return $this->citation; + } +} +``` + +And we can now refactor our controller to use the named constructor like so: + +```php +set('post', $post); + + return new TimberResponse('home', $context); + } +} +``` + +This makes controllers much leaner, but critically, much more testable by de-coupling them from Timber. + +### Available Typehints + +Any object bound in the [Container](../container/using-the-container.md) can be typehinted, for example, `Application $app` or `\Rareloop\Lumberjack\LoggerInterface`. + +For each Lumberjack type, there's full support for child classes. For example, injecting a custom post type will respect your Timber classmap. + +| Typehint | Description | Timber Equivalent | +| ------------------------------------ | ------------------------------- | --------------------- | +| `\Rareloop\Lumberjack\TimberContext` | Get a Timber context singleton | `Timber::context()` | +| `\Rareloop\Lumberjack\PostQuery` | Get all the posts for the query | `Timber::get_posts()` | +| `\Rareloop\Lumberjack\Post` | Get the current Post object | `Timber::get_post()` | +| `\Your\Custom\PostType` | Get the current PostType | `Timber::get_post()` | +| `\Rareloop\Lumberjack\Term` | Get the current Term | `Timber::get_term()` | +| `\Your\Custom\CategoryTerm` | Get the current CategoryTerm | `Timber::get_term()` | +| `\Rareloop\Lumberjack\User` | Get the current User | `Timber::get_user()` | +| `\Your\Custom\AdminUser` | Get the current AdminUser | `Timber::get_user()` | + +:::note +For each of Lumberjack's Proxy objects, the upstream Timber classes/interfaces are also supported. For example, typehinting `\Timber\PostQuery` will return an instance of that class. +::: diff --git a/versioned_docs/version-v8.3/upgrade-guide.md b/versioned_docs/version-v8.3/upgrade-guide.md new file mode 100644 index 0000000..de3ecfc --- /dev/null +++ b/versioned_docs/version-v8.3/upgrade-guide.md @@ -0,0 +1,901 @@ +--- +id: upgrade-guide +title: Upgrade Guide +sidebar_position: 3 +--- + +# Upgrade Guide + +## Upgrading from v8.2 to v8.3 + +Estimated time for upgrade: 1 minute + +Lumberjack v8.3 is a minor release with no breaking changes. + +This release introduces a new default error page for production environments, provides an easier way to configure Ignition, and expands dependency injection support for WordPress controllers. + +See [Error Handling](./the-basics/error-handling) and [WordPress Controllers](./the-basics/wordpress-controllers.md#dependency-injection-in-wordpress-controllers). + +## Upgrading from v8 to v8.1 + +Estimated time for upgrade: 5 minutes + +### Minimum PHP version increased to PHP 8.3 + +:::warning +**Likelihood of impact: High** +::: + +As part of this upgrade, we have increased the minimum version of PHP we support to PHP 8.3. + +### PHP 8.5 Support + +With Lumberjack v8.1 comes support for PHP 8.5. Please note that WordPress still only has "beta support" for this version of PHP, which means that several plugins still output errors or deprecation warnings. + +Please carefully review your site to see if it's able to run PHP 8.5 and you will need to do your own migration to this version of PHP for your theme and upgrade any composer dependencies you are using where appropriate too. + +[PHP: Migrating from PHP 8.4.x to PHP 8.5.x - Manual](https://www.php.net/manual/en/migration84.php) + +### Configurable Ignition + +This version of Lumberjack provides configuration options for [Ignition](https://github.com/spatie/ignition). This feature is considered opt-in, and can be activated by creating `[theme]/config/ignition.php`. + +
+ + Example Ignition Configuration + +```php + env('IGNITION_EDITOR', 'vscode'), + + /* + |-------------------------------------------------------------------------- + | Theme + |-------------------------------------------------------------------------- + | + | Here you may specify which theme Ignition should use. + | + | Supported: "light", "dark", "auto" + | + */ + + 'theme' => env('IGNITION_THEME', 'auto'), + + /* + |-------------------------------------------------------------------------- + | Solution Providers + |-------------------------------------------------------------------------- + | + | List of solution providers that should be loaded. You may specify additional + | providers as fully qualified class names. + | + */ + + 'solution_providers' => [ + // from spatie/ignition + BadMethodCallSolutionProvider::class, + MergeConflictSolutionProvider::class, + UndefinedPropertySolutionProvider::class, + ], + + /* + |-------------------------------------------------------------------------- + | Ignored Solution Providers + |-------------------------------------------------------------------------- + | + | You may specify a list of solution providers (as fully qualified class + | names) that shouldn't be loaded. Ignition will ignore these classes + | and possible solutions provided by them will never be displayed. + | + */ + + 'ignored_solution_providers' => [], + + /* + |-------------------------------------------------------------------------- + | Runnable Solutions + |-------------------------------------------------------------------------- + | + | Some solutions that Ignition displays are runnable and can perform + | various tasks. By default, runnable solutions are only enabled when your + | app has debug mode enabled and the environment is `local` or + | `development`. + | + | Using the `IGNITION_ENABLE_RUNNABLE_SOLUTIONS` environment variable, you + | can override this behaviour and enable or disable runnable solutions + | regardless of the application's environment. + | + | Default: env('IGNITION_ENABLE_RUNNABLE_SOLUTIONS') + | + */ + + 'enable_runnable_solutions' => env('IGNITION_ENABLE_RUNNABLE_SOLUTIONS', 'false'), + + /* + |-------------------------------------------------------------------------- + | Remote Path Mapping + |-------------------------------------------------------------------------- + | + | If you are using a remote dev server, like Laravel Homestead, Docker, or + | even a remote VPS, it will be necessary to specify your path mapping. + | + | Leaving one, or both of these, empty or null will not trigger the remote + | URL changes and Ignition will treat your editor links as local files. + | + | "remote_sites_path" is an absolute base path for your sites or projects + | in Homestead, Vagrant, Docker, or another remote development server. + | + | Example value: "/home/vagrant/Code" + | + | "local_sites_path" is an absolute base path for your sites or projects + | on your local computer where your IDE or code editor is running on. + | + | Example values: "/Users//Code", "C:\Users\\Documents\Code" + | + */ + + 'remote_sites_path' => env('IGNITION_REMOTE_SITES_PATH', dirname(__DIR__)), + 'local_sites_path' => env('IGNITION_LOCAL_SITES_PATH', ''), + + /* + |-------------------------------------------------------------------------- + | Recorders + |-------------------------------------------------------------------------- + | + | Ignition registers a couple of recorders when it is enabled. Below you may + | specify a recorders will be used to record specific events. + | + */ + + 'recorders' => [], + + /* + * When a key is set, we'll send your exceptions to Open AI to generate a solution + */ + + 'open_ai_key' => env('IGNITION_OPEN_AI_KEY'), + + /* + |-------------------------------------------------------------------------- + | Include arguments + |-------------------------------------------------------------------------- + | + | Ignition show you stack traces of exceptions with the arguments that were + | passed to each method. This feature can be disabled here. + | + */ + + 'with_stack_frame_arguments' => true, + + /* + |-------------------------------------------------------------------------- + | Argument reducers + |-------------------------------------------------------------------------- + | + | Ignition show you stack traces of exceptions with the arguments that were + | passed to each method. To make these variables more readable, you can + | specify a list of classes here which summarize the variables. + | + */ + + 'argument_reducers' => [ + \Spatie\Backtrace\Arguments\Reducers\BaseTypeArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\ArrayArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\StdClassArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\EnumArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\ClosureArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\DateTimeArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\DateTimeZoneArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\SymphonyRequestArgumentReducer::class, + \Spatie\Backtrace\Arguments\Reducers\StringableArgumentReducer::class, + ], + +]; + +```` + +
+ +## Upgrading from v7 to v8 + +Estimated time for upgrade: 5 minutes + +### Minimum PHP version increased to PHP 8.1 + +:::warning +**Likelihood of impact: Medium** +::: + +As part of this upgrade we have increased the minimum version of PHP we support to PHP 8.1. + +### PHP 8.4 Support + +With Lumberjack v8 comes support for PHP 8.4. Please note that WordPress still only has "beta support" for this version of PHP, which means that several plugins still output errors or deprecation warnings. + +Please carefully review your site to see if it's able to run PHP 8.4 and you will need to do your own migration to this version of PHP for your theme and upgrade any composer dependencies you are using where appropriate too. + +[PHP: Migrating from PHP 8.3.x to PHP 8.4.x - Manual](https://www.php.net/manual/en/migration84.php) + +### Update composer dependencies + +You will need to update the following packages in your `composer.json` file: + +- `rareloop/lumberjack-core` to `^8.0` + +### Namespace changes + +In order to support PHP 8.4 we had to upgrade a number of packages, and also bring some outdated packages into core. With this comes some namespace changes. + +#### Laminas Zend Framework Bridge removed + +:::warning +**Likelihood of impact: High** +::: + +Any imports that **start with** `Zend\Diactoros` must be **re-written to** `Laminas\Diactoros` . + +**For example:** + +```diff +- use Zend\Diactoros\Response\JsonResponse; ++ use Laminas\Diactoros\Response\JsonResponse; +```` + +#### blast/facades package added to core + +:::warning +**Likelihood of impact: High** +::: + +All Blast namespaces will need to be modified as follows: + +```diff +- use Blast\Facades\AbstractFacade; ++ use Rareloop\Lumberjack\Facades\AbstractFacade; +``` + +```diff +- use Blast\Facades\FacadeFactory; ++ use Rareloop\Lumberjack\FacadeFactory; +``` + +#### Encryption package added to core + +:::warning +**Likelihood of impact: Low** +::: + +The dcrypt package we were using has been brought into core. It's unlikely you are using this in your site, but if you are you will need to change `Dcrypt\` to `Rareloop\Lumberjack\Dcrypt\`. + +**For example:** + +```diff +- use Dcrypt\AesCbc ++ use Rareloop\Lumberjack\Dcrypt\AesCbc; +``` + +### Logging + +:::warning +**Likelihood of impact: High** +::: + +Lumberjack uses Monolog for its logging under the hood and as part of this release we upgraded the version of Monolog. + +You will need to update any instances of `Monolog\Logger` in your application like so: + +```diff +'logs' => [ + 'enabled' => true, + 'path' => false, +- 'level' => Monolog\Logger::ERROR, ++ 'level' => Monolog\Level::Error, +], +``` + +### Illuminate packages + +:::warning +**Likelihood of impact: Medium** +::: + +We've upgraded `illuminate/*` packages to `10.x` - if your site depends on any they will also need to be upgraded to version 10. + +### Ignition + +:::warning +**Likelihood of impact: Low** +::: + +We've moved away from `symfony/debug` in favour of `spatie/ignition` to give you a much nicer error page. This should not impact anything in your website and you do not need to make any changes. + +[Ignition - Laravel Error Page](https://flareapp.io/ignition) + +## Upgrading from v6 to v7 + +Lumberjack v7 introduces Timber v2, which is likely to require broad changes. Generally speaking, we recommend following the [Timber v1 - v2 upgrade before](https://timber.github.io/docs/v2/upgrade-guides/2.0/) commencing this upgrade. + +:::info +When upgrading to v7, you'll likely have lots of old, unused `use` statements that should be removed +::: + +### Hatchet deprecated + +:::warning +**Likelihood of impact: Low** +::: + +If you're using Hatchet, our now-deprecated CLI tool, it should be removed + +1. Remove `rareloop/hatchet`, `rareloop/hatchet-migrations` from `composer.json` +2. Remove `/site/web/app/themes/[theme]/hatchet` +3. Remove `/site/web/app/themes/[theme]/config/hatchet.php` +4. Remove `/site/web/app/themes/[theme]/app/Commands` + +If any commands exist, they should be converted to use WP_CLI. + +### Timber-related changes + +#### Class maps + +:::warning +**Likelihood of impact: High** +::: + +In Timber v1, you had to tell it which post class you wanted back – for example: + +```php +// Get instance of Lumberjack\Post +$post = new Post(); + +// Get Lumberjack\Post objects back +$query = new PostQuery(false, Post::class); +``` + +In Timber v2, this is deprecated and `Timber::get_post()` and `Timber::get_posts()` must be used. To determine the post type, [class maps](https://timber.github.io/docs/v2/guides/class-maps/) are used. + +:::warning +Lumberjack will automatically register custom post types to the class map, but you will need to add `Post` and `Page` yourself. +::: + +Add the following to your `app/AppServiceProvider.php` `boot` method: + +```diff +class AppServiceProvider extends ServiceProvider { + + public function boot() + { ++ add_filter('timber/post/classmap', fn($classmap) => [ ++ ...$classmap, ++ Post::getPostType() => Post::class, ++ Page::getPostType() => Page::class, ++ ]); + } +} +``` + +#### Images + +:::warning +**Likelihood of impact: High** +::: + +We found the Timber v2 upgrade documentation didn't make this clear, but instantiating a `new \Timber\Image()` is deprecated and you should use `Timber::get_image()` instead. + +```diff +-$image = new Image($data); ++$image = Timber::get_image($data); +``` + +#### Update Menu.php + +:::warning +**Likelihood of impact: High** +::: + +Timber has removed the `MenuItemClass` and `PostClass` properties, so these can be removed from `app/Menu/Menu.php` + +```diff + Menu::class); ++ add_filter('timber/menuitem/class', fn() => Item::class); + } +} +``` + +#### empty() and ArrayObject + +:::warning +**Likelihood of impact: Medium** +::: + +When getting posts from Timber, you will now get an instance of `PostArrayObject` which can cause issues if your controller uses `empty` to check for results. + +For example: + +```diff +$children = $post->children(); + +- if (empty($children)) { // Always false ++ if (!$children->count()) { // OR count($children) === 0 + ... +} +``` + +## Upgrading to v6 from from v5 + +We aim to document all the changes that could impact your theme, and there may only be a portion that are applicable to your theme. + +Lumberjack v6 **adds support for PHP 8.1**. + +### Replacing "tightenco/collect" + +[Illuminate's collection package](https://packagist.org/packages/illuminate/collections) "collect" has been separated from the core Laravel codebase and therefore the Tightenco package is no longer necessary. + +Update namespaces for any support `Tightenco\Collect` classes you are using. + +For example, change these: + +```php +use Tightenco\Collect\Support\Collection; +use Tightenco\Collect\Support\Arr; +``` + +To these: + +```php +use Illuminate\Support\Collection; +use Illuminate\Support\Arr; +``` + +### Upgrading "rareloop/lumberjack-primer" + +If you are using [Primer](https://github.com/rareloop/primer) with Lumberjack, you will need to also upgrade the `rareloop/lumberjack-primer` package to v2. + +From: + +```json +"rareloop/lumberjack-primer": "^v1.0.0", +``` + +To: + +```json +"rareloop/lumberjack-primer": "^v2.0.0", +``` + +## Upgrading from v4.3 to v5 + +There is nothing that requires upgrading between these versions. + +## Upgrading to v4.3 from v4.2 + +There is nothing that requires upgrading between these versions. + +## Upgrading to v4.2 from v4.1 + +We aim to document all the changes that could impact your theme, and there may only be a portion that are applicable to your theme. + +### Extending controllers + +Create `app/Http/Controllers/Controller.php` with the following contents: + +```php + [ + ... + Rareloop\Lumberjack\Providers\QueryBuilderServiceProvider::class, + Rareloop\Lumberjack\Providers\SessionServiceProvider::class, + Rareloop\Lumberjack\Providers\EncryptionServiceProvider::class, +], +``` + +The query builder is now part of the core, rather than an external package. If you were using the package, you will need to remove its service provider from your list of `providers` above. + +### Exception Handler + +:::warning +**Likelihood Of Impact: Critical** +::: + +The type hint on the `render()` function has changed to the PSR interface from the concrete Zend implementation. + +Make the following change in `app/Exceptions/Handler.php`: + +From: + +```php +use Zend\Diactoros\ServerRequest; + +public function render(ServerRequest $request, Exception $e) : ResponseInterface +{ + +} +``` + +To: + +```php +use Psr\Http\Message\ServerRequestInterface; + +public function render(ServerRequestInterface $request, Exception $e) : ResponseInterface +{ + +} +``` + +No changes should be required to your application logic as Zend subclasses will already comply with the new interface. + +### Container + +:::warning +**Likelihood Of Impact: Medium** +::: + +The `bind()` method on the `Application` container is no longer a singleton by default when the value (2nd param) is not a primitive or object instance. + +When [binding a concrete implementation to an interface](./container/using-the-container.md#set-concrete-implementations-for-interfaces), using singletons by default can create unexpected side affects as state is maintained across instances. + +A new `singleton()` method has been provided to enable the previous behaviour. This enables the app developer to be more intentional about the behaviour they desire. + +For example: + +```php +// Singleton +$app->singleton(App\AppInterface::class, App\AppImplementation::class); +$object1 = $app->get(App\AppInterface::class); +$object2 = $app->get(App\AppInterface::class); + +// The same object is resolved from the container +$object1 === $object2; // true + +// Bind +$app->bind(App\AppInterface::class, App\AppImplementation::class); +$object1 = $app->get(App\AppInterface::class); +$object2 = $app->get(App\AppInterface::class); + +// The container resolves new instances, so the objects are not the same +$object1 === $object2; // false +``` + +[Using the Container](./container/using-the-container) + +### `ServerRequest` class (optional) + +:::warning +**Likelihood Of Impact: Optional, but recommended** +::: + +If you're injecting an instance of the Diactoros `ServerRequest` class into a Controller, you can now switch this out for the following class if you want to benefit from some of the [new helper functions](./the-basics/http-requests.md#usage): + +```php +use Rareloop\Lumberjack\Http\ServerRequest +``` + +For example: + +```php +use Rareloop\Lumberjack\Http\ServerRequest; + +class MyController +{ + public function show(ServerRequest $request) + { + $name = $request->input('name'); + } +} +``` + +:::info +If you have enabled [global helpers](./the-basics/helpers.md#request), you can use access the current `ServerRequest` instance using the `request()` helper instead of using dependency injection. For example: + +```php +class MyController +{ + public function show() + { + $name = $request->input('name'); + } +} +``` + +::: + +Here's a quick overview of what the new `ServerRequest` object can do. _If you are using_ [_global helpers_](./the-basics/helpers.md#request)_, you can replace_ `$request` _with_ `request()` _instead in the examples below:_ + +#### **Query Parameters** + +```php +// Get all query parameters +$request->query(); + +// Get a specific query parameter +$request->query('name'); + +// Get a specific query parameter with a default +$request->query('name', 'Jane'); +``` + +#### Input + +```php +// Get all input params (from $_GET and $_POST) +$request->input(); + +// Get a specific input parameter +$request->input('name'); + +// Get a specific input parameter, with a default +$request->input('name', 'Jane'); + +// Check if the request has a key +$request->has('name'); +``` + +[HTTP Requests](./the-basics/http-requests) + +### View Models + +:::warning +**Likelihood Of Impact: Medium** + +This is a previously undocumented feature. If you are using ViewModels, this is a major change to how they work. However, if you are not using ViewModels you do not need to do anything. +:::warning + +View Models are simple classes that allow you to transform data that would otherwise be defined in your controller. This allows for better encapsulation of code and allows your code to be re-used across your controllers (and even across themes). + +#### Upgrading existing ViewModels + +The `ViewModel` base class no longer extends from `stdClass` and so can no longer have arbitrary properties set on it. + +We'd suggest upgrading your existing ViewModels to either use public methods or public properties. If your project has a large number of ViewModel's, the simplest change is to specifically name all properties in the class. + +For example: + +```php +// Lumberjack v3 +use Rareloop\Lumberjack\ViewModel; + +class MyViewModel extends ViewModel +{ + public function __construct($post) + { + $this->title = $post->title; + $this->link = $post->link; + } +} +``` + +To: + +```php +// Lumberjack v4 +use Rareloop\Lumberjack\ViewModel; + +class MyViewModel extends ViewModel +{ + // Declare the class properties + public $title; + public $link; + + public function __construct($post) + { + $this->title = $post->title; + $this->link = $post->link; + } +} +``` + +### Binding of the Exception Handler + +:::warning +**Likelihood Of Impact: Very low** +::: + +In `bootstrap/app.php` you should change how the exception handler is bound to `Rareloop\Lumberjack\Exceptions\HandlerInterface`. + +From: + +```php +$app->bind(HandlerInterface::class, $app->make(Handler::class)); +``` + +To: + +```php +$app->singleton(HandlerInterface::class, Handler::class); +``` + +### `Helpers::app()` helper + +:::warning +**Likelihood Of Impact: Very low** +::: + +`Helpers::app()` (and the `app()` global counterpart) no longer use the `make()` method of the Application instance and now rely on `get()`. This provides much more consistent behaviour with other uses of the Container. If you still want to use the helpers to get `make()` behaviour you can change your code. + +From: + +```php +Helpers::app(MyClassName::class); +``` + +To: + +```php +Helpers::app()->make(MyClassName::class); +``` + +### `Router` class namespace + +:::warning +**Likelihood Of Impact: Very low** +::: + +If you resolve an instance of the `Router` class from the container, you'll need to change the class reference. + +**If you're just using the Router Facade, you do not need to change anything.** + +From: + +```php +use Rareloop\Router\Router +``` + +To: + +```php +use Rareloop\Lumberjack\Http\Router +``` + +### PSR-15 Middleware + +:::warning +**Likelihood Of Impact: Very low** + +The `http-interop/http-server-middleware` package has been deprecated in favour of the now official PSR-15 interfaces found in `psr/http-server-middleware`. + +Make sure any middleware used now complies with the `Psr\Http\Server\MiddlewareInterface` interface. +::: diff --git a/versioned_docs/version-v8.3/whats-new.md b/versioned_docs/version-v8.3/whats-new.md new file mode 100644 index 0000000..9e6a56a --- /dev/null +++ b/versioned_docs/version-v8.3/whats-new.md @@ -0,0 +1,521 @@ +--- +title: What's New +description: This release of Lumberjack is jam packed full of goodies. We have also added a whole lot more documentation, so grab a cuppa and make yourself comfy while we take you through all the changes. +sidebar_position: 1 +--- + +# What's New + +## What's new in v8.3 + +Lumberjack v8.3 is a minor release that introduces a styled default error page for production and refactors Ignition registration to improve extensibility. + +- **Production Error Page**: A clean, styled 'Lumberjack | status' fallback page is now displayed when debug mode is `false`, preventing blank white pages on errors. +- **Easier Ignition Configuration**: A new `Ignition` facade and `IgnitionServiceProvider` have been introduced to allow for easier configuration of Ignition. You can now easily add solution providers or set themes from any service provider. +- **Expanded dependency injection support for WordPress controllers**: New, streamlined, options to make controllers smaller, and more testable. + +## What's new in v8.2 + +Lumberjack v8.2 is a minor release with the following changes: + +- **Dedicated Response Emitter**: A new `ResponseEmitter` class has been introduced to safely handle responses, improving the reliability of Lumberjack. This is an internal change and should not affect your existing code. +- **Additional Report-Only Error Levels**: `E_NOTICE` and `E_WARNING` have been added to the default report-only error levels. These errors will now be logged without crashing the application. For more details on configuring error reporting, refer to the [v6.0 release notes](#whats-new-in-v60). + +## What's new in v8.1 + +Lumberjack v8.1 is a minor release that adds support for PHP 8.5 and allows configuration of the [Ignition error handler](https://github.com/spatie/ignition). + +## What's new in v8.0 + +Lumberjack v8.0 is a major release that updates many core dependencies to provide full support for PHP 8.4. + +## Major Dependency Updates + +This release updates several critical components to their latest major versions: + +- PHP-DI: 6.x → 7.x +- Monolog: 2.x → 3.x +- Illuminate Collections: 8.x/9.x → 10.x +- Laminas Diactoros: 2.x → 3.x +- PSR Container/Log: 1.x → 2.x +- Mindplay Middleman: 3.x → 4.x + +The [Upgrade Guide](./upgrade-guide.md#upgrading-from-v7-to-v8) details the required breaking changes. + +### Features + +#### New Exception Handling with Ignition + +Lumberjack has replaced the legacy Symfony Debug component with Spatie Ignition. This provides a much more robust and beautiful error reporting interface for developers. + +#### Facades moved into core + +`blast/facades` has been deprecated in favour of an internal facades implementation to provide PHP 8.4 support. + +#### Native Dcrypt Implementation + +`mmeyer2k/dcrypt` has been replaced by an internal version to provide PHP 8.4 support. + +## What's new in v7.0 + +Lumberjack v7.0 introduces support for Timber v2. It also bumps the minimum PHP requirement to 8.1 and adds official support for PHP 8.3. + +### Features + +#### Automatic Post Class Mapping + +Lumberjack will now automatically add custom post types to the `timber/post/classmap` filter. This means Timber will always return the correct class when calling methods such as `Timber::get_post()`. + +#### Simplified Querying + +Because of the new automatic Class Mapping, the as() method has been removed from the QueryBuilder. Queries will now automatically return the correct Post subclass based on the WordPress Post Type. + +```php +// Before (v6.x) +$posts = MyPost::query()->as(MyPost::class)->get(); + +// Now (v7.x) +$posts = MyPost::query()->get(); +``` + +## What's new in v6.0 + +Lumberjack v6.0 comes with PHP 8.1 support. It also replaced the (deprecated) [tightenco/collect](https://packagist.org/packages/tightenco/collect) package with [illuminate/collections](https://packagist.org/packages/illuminate/collections) package. + +### Features + +Lumberjack will no longer give a 500 error for deprecation warnings, and instead will only "report" these to your error log. + +Specifically, lumberjack will only report (and not render) the following error codes: + +- `E_DEPRECATED` - _Run-time notices. Enable this to receive warnings about code that will not work in future versions._ +- `E_USER_DEPRECATED` - _User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function trigger_error()._ +- `E_USER_NOTICE` - _User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function trigger_error()._ + +If you need to change this behaviour, you can add a new config file `config/errors.php` in your theme, like so: + +```php + [E_USER_ERROR], +]; +``` + +## What's new in v4.3 + +This release of Lumberjack is jam packed full of goodies. We have also added a whole lot more documentation, so grab a cuppa and make yourself comfy while we take you through all the changes. + +### Features + +#### Middleware Aliases on routes and controllers + +You can now create Middleware Aliases that can be used anywhere that middleware can normally be used, both in the Router and through Controllers. + +If, for example, an Alias had been registered for an `AuthMiddleware` with the key `auth` like so: + +```php +MiddlewareAliases::set('auth', function() { + return new AuthMiddleware; +}); +``` + +You can now use this in your route definition like this: + +```php +Router::get( + 'route/uri', + '\App\Http\Controllers\TestController@testMethod' +)->middleware('auth'); +``` + +[Read more about Middleware](./the-basics/middleware) + +#### `logger()` helper + +The `logger` helper can be used to write **debug** messages to your logs. + +```php +\Rareloop\Lumberjack\Helpers::logger('Product added to basket', ['id' => $product->id]); + +// Global function +logger('Product added to basket', ['id' => $product->id]); +``` + +If you need to access the logger class itself, to log different types of errors for example, you can use the `logger` function with no arguments. This will get you an instance of the PSR3 compliant logger that is bound to the container. By default Lumberjack uses `Monolog\Logger`. + +```php +\Rareloop\Lumberjack\Helpers::logger()->warning('Example warning'); + +// Global function +logger()->warning('Example warning'); +``` + +:::info +Also, the `Logger` instance is now also bound to the PSR-3 interface `Psr\Log\LoggerInterface` in the Container. +::: + +[Read more about Helpers](./the-basics/helpers) + +### Patches + +The `E_USER_NOTICE` and `E_USER_DEPRECATED` errors are now whitelisted from the Exception Handler so that they aren’t fatal. + +## What's new in v4.2 + +### Features + +#### Query Builder + +The Query Builder became macroable & also received one new useful method: `first()`. + +You can now add your own functionality to the query builder by using a macro. In this example we are adding a custom `search` method: + +```php +use Rareloop\Lumberjack\QueryBuilder; + +// Add custom function +QueryBuilder::macro('search', function ($term) { + $this->params['s'] = $term; + + return $this; +}); + +// Use the functionality +$query = new QueryBuilder(); +$query->search('Elephant'); + +$posts = $query->first(); +``` + +[Read more about Query Builder](./the-basics/query-builder) + +#### Define middleware in controllers + +You can now apply Middleware on a Controller class too, either for use with the [Router](./the-basics/routing) or as a [WordPress Controller](./the-basics/wordpress-controllers). In order to do this your Controller must extend the `App\Http\Controllers\Controller` base class. + +Middleware is added by calling the `middleware()` function in your Controller's `__constructor()`. + +```php +use App\Http\Controllers\Controller; + +class MyController extends Controller +{ + public function __construct() + { + // Add one at a time + $this->middleware(new AddHeaderMiddleware('X-Key1', 'abc')); + $this->middleware(new AuthMiddleware()); + + // Add multiple with one method call + $this->middleware([ + new AddHeaderMiddleware('X-Key1', 'abc', + new AuthMiddleware(), + ]); + } +} +``` + +[Read more about Middleware](./the-basics/middleware) + +#### Config has\(\) + +Lumberjack's configuration class now lets you check whether a config file contains a given item: + +```php +if (Config::has('app.mySetting') { + // ... +} +``` + +Note that the `has` method only checks whether the config item exists, regardless of its value. + +If you set `app.mySetting` to an empty value such as `false` or `null`, `has('app.mySetting')` will return `true`. + +[Read more about Configuration](./getting-started/configuration) + +### Documentation + +We have also added/revisited some of the documentation. We recommend checking these out: + +- [View Models](./the-basics/view-models) - New documentation +- [Middleware](./the-basics/middleware) - New documentation +- [Collections](./the-basics/collections) - New documentation + +## What's new in v4.1 + +### Features + +#### Extending Lumberjack with Macros + +You can now extend core Lumberjack classes and add your own functionality without needing to rely on inheritance. Instead, you can add macros \(custom functions\) to the core classes themselves. + +Here's an example macro, that adds a custom `acf()` method on `Rareloop\Lumberjack\Post`. + +```php +use Rareloop\Lumberjack\Post; + +// Add custom function +Post::macro('acf', function ($field) { + return get_field($field, $this->id); +}); + +// Use the functionality +$post = new Post; +$value = $post->acf('custom_field_name'); +``` + +The following classes are 'macroable': + +- `Rareloop\Lumberjack\Post` +- `Rareloop\Router\Router` +- `Rareloop\Router\RouteGroup` +- `Rareloop\Router\Route` + +## What's new in v4.0 + +### General + +#### PHP Version + +The first important thing to mention is that the minimum version of PHP has been bumped up to `7.1`. So make sure your server can handle this version. + +#### Standardising the Container + +Lumberjack uses a [dependency injection container](./container/using-the-container) under the hood, which allows you to decouple your class dependencies by having the container inject dependencies when needed. + +In v3, it wasn't clear when you were resolving a singleton or a new instance of a class from the container. It could have lead to some unusual & unexpected issues, so we decided to make things much clearer with v4 and standardise the behaviour. + +Now, when you bind a **class name** into the container like so: + +```php +$app->bind('key', MyClass::class); + +// Or bind a concrete class to an interface +$app->bind(MyInterface::class, MyClass::class); +``` + +The container will **always resolve a new instance**. What does that mean? In short, it means state is not kept between resolves, you will always get a new instance of the class. Here's a couple of examples to illustrate the point: + +```php +// Bind a class to the container +$app->bind('key', MyClass::class); + +$value1 = $app->get('key'); +$value2 = $app->get('key'); + +$value1 === $value2; // false +``` + +Here we are resolving `key` from the container twice. Each time it is resolved, the container will create a new instance of the `MyClass` class. If we were to modify `$value1` in any way, that change **would not** persist in `$value2`. For example: + +```php +// Bind a class to the container +$app->bind('key', MyClass::class); + +$value1 = $app->get('key'); + +// Modify $key1 +$value1->name = 'Adam'; + +// Get 'key' from the container again +$value2 = $app->get('key'); + +// Throws an exception as name is not defined on $value2 +$value2->name; +``` + +For the majority of the time, we feel like this is the better option. It means you are not accidentally coupling your application to the state of something in the container. + +However, sometimes you do want that behaviour. When you do, you can simply use the `singleton` method to tell the container to resolve the same instance if there is one. + +```php +$app->singleton('key', MyClass::class); + +// Or bind a concrete class to an interface +$app->singleton(MyInterface::class, MyClass::class); +``` + +Now, when the container resolves the instance it will use the one that is already bound to the container. For example: + +```php +// Bind a singleton to the container +$app->singleton('key', MyClass::class); + +$value1 = $app->get('key'); +$value2 = $app->get('key'); + +$value1 === $value2; // true +``` + +And when we modify the instance, its state will persist: + +```php +// Bind a class to the container +$app->singleton('key', MyClass::class); + +$value1 = $app->get('key'); + +// Modify $value1 +$value1->name = 'Adam'; + +// Get 'key' from the container again +$value2 = $app->get('key'); + +// 'name' is available because $value2 is the same object as $value1 +$value2->name; // 'Adam' +``` + +:::info +It is important to note that if you bind **an object instance** to the container, you will always get that instance back. For example: + +```php +$app->bind('key', new MyClass); + +$value1 = $app->get('key'); +$value1->name = 'Adam'; + +$value2 = $app->get('key'); + +// Both variables reference the same object +$value1 === $value2; // true + +$value2->name; // 'Adam' +``` + +::: + +Head over to the "Using the Container" docs to learn more: + +[Read more about Using the Container](./container/using-the-container) + +### Features + +#### New helper functions + +To make your development lives easier, there are now some additional helper functions available. These are: + +- `redirect()` - returns a `RedirectResponse` +- `back()` - returns a `RedirectResponse` which automatically redirects back to the previous URL +- `report($exception)` - tells the Exception Handler to report an exception. Useful if your theme needs to swallow an exception, but you still want to log the fact that it happened +- `request()` - returns the current `ServerRequest` object +- `session()` - can be used to interact with the session in various ways + +Check out the Helpers documentation for more details: + +[Read more about Helpers](./the-basics/helpers) + +#### Query Builder + +We've baked-in the [rareloop/lumberjack-querybuilder](https://github.com/Rareloop/lumberjack-querybuilder) package into the core. You now get an expressive, fluent and explicit way of querying data in WordPress out-of-the-box with Lumberjack. It can be used instead of [WP_Query](https://codex.wordpress.org/Class_Reference/WP_Query) to query posts \(of any type\) and means you do not have to worry about "the loop". + +[Read more about Query Builder](./the-basics/query-builder) + +#### Sessions + +This is one of the bigger features added to v4. You can now manage sessions in a concise, expressive and headache-free way. + +Let's dive straight into what sessions look like in Lumberjack. We'll be using the [global helper function](./the-basics/helpers.md#session) `session()` for these examples; [_make sure you have enabled them_](./the-basics/helpers.md#adding-global-helpers)_if you want to use it too._ + +```php +// Get a value, with a default value +$value = session('key', 'default'); + +// Get all values +$values = session()->all(); + +// Store a value +session()->put('key', 'value'); + +// Check if the session has a value +session()->has('key'); + +// Flash a value for 1 request +session()->flash('key', 'value'); + +// Remove a value +session()->forget('key'); +``` + +Be sure to read the Sessions documentation for a more in-depth look: + +[Read more about Session](./the-basics/session) + +#### Interacting with the request + +In v3, you could access the request by dependency injecting `Zend\Diactoros\ServerRequest`, like so: + +```php +use Zend\Diactoros\ServerRequest; + +class ExampleController +{ + public function handle(ServerRequest $request) + { + + } +} +``` + +Lumberjack now has its own `ServerRequest` class, making it much easier to work with the request. You can access it like so: + +```php +use Rareloop\Lumberjack\Http\ServerRequest; + +class ExampleController +{ + public function handle(ServerRequest $request) + { + + } +} +``` + +You can also use the `request()` helper to access the request from anywhere in your theme: + +```php +use Rareloop\Lumberjack\Helpers; + +$request = Helpers::request(); + +// Or if you have global helpers enabled: +$request = request(); +``` + +**Overview of some available methods** + +```php +// Get the current path +$request->path(); // e.g. /path + +// Get the current URL +$request->url(); // e.g. [http://test.com/path](http://test.com/path) + +// Get the current URL, with query parameters etc +$request->fullUrl(); // e.g. [http://test.com/path?name=adam](http://test.com/path?name=adam) + +// Get query params +$request->query(); +$name = $request->query('name', 'default'); + +// Get all input (from $_GET and $_POST) +$input = $request->input(); +$name = $request->input('name', 'default'); + +// Check the request has a specific key +$request->has('name'); +``` + +You can read the HTTP Requests documentation for more information: + +[Read more about HTTP Requests](./the-basics/http-requests) + +### Documentation + +We have also added/revisited some of the documentation. We recommend checking these out: + +- [Upgrade Guide](./upgrade-guide) - How to upgrade to v4 from v3 +- [HTTP Requests](./the-basics/http-requests) - New feature! +- [Sessions](./the-basics/session) - New feature! +- [Using the Container](./container/using-the-container) - Revisited docs after the changes to the container's behaviour +- [Helpers](./the-basics/helpers) - Added more helpers diff --git a/versioned_sidebars/version-v8.3-sidebars.json b/versioned_sidebars/version-v8.3-sidebars.json new file mode 100644 index 0000000..2782dc0 --- /dev/null +++ b/versioned_sidebars/version-v8.3-sidebars.json @@ -0,0 +1,8 @@ +{ + "sidebar": [ + { + "type": "autogenerated", + "dirName": "." + } + ] +} diff --git a/versions.json b/versions.json index 627488f..0963f6a 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,5 @@ [ + "v8.3", "v8.1", "v8", "v7",