diff --git a/.env.example b/.env.example index 6e68a83c0..ea506fca5 100644 --- a/.env.example +++ b/.env.example @@ -157,3 +157,7 @@ DISCORD_INVITE_API_URL=https://discord.com/api/v9/invites/MJyWKkCJ5k?with_counts TELESCOPE_ENABLED=false 2FA_ENABLED=true + +BROWSERSHOT_NODE_BINARY="/usr/local/bin/node" +BROWSERSHOT_NPM_BINARY="/usr/local/bin/npm" +BROWSERSHOT_TIMEOUT=60 \ No newline at end of file diff --git a/SETUP.md b/SETUP.md index 1e54f7bb3..e9d0b4e98 100644 --- a/SETUP.md +++ b/SETUP.md @@ -54,6 +54,19 @@ When you run `composer db:dev` command, you'll notice there are several users se You can always create a new admin user by running `php artisan make:admin` CLI command. +## Dynamic Meta Images + +Dashbrd utilizes [`spatie/browsershot`](https://spatie.be/docs/browsershot/v2) to generate dynamic meta images for the galleries section. For this package to function properly, Node 7.6.0 or higher, along with the Puppeteer Node library, are required. + +You need to adjust the following .env variables according to your server configuration: + +```plaintext +BROWSERSHOT_NODE_BINARY="/usr/local/bin/node" +BROWSERSHOT_NPM_BINARY="/usr/local/bin/npm" +``` + +For details on driver requirements and installation, [visit here](https://spatie.be/docs/browsershot/v2/requirements). + ## Reports When a model gets reported (Gallery, Collection, NFT), this creates an entry in the Admin panel to review. Depending on your needs, you may want to be notified as well to quickly respond to new reports. For this reason, it's possible to add a webhook to get reports pushed to Slack as well. You can adjust the `.env` as follows to achieve this: diff --git a/app/Console/Commands/PruneMetaImages.php b/app/Console/Commands/PruneMetaImages.php new file mode 100644 index 000000000..7d7c51357 --- /dev/null +++ b/app/Console/Commands/PruneMetaImages.php @@ -0,0 +1,56 @@ + $item->image_name, DB::select(get_query('gallery.get_meta_images'))); + // Convert to associative array so we can use `isset` + $validImages = array_combine($validImages, $validImages); + + $directory = storage_path(sprintf('meta/galleries/')); + + if (is_dir($directory)) { + // Open directory + if ($handle = opendir($directory)) { + // Loop through each file in the directory + while (false !== ($file = readdir($handle))) { + // Check if file is a PNG and not in validImages + if (pathinfo($file, PATHINFO_EXTENSION) === 'png' && ! isset($validImages[$file])) { + // Delete the file + unlink($directory.$file); + } + } + + // Close directory handle + closedir($handle); + } + } + + return Command::SUCCESS; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index f77aa02a3..c6046534a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -18,6 +18,7 @@ use App\Console\Commands\MarketData\FetchPriceHistory; use App\Console\Commands\MarketData\UpdateTokenDetails; use App\Console\Commands\MarketData\VerifySupportedCurrencies; +use App\Console\Commands\PruneMetaImages; use App\Console\Commands\SyncSpamContracts; use App\Console\Commands\UpdateCollectionsFiatValue; use App\Console\Commands\UpdateDiscordMembers; @@ -122,6 +123,10 @@ private function scheduleJobsForGalleries(Schedule $schedule): void ->withoutOverlapping() ->hourlyAt(2); + $schedule + ->command(PruneMetaImages::class) + ->daily(); + $schedule ->command(UpdateGalleriesValue::class) ->withoutOverlapping() diff --git a/app/Http/Controllers/GalleryController.php b/app/Http/Controllers/GalleryController.php index dca758bc1..67e5ae223 100644 --- a/app/Http/Controllers/GalleryController.php +++ b/app/Http/Controllers/GalleryController.php @@ -85,7 +85,7 @@ public function view(Request $request, Gallery $gallery): Response ])->withViewData([ 'title' => trans('metatags.galleries.view.title', ['name' => $gallery->name]), 'description' => trans('metatags.galleries.view.description', ['name' => $gallery->name]), - 'image' => trans('metatags.galleries.view.image'), + 'image' => route('galleries.meta-image', ['gallery' => $gallery->slug]), ]); } diff --git a/app/Http/Controllers/MetaImageController.php b/app/Http/Controllers/MetaImageController.php new file mode 100644 index 000000000..4d1283870 --- /dev/null +++ b/app/Http/Controllers/MetaImageController.php @@ -0,0 +1,100 @@ +getImagePath($gallery); + + $this->generateMetaImage($gallery, $imagePath); + + return response()->file($imagePath); + } + + private function generateMetaImage(Gallery $gallery, string $imagePath): void + { + Cache::lock($gallery->slug.'_meta_image', config('dashbrd.browsershot.timeout') + 15)->get(function () use ($gallery, $imagePath) { + if ($this->shouldGenerateMetaImage($imagePath)) { + $screenshotPath = $this->takeScreenshot($gallery); + + $this->storeMetaImage($imagePath, $screenshotPath); + } + }); + } + + private function shouldGenerateMetaImage(string $imagePath): bool + { + return ! file_exists($imagePath); + } + + private function getImagePath(Gallery $gallery): string + { + return storage_path(sprintf('meta/galleries/%s.png', $this->getImageName($gallery))); + } + + /** + * IMPORTANT: Ensure this method is in sync with the query in `queries/gallery.get_meta_images.sql` + */ + private function getImageName(Gallery $gallery): string + { + $parts[] = $gallery->nfts()->orderByPivot('order_index', 'asc')->limit(4)->pluck('id')->join('.'); + + $parts[] = $gallery->nfts()->count(); + + $parts[] = $gallery->name; + + return $gallery->slug.'_'.md5(implode('_', $parts)); + } + + private function takeScreenshot(Gallery $gallery): string + { + $tempPath = storage_path('tmp/'.$gallery->slug.'_screenshot.png'); + + app(Browsershot::class)->url(route('galleries.view', ['gallery' => $gallery->slug])) + ->windowSize(1480, 768) + ->timeout(config('dashbrd.browsershot.timeout')) + ->waitForFunction("document.querySelectorAll('[data-testid=GalleryNfts__nft]').length > 0 && Array.from(document.querySelectorAll('[data-testid=GalleryNfts__nft]')).slice(0, 4).every(el => ! el.querySelector('[data-testid=Skeleton]'))") + ->setNodeBinary(config('dashbrd.browsershot.node_binary')) + ->setNpmBinary(config('dashbrd.browsershot.npm_binary')) + ->save($tempPath); + + $this->resizeScreenshot($tempPath); + + return $tempPath; + } + + private function resizeScreenshot(string $screenshotPath): void + { + $image = Image::load($screenshotPath); + + $image->width(1006)->crop(Manipulations::CROP_TOP, 1006, 373); + + $image->save($screenshotPath); + } + + private function storeMetaImage(string $imagePath, string $screenshotPath): string + { + $template = Image::load(resource_path('images/gallery/gallery_template.png')); + + $template + ->watermark($screenshotPath) + ->watermarkPosition(Manipulations::POSITION_BOTTOM); + + $template->save($imagePath); + + unlink($screenshotPath); + + return $imagePath; + } +} diff --git a/composer.json b/composer.json index 3dea0d631..7d99dce78 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "monolog/monolog": "^3.4", "sentry/sentry-laravel": "^3.8", "simplito/elliptic-php": "^1.0", + "spatie/browsershot": "^3.59", "spatie/laravel-data": "^3.9", "spatie/laravel-medialibrary": "^10.13", "spatie/laravel-permission": "^5.11", diff --git a/composer.lock b/composer.lock index 9ba55cf28..459d1dede 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "60193dbd3ece7115df8bb23f4da6f5a4", + "content-hash": "7967c65a2b6a5fde6e6e515350db4f7f", "packages": [ { "name": "atymic/twitter", @@ -8103,6 +8103,72 @@ }, "time": "2023-08-28T15:27:19+00:00" }, + { + "name": "spatie/browsershot", + "version": "3.59.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/browsershot.git", + "reference": "1b74e71fdd1c30fa1de45465bacc1cf5dc852881" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/browsershot/zipball/1b74e71fdd1c30fa1de45465bacc1cf5dc852881", + "reference": "1b74e71fdd1c30fa1de45465bacc1cf5dc852881", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0", + "spatie/image": "^1.5.3|^2.0", + "spatie/temporary-directory": "^1.1|^2.0", + "symfony/process": "^4.2|^5.0|^6.0" + }, + "require-dev": { + "pestphp/pest": "^1.20", + "spatie/phpunit-snapshot-assertions": "^4.2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Browsershot\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://github.com/freekmurze", + "role": "Developer" + } + ], + "description": "Convert a webpage to an image or pdf using headless Chrome", + "homepage": "https://github.com/spatie/browsershot", + "keywords": [ + "chrome", + "convert", + "headless", + "image", + "pdf", + "puppeteer", + "screenshot", + "webpage" + ], + "support": { + "source": "https://github.com/spatie/browsershot/tree/3.59.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2023-10-09T12:59:37+00:00" + }, { "name": "spatie/color", "version": "1.5.3", @@ -15675,5 +15741,5 @@ "php": "^8.2" }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/config/dashbrd.php b/config/dashbrd.php index 0bfd2e587..2f50d0dd7 100644 --- a/config/dashbrd.php +++ b/config/dashbrd.php @@ -5,6 +5,11 @@ use App\Enums\Period; return [ + 'browsershot' => [ + 'timeout' => (int) env('BROWSERSHOT_TIMEOUT', 60), + 'node_binary' => env('BROWSERSHOT_NODE_BINARY', '/usr/local/bin/node'), + 'npm_binary' => env('BROWSERSHOT_NPM_BINARY', '/usr/local/bin/npm'), + ], 'contact_email' => env('CONTACT_EMAIL', 'support@ardenthq.com'), 'features' => [ diff --git a/package.json b/package.json index 0439d3a4e..b61f75e72 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,7 @@ "file-saver": "^2.0.5", "i18next": "^22.5.1", "lru-cache": "^10.0.1", + "puppeteer": "^21.4.0", "react-chartjs-2": "^5.2.0", "react-i18next": "^12.3.1", "react-in-viewport": "1.0.0-alpha.30", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3010b5cd4..bed7746bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ dependencies: lru-cache: specifier: ^10.0.1 version: 10.0.1 + puppeteer: + specifier: ^21.4.0 + version: 21.4.0(typescript@5.2.2) react-chartjs-2: specifier: ^5.2.0 version: 5.2.0(chart.js@4.4.0)(react@18.2.0) @@ -333,10 +336,10 @@ devDependencies: version: 9.0.2(react@18.2.0) storybook: specifier: next - version: 7.5.0-alpha.4 + version: 7.6.0-alpha.2 storybook-react-i18next: specifier: ^2.0.9 - version: 2.0.9(@storybook/components@7.4.6)(@storybook/manager-api@7.4.6)(@storybook/preview-api@7.4.6)(@storybook/types@7.5.1)(i18next-browser-languagedetector@7.1.0)(i18next-http-backend@2.2.2)(i18next@22.5.1)(react-dom@18.2.0)(react-i18next@12.3.1)(react@18.2.0) + version: 2.0.9(@storybook/components@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/types@7.5.1)(i18next-browser-languagedetector@7.1.0)(i18next-http-backend@2.2.2)(i18next@22.5.1)(react-dom@18.2.0)(react-i18next@12.3.1)(react@18.2.0) swiper: specifier: ^9.4.1 version: 9.4.1 @@ -2605,6 +2608,22 @@ packages: /@popperjs/core@2.11.8: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + /@puppeteer/browsers@1.8.0: + resolution: {integrity: sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==} + engines: {node: '>=16.3.0'} + hasBin: true + dependencies: + debug: 4.3.4 + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.3.1 + tar-fs: 3.0.4 + unbzip2-stream: 1.4.3 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + dev: false + /@radix-ui/number@1.0.1: resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} dependencies: @@ -3606,13 +3625,13 @@ packages: - encoding - supports-color - /@storybook/builder-manager@7.5.0-alpha.4: - resolution: {integrity: sha512-Gh2s42BvgF5/rng2rizGKQ51PB68oXY+VEZfhsZRf+Sh3o6bm4zo9lec2p4mpfEmnfPrKRl40IhibgW2EIoXJA==} + /@storybook/builder-manager@7.6.0-alpha.2: + resolution: {integrity: sha512-4JO8n35jg0v4Dg2X4hmDjVTRxhcokAqi7BCWdRqf05GZZjdTRCK698Su+SMz4gGSxt88QihZ+D0HgvXkb0yEvQ==} dependencies: '@fal-works/esbuild-plugin-global-externals': 2.1.2 - '@storybook/core-common': 7.5.0-alpha.4 - '@storybook/manager': 7.5.0-alpha.4 - '@storybook/node-logger': 7.5.0-alpha.4 + '@storybook/core-common': 7.6.0-alpha.2 + '@storybook/manager': 7.6.0-alpha.2 + '@storybook/node-logger': 7.6.0-alpha.2 '@types/ejs': 3.1.3 '@types/find-cache-dir': 3.2.1 '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.18.20) @@ -3668,54 +3687,43 @@ packages: - supports-color dev: true - /@storybook/channels@7.4.6: - resolution: {integrity: sha512-yPv/sfo2c18fM3fvG0i1xse63vG8l33Al/OU0k/dtovltPu001/HVa1QgBgsb/QrEfZtvGjGhmtdVeYb39fv3A==} + /@storybook/channels@7.5.1: + resolution: {integrity: sha512-7hTGHqvtdFTqRx8LuCznOpqPBYfUeMUt/0IIp7SFuZT585yMPxrYoaK//QmLEWnPb80B8HVTSQi7caUkJb32LA==} dependencies: - '@storybook/client-logger': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/client-logger': 7.5.1 + '@storybook/core-events': 7.5.1 '@storybook/global': 5.0.0 qs: 6.11.2 telejson: 7.2.0 tiny-invariant: 1.3.1 - dev: true - /@storybook/channels@7.5.0-alpha.4: - resolution: {integrity: sha512-Cf26J9l7vnCMnzWcCZyRuGkpokp/L1tuceHWR/Ku2P11PgX/mM6pqmbKUaKEnfMY1RM7KaOYP4pL/p9UzjXq5g==} + /@storybook/channels@7.6.0-alpha.2: + resolution: {integrity: sha512-/RifysrrWYlYMpgYmkfZfTmFSeZQ4vdc0FaV3UupILJcSOz13rY+CvHjJzLGd53NPyG4B0YsFBnzqTUsQ1hPWA==} dependencies: - '@storybook/client-logger': 7.5.0-alpha.4 - '@storybook/core-events': 7.5.0-alpha.4 + '@storybook/client-logger': 7.6.0-alpha.2 + '@storybook/core-events': 7.6.0-alpha.2 '@storybook/global': 5.0.0 qs: 6.11.2 telejson: 7.2.0 tiny-invariant: 1.3.1 dev: true - /@storybook/channels@7.5.1: - resolution: {integrity: sha512-7hTGHqvtdFTqRx8LuCznOpqPBYfUeMUt/0IIp7SFuZT585yMPxrYoaK//QmLEWnPb80B8HVTSQi7caUkJb32LA==} - dependencies: - '@storybook/client-logger': 7.5.1 - '@storybook/core-events': 7.5.1 - '@storybook/global': 5.0.0 - qs: 6.11.2 - telejson: 7.2.0 - tiny-invariant: 1.3.1 - - /@storybook/cli@7.5.0-alpha.4: - resolution: {integrity: sha512-8wlZknJb7JOA4DdGPOyy8j8XHv8OSQSfovCPk3et0MOooUFb1SgZLAiSQui19KpKN7yepcVg3JT/VwKqqIOrZg==} + /@storybook/cli@7.6.0-alpha.2: + resolution: {integrity: sha512-k5ME2iu51GY1w/jSUKKM2XpfVeRmyrN97VJLlEHokrYAh71nS3qbxEO3fmzeq4RFJytlbcZYmnzMnWU9H9si/w==} hasBin: true dependencies: '@babel/core': 7.23.2 '@babel/preset-env': 7.22.20(@babel/core@7.23.2) '@babel/types': 7.23.0 '@ndelangen/get-tarball': 3.0.9 - '@storybook/codemod': 7.5.0-alpha.4 - '@storybook/core-common': 7.5.0-alpha.4 - '@storybook/core-events': 7.5.0-alpha.4 - '@storybook/core-server': 7.5.0-alpha.4 - '@storybook/csf-tools': 7.5.0-alpha.4 - '@storybook/node-logger': 7.5.0-alpha.4 - '@storybook/telemetry': 7.5.0-alpha.4 - '@storybook/types': 7.5.0-alpha.4 + '@storybook/codemod': 7.6.0-alpha.2 + '@storybook/core-common': 7.6.0-alpha.2 + '@storybook/core-events': 7.6.0-alpha.2 + '@storybook/core-server': 7.6.0-alpha.2 + '@storybook/csf-tools': 7.6.0-alpha.2 + '@storybook/node-logger': 7.6.0-alpha.2 + '@storybook/telemetry': 7.6.0-alpha.2 + '@storybook/types': 7.6.0-alpha.2 '@types/semver': 7.5.3 '@yarnpkg/fslib': 2.10.3 '@yarnpkg/libzip': 2.3.0 @@ -3752,33 +3760,27 @@ packages: - utf-8-validate dev: true - /@storybook/client-logger@7.4.6: - resolution: {integrity: sha512-XDw31ZziU//86PKuMRnmc+L/G0VopaGKENQOGEpvAXCU9IZASwGKlKAtcyosjrpi+ZiUXlMgUXCpXM7x3b1Ehw==} + /@storybook/client-logger@7.5.1: + resolution: {integrity: sha512-XxbLvg0aQRoBrzxYLcVYCbjDkGbkU8Rfb74XbV2CLiO2bIbFPmA1l1Nwbp+wkCGA+O6Z1zwzSl6wcKKqZ6XZCg==} dependencies: '@storybook/global': 5.0.0 - dev: true - /@storybook/client-logger@7.5.0-alpha.4: - resolution: {integrity: sha512-YoVz2uU5u3OJWWnNNpy1jakwWluxkOZQg+aw7c7Av5jLwoKO0ZDwGQoaQcaXnpBCb9KWAV9o8SZgFn9Qn0bk8A==} + /@storybook/client-logger@7.6.0-alpha.2: + resolution: {integrity: sha512-HhoeGMc1SYLwR/bGoMjhUUAqxqTw3C9Z8G3+FiNI6J2Ape0AGKdSFhJ5sRx4j1K9iVaBFqsFh70Ba01JezGSIQ==} dependencies: '@storybook/global': 5.0.0 dev: true - /@storybook/client-logger@7.5.1: - resolution: {integrity: sha512-XxbLvg0aQRoBrzxYLcVYCbjDkGbkU8Rfb74XbV2CLiO2bIbFPmA1l1Nwbp+wkCGA+O6Z1zwzSl6wcKKqZ6XZCg==} - dependencies: - '@storybook/global': 5.0.0 - - /@storybook/codemod@7.5.0-alpha.4: - resolution: {integrity: sha512-PHXbeLo5c8aFSb1M5DFLGaNcp/wQrgPut/SjhWnIthmdjeroJbNNVi86SZ2ZLSj1kQIcuU6zlbxPnxEk58uTjA==} + /@storybook/codemod@7.6.0-alpha.2: + resolution: {integrity: sha512-ARke7fU5TQ8uzgbeJx8NawYvdDCVQYWKUyrLUgzqIWU/J/oqcMp62ygpCeRW3BdfjmhN8+PmiSUUJu7yOku1mg==} dependencies: '@babel/core': 7.23.2 '@babel/preset-env': 7.22.20(@babel/core@7.23.2) '@babel/types': 7.23.0 '@storybook/csf': 0.1.1 - '@storybook/csf-tools': 7.5.0-alpha.4 - '@storybook/node-logger': 7.5.0-alpha.4 - '@storybook/types': 7.5.0-alpha.4 + '@storybook/csf-tools': 7.6.0-alpha.2 + '@storybook/node-logger': 7.6.0-alpha.2 + '@storybook/types': 7.6.0-alpha.2 '@types/cross-spawn': 6.0.3 cross-spawn: 7.0.3 globby: 11.1.0 @@ -3790,29 +3792,6 @@ packages: - supports-color dev: true - /@storybook/components@7.4.6(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-nIRBhewAgrJJVafyCzuaLx1l+YOfvvD5dOZ0JxZsxJsefOdw1jFpUqUZ5fIpQ2moyvrR0mAUFw378rBfMdHz5Q==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@radix-ui/react-select': 1.2.2(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-toolbar': 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) - '@storybook/client-logger': 7.4.6 - '@storybook/csf': 0.1.1 - '@storybook/global': 5.0.0 - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 - memoizerific: 1.11.3 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0) - util-deprecate: 1.0.2 - transitivePeerDependencies: - - '@types/react' - - '@types/react-dom' - dev: true - /@storybook/components@7.5.1(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-fdzzxGBV/Fj9pYwfYL3RZsVUHeBqlfLMBP/L6mPmjaZSwHFqkaRZZUajZc57lCtI+TOy2gY6WH3cPavEtqtgLw==} peerDependencies: @@ -3842,20 +3821,20 @@ packages: '@storybook/preview-api': 7.5.1 dev: true - /@storybook/core-common@7.5.0-alpha.4: - resolution: {integrity: sha512-ReKIXa1jz1hRj6gcEjrvykn9qsxjmsxTHn3d1AbM4gnsJZQMYKkl0fUWLqJAo5XWW9Q3K7ksvemGtTOU5eHeAg==} + /@storybook/core-common@7.5.1: + resolution: {integrity: sha512-/rQ0/xvxFHSGCgIkK74HrgDMnzfYtDYTCoSod/qCTojfs9aciX+JYgvo5ChPnI/LEKWwxRTkrE7pl2u5+C4XGA==} dependencies: - '@storybook/core-events': 7.5.0-alpha.4 - '@storybook/node-logger': 7.5.0-alpha.4 - '@storybook/types': 7.5.0-alpha.4 + '@storybook/core-events': 7.5.1 + '@storybook/node-logger': 7.5.1 + '@storybook/types': 7.5.1 '@types/find-cache-dir': 3.2.1 - '@types/node': 16.18.57 + '@types/node': 18.18.6 '@types/node-fetch': 2.6.6 '@types/pretty-hrtime': 1.0.1 chalk: 4.1.2 esbuild: 0.18.20 esbuild-register: 3.5.0(esbuild@0.18.20) - file-system-cache: 2.4.4 + file-system-cache: 2.3.0 find-cache-dir: 3.3.2 find-up: 5.0.0 fs-extra: 11.1.1 @@ -3871,14 +3850,13 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: true - /@storybook/core-common@7.5.1: - resolution: {integrity: sha512-/rQ0/xvxFHSGCgIkK74HrgDMnzfYtDYTCoSod/qCTojfs9aciX+JYgvo5ChPnI/LEKWwxRTkrE7pl2u5+C4XGA==} + /@storybook/core-common@7.6.0-alpha.2: + resolution: {integrity: sha512-l3QOACXOeQmLGSxXGxChPTCLC+1E2vKxYPXpgv5T9CEEVDtipMO3+YLvj6FhOhKisrDQwWyr5V+epVpy+fNP6w==} dependencies: - '@storybook/core-events': 7.5.1 - '@storybook/node-logger': 7.5.1 - '@storybook/types': 7.5.1 + '@storybook/core-events': 7.6.0-alpha.2 + '@storybook/node-logger': 7.6.0-alpha.2 + '@storybook/types': 7.6.0-alpha.2 '@types/find-cache-dir': 3.2.1 '@types/node': 18.18.6 '@types/node-fetch': 2.6.6 @@ -3902,44 +3880,39 @@ packages: transitivePeerDependencies: - encoding - supports-color - - /@storybook/core-events@7.4.6: - resolution: {integrity: sha512-r5vrE+32lwrJh1NGFr1a0mWjvxo7q8FXYShylcwRWpacmL5NTtLkrXOoJSeGvJ4yKNYkvxQFtOPId4lzDxa32w==} - dependencies: - ts-dedent: 2.2.0 dev: true - /@storybook/core-events@7.5.0-alpha.4: - resolution: {integrity: sha512-7oaGGBEKYI0eKS1vA7GskbBQkPqJzmhP1uIzLM8MgiZXUuwU9/7bxTAQCa1mlHXwpwn3wIaZ53NbDBweilSHXw==} + /@storybook/core-events@7.5.1: + resolution: {integrity: sha512-2eyaUhTfmEEqOEZVoCXVITCBn6N7QuZCG2UNxv0l//ED+7MuMiFhVw7kS7H3WOVk65R7gb8qbKFTNX8HFTgBHg==} dependencies: ts-dedent: 2.2.0 - dev: true - /@storybook/core-events@7.5.1: - resolution: {integrity: sha512-2eyaUhTfmEEqOEZVoCXVITCBn6N7QuZCG2UNxv0l//ED+7MuMiFhVw7kS7H3WOVk65R7gb8qbKFTNX8HFTgBHg==} + /@storybook/core-events@7.6.0-alpha.2: + resolution: {integrity: sha512-2bRYqGQ64JD9mFAtRfT1a+DdM4OX/bKBnvfRj0KGnJQCNI4+CTCPKhtVfX59PmJd5coGdqMFmU9S75H5cMnthA==} dependencies: ts-dedent: 2.2.0 + dev: true - /@storybook/core-server@7.5.0-alpha.4: - resolution: {integrity: sha512-M7dNjptFHSG8IYdWnRmjTBJ1+lfxc4ElcJIYc6pQm2zBteuNYmcOmPTpBOXXnpayAN566H99ARQ+Sk8TV/+vFw==} + /@storybook/core-server@7.6.0-alpha.2: + resolution: {integrity: sha512-W0RnbQ9A7A7RBSHscGf4k2xnxS8kpH1PG1phM/NlRi8EhkqzDb2eCTk4A7OX2+xlI1yhuCucaS4cKtJLtFHrKw==} dependencies: '@aw-web-design/x-default-browser': 1.4.126 '@discoveryjs/json-ext': 0.5.7 - '@storybook/builder-manager': 7.5.0-alpha.4 - '@storybook/channels': 7.5.0-alpha.4 - '@storybook/core-common': 7.5.0-alpha.4 - '@storybook/core-events': 7.5.0-alpha.4 + '@storybook/builder-manager': 7.6.0-alpha.2 + '@storybook/channels': 7.6.0-alpha.2 + '@storybook/core-common': 7.6.0-alpha.2 + '@storybook/core-events': 7.6.0-alpha.2 '@storybook/csf': 0.1.1 - '@storybook/csf-tools': 7.5.0-alpha.4 + '@storybook/csf-tools': 7.6.0-alpha.2 '@storybook/docs-mdx': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/manager': 7.5.0-alpha.4 - '@storybook/node-logger': 7.5.0-alpha.4 - '@storybook/preview-api': 7.5.0-alpha.4 - '@storybook/telemetry': 7.5.0-alpha.4 - '@storybook/types': 7.5.0-alpha.4 + '@storybook/manager': 7.6.0-alpha.2 + '@storybook/node-logger': 7.6.0-alpha.2 + '@storybook/preview-api': 7.6.0-alpha.2 + '@storybook/telemetry': 7.6.0-alpha.2 + '@storybook/types': 7.6.0-alpha.2 '@types/detect-port': 1.3.3 - '@types/node': 16.18.57 + '@types/node': 18.18.6 '@types/pretty-hrtime': 1.0.1 '@types/semver': 7.5.3 better-opn: 3.0.2 @@ -3979,36 +3952,36 @@ packages: transitivePeerDependencies: - supports-color - /@storybook/csf-tools@7.5.0-alpha.4: - resolution: {integrity: sha512-e6ZidOGRTH4UVEIJGmjOFp3MEeTJPyWnkZ3vGsfJNEQ7JLx70MsLZGU3d5yxSP5FLywlGnAXTdXZ7wG4wfeUYA==} + /@storybook/csf-tools@7.5.1: + resolution: {integrity: sha512-YChGbT1/odLS4RLb2HtK7ixM7mH5s7G5nOsWGKXalbza4SFKZIU2UzllEUsA+X8YfxMHnCD5TC3xLfK0ByxmzQ==} dependencies: '@babel/generator': 7.23.0 '@babel/parser': 7.23.0 '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 '@storybook/csf': 0.1.1 - '@storybook/types': 7.5.0-alpha.4 + '@storybook/types': 7.5.1 fs-extra: 11.1.1 recast: 0.23.4 ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color - dev: true - /@storybook/csf-tools@7.5.1: - resolution: {integrity: sha512-YChGbT1/odLS4RLb2HtK7ixM7mH5s7G5nOsWGKXalbza4SFKZIU2UzllEUsA+X8YfxMHnCD5TC3xLfK0ByxmzQ==} + /@storybook/csf-tools@7.6.0-alpha.2: + resolution: {integrity: sha512-VLWqqqoWRLGfnbYpQakx1cyJSCKdH4jiFQWKP7ytZjKw6q9OSTtWTmZw6ogf0y0aOZHjtWy4WDKCVGlfHea6pA==} dependencies: '@babel/generator': 7.23.0 '@babel/parser': 7.23.0 '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 '@storybook/csf': 0.1.1 - '@storybook/types': 7.5.1 + '@storybook/types': 7.6.0-alpha.2 fs-extra: 11.1.1 recast: 0.23.4 ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color + dev: true /@storybook/csf@0.0.1: resolution: {integrity: sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==} @@ -4051,31 +4024,6 @@ packages: '@storybook/preview-api': 7.5.1 dev: true - /@storybook/manager-api@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-inrm3DIbCp8wjXSN/wK6e6i2ysQ/IEmtC7IN0OJ7vdrp+USCooPT448SQTUmVctUGCFmOU3fxXByq8g77oIi7w==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@storybook/channels': 7.4.6 - '@storybook/client-logger': 7.4.6 - '@storybook/core-events': 7.4.6 - '@storybook/csf': 0.1.1 - '@storybook/global': 5.0.0 - '@storybook/router': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.4.6 - dequal: 2.0.3 - lodash: 4.17.21 - memoizerific: 1.11.3 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - semver: 7.5.4 - store2: 2.14.2 - telejson: 7.2.0 - ts-dedent: 2.2.0 - dev: true - /@storybook/manager-api@7.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ygwJywluhhE1dpA0jC2D/3NFhMXzFCt+iW4m3cOwexYTuiDWF66AbGOFBx9peE7Wk/Z9doKkf9E3v11enwaidA==} peerDependencies: @@ -4100,32 +4048,32 @@ packages: telejson: 7.2.0 ts-dedent: 2.2.0 - /@storybook/manager@7.5.0-alpha.4: - resolution: {integrity: sha512-A0Ol7qCvjTgdWl+uxCr7c3mtQ+DlUJodV+RtavkALLwPiG0yav9WAd1uuCoIh7RlrlU7ahc6vbzARnO/Yk14ZA==} + /@storybook/manager@7.6.0-alpha.2: + resolution: {integrity: sha512-4DPFnJCMz14XkZyPS+YoIml1lCuSW2jfsUhl5SHS478VIDvNR4tCnPCKKXXfeTV77XAH8ZrUn+8bAzhNpNV3Gg==} dev: true /@storybook/mdx2-csf@1.1.0: resolution: {integrity: sha512-TXJJd5RAKakWx4BtpwvSNdgTDkKM6RkXU8GK34S/LhidQ5Pjz3wcnqb0TxEkfhK/ztbP8nKHqXFwLfa2CYkvQw==} - /@storybook/node-logger@7.5.0-alpha.4: - resolution: {integrity: sha512-nCwaq99u5EvtzGg4AdsSsZtg8bkUA+Rv1n5ALXbm7nOzydpW/LbqYAwGxmxORwnoS1TGkd8q7tAk6DKRCUcDow==} - dev: true - /@storybook/node-logger@7.5.1: resolution: {integrity: sha512-xRMdL5YPe8C9sgJ1R0QD3YbiLjDGrfQk91+GplRD8N9FVCT5dki55Bv5Kp0FpemLYYg6uxAZL5nHmsZHKDKQoA==} + /@storybook/node-logger@7.6.0-alpha.2: + resolution: {integrity: sha512-ERFaYl47zXNnre/V4jVSdB4EIy2S3x2+O4ryFGIYM+1DpxbwRHUA4M+JKaDQ4EXUB+s/LItPKPpEYGr/y/TqWA==} + dev: true + /@storybook/postinstall@7.5.1: resolution: {integrity: sha512-+LFUe2nNbmmLPKNt34RXSSC1r40yGGOoP/qlaPFwNOgQN2AZUrfqk6ZYnw6LjmcuHpQInZ4y4WDgbzg6QQL3+w==} - /@storybook/preview-api@7.4.6: - resolution: {integrity: sha512-byUS/Opt3ytWD4cWz3sNEKw5Yks8MkQgRN+GDSyIomaEAQkLAM0rchPC0MYjwCeUSecV7IIQweNX5RbV4a34BA==} + /@storybook/preview-api@7.5.1: + resolution: {integrity: sha512-8xjUbuGmHLmw8tfTUCjXSvMM9r96JaexPFmHdwW6XLe71KKdWp8u96vRDRE5648cd+/of15OjaRtakRKqluA/A==} dependencies: - '@storybook/channels': 7.4.6 - '@storybook/client-logger': 7.4.6 - '@storybook/core-events': 7.4.6 + '@storybook/channels': 7.5.1 + '@storybook/client-logger': 7.5.1 + '@storybook/core-events': 7.5.1 '@storybook/csf': 0.1.1 '@storybook/global': 5.0.0 - '@storybook/types': 7.4.6 + '@storybook/types': 7.5.1 '@types/qs': 6.9.8 dequal: 2.0.3 lodash: 4.17.21 @@ -4134,17 +4082,16 @@ packages: synchronous-promise: 2.0.17 ts-dedent: 2.2.0 util-deprecate: 1.0.2 - dev: true - /@storybook/preview-api@7.5.0-alpha.4: - resolution: {integrity: sha512-uYWCNvV81n0DRw37G6BTX4B7St4Sq1lnKHDnz+QbbomU4E+gebjOfhw3PghD/ZFvv46rKqyOWhweLdXGhy5rqg==} + /@storybook/preview-api@7.6.0-alpha.2: + resolution: {integrity: sha512-puoNcVVTbGHFhMw1u2HgzEdN9L9vJInejdNBpRS1YIc0+rHRyBbDNtm/bnve92p1eE/JY6KuAtFF1b8NMehgMg==} dependencies: - '@storybook/channels': 7.5.0-alpha.4 - '@storybook/client-logger': 7.5.0-alpha.4 - '@storybook/core-events': 7.5.0-alpha.4 + '@storybook/channels': 7.6.0-alpha.2 + '@storybook/client-logger': 7.6.0-alpha.2 + '@storybook/core-events': 7.6.0-alpha.2 '@storybook/csf': 0.1.1 '@storybook/global': 5.0.0 - '@storybook/types': 7.5.0-alpha.4 + '@storybook/types': 7.6.0-alpha.2 '@types/qs': 6.9.8 dequal: 2.0.3 lodash: 4.17.21 @@ -4155,24 +4102,6 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/preview-api@7.5.1: - resolution: {integrity: sha512-8xjUbuGmHLmw8tfTUCjXSvMM9r96JaexPFmHdwW6XLe71KKdWp8u96vRDRE5648cd+/of15OjaRtakRKqluA/A==} - dependencies: - '@storybook/channels': 7.5.1 - '@storybook/client-logger': 7.5.1 - '@storybook/core-events': 7.5.1 - '@storybook/csf': 0.1.1 - '@storybook/global': 5.0.0 - '@storybook/types': 7.5.1 - '@types/qs': 6.9.8 - dequal: 2.0.3 - lodash: 4.17.21 - memoizerific: 1.11.3 - qs: 6.11.2 - synchronous-promise: 2.0.17 - ts-dedent: 2.2.0 - util-deprecate: 1.0.2 - /@storybook/preview@7.5.1: resolution: {integrity: sha512-nfZC103z9Cy27FrJKUr2IjDuVt8Mvn1Z5gZ0TtJihoK7sfLTv29nd/XU9zzrb/epM3o8UEzc63xZZsMaToDbAw==} dev: true @@ -4253,19 +4182,6 @@ packages: - supports-color dev: true - /@storybook/router@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Vl1esrHkcHxDKqc+HY7+6JQpBPW3zYvGk0cQ2rxVMhWdLZTAz1hss9DqzN9tFnPyfn0a1Q77EpMySkUrvWKKNQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@storybook/client-logger': 7.4.6 - memoizerific: 1.11.3 - qs: 6.11.2 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - dev: true - /@storybook/router@7.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-BvKo+IxWwo3dfIG1+vLtZLT4qqkNHL5GTIozTyX04uqt9ByYZL6SJEzxEa1Xn6Qq/fbdQwzCanNHbTlwiTMf7Q==} peerDependencies: @@ -4278,12 +4194,12 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /@storybook/telemetry@7.5.0-alpha.4: - resolution: {integrity: sha512-LDWzVNCBuOOilGet/+xZTMFEHklYBjfl2/UT1JyPvHDao0F0xRw/ZrfUBL16FHTmD4d/rvtAKvDIAqdQuG45CQ==} + /@storybook/telemetry@7.6.0-alpha.2: + resolution: {integrity: sha512-oANJyVbLqlh89vVhZcu1ObDzSDzbAFBDnabGsiYYL8c76vnxmwrf3lUHpwZtcIsQVU8fRFXz/EJhw70K2Yf4IQ==} dependencies: - '@storybook/client-logger': 7.5.0-alpha.4 - '@storybook/core-common': 7.5.0-alpha.4 - '@storybook/csf-tools': 7.5.0-alpha.4 + '@storybook/client-logger': 7.6.0-alpha.2 + '@storybook/core-common': 7.6.0-alpha.2 + '@storybook/csf-tools': 7.6.0-alpha.2 chalk: 4.1.2 detect-package-manager: 2.0.1 fetch-retry: 5.0.6 @@ -4302,20 +4218,6 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/theming@7.4.6(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-HW77iJ9ptCMqhoBOYFjRQw7VBap+38fkJGHP5KylEJCyYCgIAm2dEcQmtWpMVYFssSGcb6djfbtAMhYU4TL4Iw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) - '@storybook/client-logger': 7.4.6 - '@storybook/global': 5.0.0 - memoizerific: 1.11.3 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - dev: true - /@storybook/theming@7.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ETLAOn10hI4Mkmjsr0HGcM6HbzaURrrPBYmfXOrdbrzEVN+AHW4FlvP9d8fYyP1gdjPE1F39XvF0jYgt1zXiHQ==} peerDependencies: @@ -4329,31 +4231,22 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - /@storybook/types@7.4.6: - resolution: {integrity: sha512-6QLXtMVsFZFpzPkdGWsu/iuc8na9dnS67AMOBKm5qCLPwtUJOYkwhMdFRSSeJthLRpzV7JLAL8Kwvl7MFP3QSw==} + /@storybook/types@7.5.1: + resolution: {integrity: sha512-ZcMSaqFNx1E+G00nRDUi8kKL7gxJVlnCvbKLNj3V85guy4DkIYAZr31yDqze07gDWbjvKoHIp3tKpgE+2i8upQ==} dependencies: - '@storybook/channels': 7.4.6 + '@storybook/channels': 7.5.1 '@types/babel__core': 7.20.2 '@types/express': 4.17.18 file-system-cache: 2.3.0 - dev: true - /@storybook/types@7.5.0-alpha.4: - resolution: {integrity: sha512-IhSX09nvWkv4qz4oiys0v7eGI9gIWLN94iUw4y+StxjVMnaUSM4KyMYR/2kYxX024cvyHUDLhmGAKRWr1E7wgA==} + /@storybook/types@7.6.0-alpha.2: + resolution: {integrity: sha512-nyiktBBZrjBoJyYIiK0lWcqmyrlqD0Hy/EL4rA739yCwiIgN8KJTPhqPElydYQhN6DOT6qQe7cCGotHioGneIg==} dependencies: - '@storybook/channels': 7.5.0-alpha.4 - '@types/babel__core': 7.20.2 - '@types/express': 4.17.18 - file-system-cache: 2.4.4 - dev: true - - /@storybook/types@7.5.1: - resolution: {integrity: sha512-ZcMSaqFNx1E+G00nRDUi8kKL7gxJVlnCvbKLNj3V85guy4DkIYAZr31yDqze07gDWbjvKoHIp3tKpgE+2i8upQ==} - dependencies: - '@storybook/channels': 7.5.1 + '@storybook/channels': 7.6.0-alpha.2 '@types/babel__core': 7.20.2 '@types/express': 4.17.18 file-system-cache: 2.3.0 + dev: true /@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.23.2): resolution: {integrity: sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==} @@ -4614,6 +4507,10 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} + /@tootallnate/quickjs-emscripten@0.23.0: + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + dev: false + /@types/aria-query@5.0.1: resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} dev: true @@ -4771,13 +4668,6 @@ packages: /@types/find-cache-dir@3.2.1: resolution: {integrity: sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==} - /@types/fs-extra@11.0.1: - resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} - dependencies: - '@types/jsonfile': 6.1.2 - '@types/node': 18.18.6 - dev: true - /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: @@ -4826,12 +4716,6 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/jsonfile@6.1.2: - resolution: {integrity: sha512-8t92P+oeW4d/CRQfJaSqEwXujrhH4OEeHRjGU3v1Q8mUS8GPF3yiX26sw4svv6faL2HfBtGTe2xWIoVgN3dy9w==} - dependencies: - '@types/node': 18.18.6 - dev: true - /@types/lodash@4.14.200: resolution: {integrity: sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==} @@ -4869,10 +4753,6 @@ packages: '@types/node': 18.18.6 form-data: 4.0.0 - /@types/node@16.18.57: - resolution: {integrity: sha512-piPoDozdPaX1hNWFJQzzgWqE40gh986VvVx/QO9RU4qYRE55ld7iepDVgZ3ccGUw0R4wge0Oy1dd+3xOQNkkUQ==} - dev: true - /@types/node@18.18.6: resolution: {integrity: sha512-wf3Vz+jCmOQ2HV1YUJuCWdL64adYxumkrxtc+H1VUQlnQI04+5HtH+qZCOE21lBE7gIrt+CwX2Wv8Acrw5Ak6w==} @@ -4893,12 +4773,6 @@ packages: /@types/qs@6.9.8: resolution: {integrity: sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==} - /@types/ramda@0.29.3: - resolution: {integrity: sha512-Yh/RHkjN0ru6LVhSQtTkCRo6HXkfL9trot/2elzM/yXLJmbLm2v6kJc8yftTnwv1zvUob6TEtqI2cYjdqG3U0Q==} - dependencies: - types-ramda: 0.29.5 - dev: true - /@types/range-parser@1.2.5: resolution: {integrity: sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==} @@ -4986,6 +4860,14 @@ packages: dependencies: '@types/yargs-parser': 21.0.0 + /@types/yauzl@2.10.2: + resolution: {integrity: sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==} + requiresBuild: true + dependencies: + '@types/node': 18.18.6 + dev: false + optional: true + /@types/ziggy-js@1.3.3: resolution: {integrity: sha512-vBsSiMYhpG6zMiFUFmGoeo/0Ff882m7GLmy2dutsnx9NI+bces+ap4e5tKrzy4TzAAFHlvU1Io6SN8IeUp689w==} dependencies: @@ -5520,7 +5402,6 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true /aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} @@ -5607,7 +5488,6 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true /aria-hidden@1.2.3: resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} @@ -5718,6 +5598,13 @@ packages: /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + /ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.2 + dev: false + /ast-types@0.15.2: resolution: {integrity: sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==} engines: {node: '>=4'} @@ -5787,6 +5674,10 @@ packages: - debug dev: true + /b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + dev: false + /babel-core@7.0.0-bridge.0(@babel/core@7.23.2): resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} peerDependencies: @@ -5874,7 +5765,11 @@ packages: /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true + + /basic-ftp@5.0.3: + resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==} + engines: {node: '>=10.0.0'} + dev: false /bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} @@ -6015,7 +5910,6 @@ packages: /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: true /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -6026,7 +5920,6 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: true /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} @@ -6069,7 +5962,6 @@ packages: /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - dev: true /camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} @@ -6190,6 +6082,16 @@ packages: engines: {node: '>=6.0'} dev: true + /chromium-bidi@0.4.32(devtools-protocol@0.0.1191157): + resolution: {integrity: sha512-RJnw0PW3sNdx1WclINVfVVx8JUH+tWTHZNpnEzlcM+Qgvf40dUH34U7gJq+cc/0LE+rbPxeT6ldqWrCbUf4jeg==} + peerDependencies: + devtools-protocol: '*' + dependencies: + devtools-protocol: 0.0.1191157 + mitt: 3.0.1 + urlpattern-polyfill: 9.0.0 + dev: false + /ci-info@3.8.0: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} engines: {node: '>=8'} @@ -6259,7 +6161,6 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: true /clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} @@ -6403,6 +6304,22 @@ packages: yaml: 1.10.2 dev: true + /cosmiconfig@8.3.6(typescript@5.2.2): + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + typescript: 5.2.2 + dev: false + /cross-fetch@3.1.6: resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} dependencies: @@ -6411,6 +6328,14 @@ packages: - encoding dev: true + /cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -6446,6 +6371,11 @@ packages: /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + /data-uri-to-buffer@6.0.1: + resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==} + engines: {node: '>= 14'} + dev: false + /data-urls@4.0.0: resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} engines: {node: '>=14'} @@ -6611,6 +6541,15 @@ packages: resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} dev: true + /degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + dev: false + /del@6.1.1: resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} engines: {node: '>=10'} @@ -6672,6 +6611,10 @@ packages: - supports-color dev: true + /devtools-protocol@0.0.1191157: + resolution: {integrity: sha512-Fu2mUhX7zkzLHMJZk5wQTiHdl1eJrhK0GypUoSzogUt51MmYEv/46pCz4PtGGFlr0f2ZyYDzzx5CPtbEkuvcTA==} + dev: false + /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} dev: true @@ -6825,7 +6768,6 @@ packages: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 - dev: true /es-abstract@1.22.1: resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} @@ -7556,6 +7498,20 @@ packages: - supports-color dev: true + /extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + dependencies: + debug: 4.3.4 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.2 + transitivePeerDependencies: + - supports-color + dev: false + /fast-copy@2.1.7: resolution: {integrity: sha512-ozrGwyuCTAy7YgFCua8rmqmytECYk/JYAMXcswOcm0qvGoE3tPb7ivBeIHTOK2DiapBhDZgacIhzhQIKU5TCfA==} dev: false @@ -7571,6 +7527,10 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + dev: false + /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} @@ -7612,7 +7572,6 @@ packages: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} dependencies: pend: 1.2.0 - dev: true /fetch-retry@5.0.6: resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==} @@ -7642,15 +7601,6 @@ packages: fs-extra: 11.1.1 ramda: 0.29.0 - /file-system-cache@2.4.4: - resolution: {integrity: sha512-vCYhn8pb5nlC3Gs2FFCOkmf4NEg2Ym3ulJwkmS9o6p9oRShGj6CwTMFvpgZihBlsh373NaM0XgAgDHXQIlS4LQ==} - dependencies: - '@types/fs-extra': 11.0.1 - '@types/ramda': 0.29.3 - fs-extra: 11.1.1 - ramda: 0.29.0 - dev: true - /filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} dependencies: @@ -7793,6 +7743,15 @@ packages: jsonfile: 6.1.0 universalify: 2.0.0 + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: false + /fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -7864,6 +7823,13 @@ packages: engines: {node: '>=8'} dev: true + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: false + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -7883,6 +7849,18 @@ packages: resolve-pkg-maps: 1.0.0 dev: true + /get-uri@6.0.2: + resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==} + engines: {node: '>= 14'} + dependencies: + basic-ftp: 5.0.3 + data-uri-to-buffer: 6.0.1 + debug: 4.3.4 + fs-extra: 8.1.0 + transitivePeerDependencies: + - supports-color + dev: false + /giget@1.1.3: resolution: {integrity: sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q==} hasBin: true @@ -8144,6 +8122,16 @@ packages: transitivePeerDependencies: - supports-color + /http-proxy-agent@7.0.0: + resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + /https-proxy-agent@4.0.0: resolution: {integrity: sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==} engines: {node: '>= 6.0.0'} @@ -8171,7 +8159,6 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} @@ -8227,7 +8214,6 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} @@ -8240,7 +8226,6 @@ packages: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -8294,9 +8279,12 @@ packages: dependencies: loose-envify: 1.4.0 + /ip@1.1.8: + resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} + dev: false + /ip@2.0.0: resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} - dev: true /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} @@ -8324,7 +8312,6 @@ packages: /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true /is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} @@ -8772,7 +8759,6 @@ packages: hasBin: true dependencies: argparse: 2.0.1 - dev: true /jscodeshift@0.14.0(@babel/preset-env@7.22.20): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} @@ -8862,7 +8848,6 @@ packages: /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true /json-rpc-engine@6.1.0: resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} @@ -8903,6 +8888,12 @@ packages: /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: @@ -8969,7 +8960,6 @@ packages: /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true /linkify-it@3.0.3: resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} @@ -9064,6 +9054,11 @@ packages: dependencies: yallist: 4.0.0 + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: false + /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -9263,9 +9258,12 @@ packages: yallist: 4.0.0 dev: true + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: false + /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - dev: true /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} @@ -9373,6 +9371,11 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + /netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + dev: false + /node-dir@0.1.17: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} @@ -9662,6 +9665,31 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + /pac-proxy-agent@7.0.1: + resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} + engines: {node: '>= 14'} + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.0 + debug: 4.3.4 + get-uri: 6.0.2 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + pac-resolver: 7.0.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /pac-resolver@7.0.0: + resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==} + engines: {node: '>= 14'} + dependencies: + degenerator: 5.0.1 + ip: 1.1.8 + netmask: 2.0.2 + dev: false + /pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} dev: true @@ -9671,7 +9699,6 @@ packages: engines: {node: '>=6'} dependencies: callsites: 3.1.0 - dev: true /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} @@ -9681,7 +9708,6 @@ packages: error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: true /parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} @@ -9737,7 +9763,6 @@ packages: /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - dev: true /pathe@1.1.1: resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} @@ -9755,7 +9780,6 @@ packages: /pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - dev: true /php-parser@3.1.5: resolution: {integrity: sha512-jEY2DcbgCm5aclzBdfW86GM6VEIWcSlhTBSHN1qhJguVePlYe28GhwS0yoeLYXpM2K8y6wzLwrbq814n2PHSoQ==} @@ -10004,7 +10028,6 @@ packages: /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - dev: true /prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} @@ -10030,9 +10053,24 @@ packages: ipaddr.js: 1.9.1 dev: true + /proxy-agent@6.3.1: + resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.1 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: false + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: true /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} @@ -10082,6 +10120,39 @@ packages: - utf-8-validate dev: true + /puppeteer-core@21.4.0: + resolution: {integrity: sha512-ONYjYgHItm6i9WdJf+MnRTRPB4HegwPbPfi1jjNN0LCW3rnNich/5hXgZFcn2oWvgFc8DWLDIcwly7C8z+EvIw==} + engines: {node: '>=16.3.0'} + dependencies: + '@puppeteer/browsers': 1.8.0 + chromium-bidi: 0.4.32(devtools-protocol@0.0.1191157) + cross-fetch: 4.0.0 + debug: 4.3.4 + devtools-protocol: 0.0.1191157 + ws: 8.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: false + + /puppeteer@21.4.0(typescript@5.2.2): + resolution: {integrity: sha512-KkiDe39NJxlw7fyiN6fieM9SVsewzt037nUZRoffNuFtYdAl5rRLVtleBuVZ5i1swK/R4CmA6Pbka/ytpFCu4Q==} + engines: {node: '>=16.3.0'} + requiresBuild: true + dependencies: + '@puppeteer/browsers': 1.8.0 + cosmiconfig: 8.3.6(typescript@5.2.2) + puppeteer-core: 21.4.0 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - typescript + - utf-8-validate + dev: false + /qr.js@0.0.0: resolution: {integrity: sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==} dev: true @@ -10127,6 +10198,10 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + dev: false + /ramda@0.29.0: resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} @@ -10653,7 +10728,6 @@ packages: /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - dev: true /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} @@ -10958,6 +11032,30 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: false + + /socks-proxy-agent@8.0.2: + resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: false + + /socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: false + /sortablejs@1.15.0: resolution: {integrity: sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==} dev: false @@ -11040,7 +11138,7 @@ packages: /store2@2.14.2: resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==} - /storybook-i18n@2.0.13(@storybook/components@7.4.6)(@storybook/manager-api@7.4.6)(@storybook/preview-api@7.4.6)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0): + /storybook-i18n@2.0.13(@storybook/components@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-p0VPL5QiHdeS3W9BvV7UnuTKw7Mj1HWLW67LK0EOoh5fpSQIchu7byfrUUe1RbCF1gT0gOOhdNuTSXMoVVoTDw==} peerDependencies: '@storybook/components': ^7.0.0 @@ -11055,15 +11153,15 @@ packages: react-dom: optional: true dependencies: - '@storybook/components': 7.4.6(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 + '@storybook/components': 7.5.1(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.5.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.1 '@storybook/types': 7.5.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /storybook-react-i18next@2.0.9(@storybook/components@7.4.6)(@storybook/manager-api@7.4.6)(@storybook/preview-api@7.4.6)(@storybook/types@7.5.1)(i18next-browser-languagedetector@7.1.0)(i18next-http-backend@2.2.2)(i18next@22.5.1)(react-dom@18.2.0)(react-i18next@12.3.1)(react@18.2.0): + /storybook-react-i18next@2.0.9(@storybook/components@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/types@7.5.1)(i18next-browser-languagedetector@7.1.0)(i18next-http-backend@2.2.2)(i18next@22.5.1)(react-dom@18.2.0)(react-i18next@12.3.1)(react@18.2.0): resolution: {integrity: sha512-GFTOrYwOWShLqWNuTesPNhC79P3OHw1jkZ4gU3R50yTD2MUclF5DHLnuKeVfKZ323iV+I9fxLxuLIVHWVDJgXA==} peerDependencies: '@storybook/components': ^7.0.0 @@ -11082,9 +11180,9 @@ packages: react-dom: optional: true dependencies: - '@storybook/components': 7.4.6(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) - '@storybook/manager-api': 7.4.6(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.4.6 + '@storybook/components': 7.5.1(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.5.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.5.1 '@storybook/types': 7.5.1 i18next: 22.5.1 i18next-browser-languagedetector: 7.1.0 @@ -11092,14 +11190,14 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-i18next: 12.3.1(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0) - storybook-i18n: 2.0.13(@storybook/components@7.4.6)(@storybook/manager-api@7.4.6)(@storybook/preview-api@7.4.6)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0) + storybook-i18n: 2.0.13(@storybook/components@7.5.1)(@storybook/manager-api@7.5.1)(@storybook/preview-api@7.5.1)(@storybook/types@7.5.1)(react-dom@18.2.0)(react@18.2.0) dev: true - /storybook@7.5.0-alpha.4: - resolution: {integrity: sha512-DsQUgiZan9pa70ZeFcVHimfWAFpymY5+iyYgNfmgS6MJc7LeFOXVtynM5mcbhGVnvcgho6T3W35vGQzanJcdYg==} + /storybook@7.6.0-alpha.2: + resolution: {integrity: sha512-zs/t//ohhV5bmC5EYa4UNtBl0YbEswbqxGXPI3XCc3wOUDZhR98LEECiZXz1jNloFHWJVRjVUCGRIwPzBf+AlQ==} hasBin: true dependencies: - '@storybook/cli': 7.5.0-alpha.4 + '@storybook/cli': 7.6.0-alpha.2 transitivePeerDependencies: - bufferutil - encoding @@ -11111,6 +11209,13 @@ packages: resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} dev: true + /streamx@2.15.1: + resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + dev: false + /strict-event-emitter@0.2.8: resolution: {integrity: sha512-KDf/ujU8Zud3YaLtMCcTI4xkZlZVIYxTLr+XIULexP+77EEVWixeXroLUXQXiVtH4XH2W7jr/3PT1v3zBuvc3A==} dependencies: @@ -11356,6 +11461,14 @@ packages: tar-stream: 2.2.0 dev: true + /tar-fs@3.0.4: + resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} + dependencies: + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 3.1.6 + dev: false + /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} @@ -11367,6 +11480,14 @@ packages: readable-stream: 3.6.2 dev: true + /tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + dependencies: + b4a: 1.6.4 + fast-fifo: 1.3.2 + streamx: 2.15.1 + dev: false + /tar@6.2.0: resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} engines: {node: '>=10'} @@ -11477,7 +11598,6 @@ packages: /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true /tiny-invariant@1.2.0: resolution: {integrity: sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==} @@ -11586,10 +11706,6 @@ packages: webpack: 5.88.2(esbuild@0.18.20) dev: true - /ts-toolbelt@9.6.0: - resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} - dev: true - /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -11706,17 +11822,10 @@ packages: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} dev: true - /types-ramda@0.29.5: - resolution: {integrity: sha512-u+bAYXHDPJR+amB0qMrMU/NXRB2PG8QqpO2v6j7yK/0mPZhlaaZj++ynYjnVpkPEpCkZEGxNpWY3X7qyLCGE3w==} - dependencies: - ts-toolbelt: 9.6.0 - dev: true - /typescript@5.2.2: resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} engines: {node: '>=14.17'} hasBin: true - dev: true /uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} @@ -11741,6 +11850,13 @@ packages: which-boxed-primitive: 1.0.2 dev: true + /unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + dependencies: + buffer: 5.7.1 + through: 2.3.8 + dev: false + /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} @@ -11787,6 +11903,11 @@ packages: unist-util-is: 4.1.0 unist-util-visit-parents: 3.1.1 + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: false + /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -11846,6 +11967,10 @@ packages: querystringify: 2.2.0 requires-port: 1.0.0 + /urlpattern-polyfill@9.0.0: + resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} + dev: false + /use-callback-ref@1.3.0(@types/react@18.2.31)(react@18.2.0): resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} engines: {node: '>=10'} @@ -12379,7 +12504,6 @@ packages: optional: true utf-8-validate: optional: true - dev: true /xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} @@ -12400,7 +12524,6 @@ packages: /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - dev: true /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -12429,7 +12552,6 @@ packages: /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - dev: true /yargs@15.4.1: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} @@ -12459,14 +12581,12 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: true /yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} dependencies: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - dev: true /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} diff --git a/queries/gallery.get_meta_images.sql b/queries/gallery.get_meta_images.sql new file mode 100644 index 000000000..cbf12db53 --- /dev/null +++ b/queries/gallery.get_meta_images.sql @@ -0,0 +1,34 @@ +/** +* IMPORTANT: Ensure this query is in sync with the method in `app/Http/Controllers/MetaImageController.php@getImageName` +*/ +SELECT + CONCAT( + "galleries".slug, + '_', + MD5(CONCAT( + string_agg(CAST(sub.nft_id AS VARCHAR), '.'), + '_', + count(sub.nft_id), + '_', + "galleries".name + )), '.png') AS image_name +FROM + "galleries" + INNER JOIN ( + SELECT + "nft_gallery"."gallery_id", + "nft_gallery"."nft_id", + ROW_NUMBER() OVER (PARTITION BY "nft_gallery"."gallery_id" ORDER BY "nft_gallery"."order_index" ASC) AS rn + FROM + "nft_gallery" + WHERE + "nft_gallery"."gallery_id" IN( + SELECT + id FROM "galleries" + WHERE + "deleted_at" IS NULL)) AS sub ON sub. "gallery_id" = "galleries"."id" + WHERE + sub.rn <= 4 + AND "galleries"."deleted_at" IS NULL + GROUP BY + "galleries".id; \ No newline at end of file diff --git a/resources/images/gallery/gallery_template.png b/resources/images/gallery/gallery_template.png new file mode 100644 index 000000000..4e697656b Binary files /dev/null and b/resources/images/gallery/gallery_template.png differ diff --git a/routes/web.php b/routes/web.php index fc8179811..055fc1538 100644 --- a/routes/web.php +++ b/routes/web.php @@ -10,6 +10,7 @@ use App\Http\Controllers\GalleryReportController; use App\Http\Controllers\GeneralSettingsController; use App\Http\Controllers\HiddenCollectionController; +use App\Http\Controllers\MetaImageController; use App\Http\Controllers\MyGalleryCollectionController; use App\Http\Controllers\MyGalleryController; use App\Http\Controllers\NftController; @@ -93,6 +94,8 @@ Route::get('{gallery:slug}', [GalleryController::class, 'view']) ->middleware(RecordGalleryView::class) ->name('galleries.view'); + + Route::get('{gallery:slug}/meta-image.png', MetaImageController::class)->name('galleries.meta-image'); }); require __DIR__.'/auth.php'; diff --git a/storage/meta/galleries/.gitignore b/storage/meta/galleries/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/storage/meta/galleries/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/tmp/.gitignore b/storage/tmp/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/storage/tmp/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/App/Console/Commands/PruneMetaImagesTest.php b/tests/App/Console/Commands/PruneMetaImagesTest.php new file mode 100644 index 000000000..dfce69821 --- /dev/null +++ b/tests/App/Console/Commands/PruneMetaImagesTest.php @@ -0,0 +1,70 @@ +create([ + 'name' => 'my gallery', + ]); + $gallery->nfts()->attach(Nft::factory()->create(), ['order_index' => 2]); + $gallery->nfts()->attach(Nft::factory()->create(), ['order_index' => 1]); + $gallery->nfts()->attach(Nft::factory()->create(), ['order_index' => 3]); + + $gallery2 = Gallery::factory()->create([ + 'name' => 'other name of my gallery', + ]); + $gallery2->nfts()->attach(Nft::factory()->create(), ['order_index' => 0]); + $gallery2->nfts()->attach(Nft::factory()->create(), ['order_index' => 1]); + + $gallery3 = Gallery::factory()->create([ + 'name' => 'This is another NAME', + ]); + $gallery3->nfts()->attach(Nft::factory()->create(), ['order_index' => 0]); + + // for gallery 1 + copy(base_path('tests/fixtures/page-screenshot.png'), storage_path('meta/galleries/my-gallery_dd0f42923f5f46c600b8e7503dd6290b.png')); + + // no image for gallery 2 + // .... + + // for gallery 3 + copy(base_path('tests/fixtures/page-screenshot.png'), storage_path('meta/galleries/this-is-another-name_94bb0c06f620aaf0f3ce27f3df8c1869.png')); + + // similar name to gallery 3 (should be removed) + copy(base_path('tests/fixtures/page-screenshot.png'), storage_path('meta/galleries/this-is-another-name_differenthash.png')); + + expect(glob($directory.'*'))->toHaveCount(3); + + $this->artisan('prune-meta-images'); + + expect(glob($directory.'*'))->toHaveCount(2); +}); diff --git a/tests/App/Http/Controllers/MetaImageControllerTest.php b/tests/App/Http/Controllers/MetaImageControllerTest.php new file mode 100644 index 000000000..4cac46251 --- /dev/null +++ b/tests/App/Http/Controllers/MetaImageControllerTest.php @@ -0,0 +1,145 @@ +create([ + 'name' => 'Test Gallery', + ]); + + // md5 hash hardcoded here, comes from gallery name and amount and order of nfts (zero in this case) + copy(base_path('tests/fixtures/page-screenshot.png'), storage_path('meta/galleries/test-gallery_322d55e3faec28077221c1c01b69a30f.png')); + + $this + ->mock(Browsershot::class) + ->shouldNotReceive('url'); + + $this + ->get(route('galleries.meta-image', ['gallery' => $gallery->slug])) + ->assertOk(); +}); + +it('generates an image', function () { + $gallery = Gallery::factory()->create(); + + $this + ->mock(Browsershot::class) + ->shouldReceive('url') + ->with(route('galleries.view', ['gallery' => $gallery->slug])) + ->once() + ->andReturnSelf() + ->shouldReceive('windowSize') + ->once() + ->andReturnSelf() + ->shouldReceive('timeout') + ->once() + ->andReturnSelf() + ->shouldReceive('waitForFunction') + ->once() + ->andReturnSelf() + ->shouldReceive('setNodeBinary') + ->once() + ->andReturnSelf() + ->shouldReceive('setNpmBinary') + ->once() + ->andReturnSelf() + // Mock save method implementation + ->shouldReceive('save') + ->once() + ->andReturnUsing(function ($test) { + // Emulate stored screenshot + copy(base_path('tests/fixtures/page-screenshot.png'), $test); + }); + + $this->get(route('galleries.meta-image', ['gallery' => $gallery->slug]))->assertOk(); + + $directory = storage_path('meta/galleries'); + + $files = glob($directory.'/'.$gallery->slug.'*'); + + expect($files)->toHaveCount(1); +}); + +it('removes deprecated existing images for the gallery when pruning', function () { + $gallery = Gallery::factory()->create(); + + $nft = Nft::factory()->create(); + + $gallery->nfts()->attach($nft, ['order_index' => 0]); + + // Pre-existing image + copy(base_path('tests/fixtures/page-screenshot.png'), storage_path('meta/galleries/'.$gallery->slug.'_test.png')); + + // For other gallery + copy(base_path('tests/fixtures/page-screenshot.png'), storage_path('meta/galleries/other-slug_test.png')); + + $directory = storage_path('meta/galleries'); + + $this + ->mock(Browsershot::class) + ->shouldReceive('url') + ->with(route('galleries.view', ['gallery' => $gallery->slug])) + ->once() + ->andReturnSelf() + ->shouldReceive('windowSize') + ->once() + ->andReturnSelf() + ->shouldReceive('timeout') + ->with(60) + ->once() + ->andReturnSelf() + ->shouldReceive('waitForFunction') + ->once() + ->andReturnSelf() + ->shouldReceive('setNodeBinary') + ->once() + ->andReturnSelf() + ->shouldReceive('setNpmBinary') + ->once() + ->andReturnSelf() + // Mock save method implementation + ->shouldReceive('save') + ->once() + ->andReturnUsing(function ($test) { + // Emulate stored screenshot + copy(base_path('tests/fixtures/page-screenshot.png'), $test); + }); + + $this->get(route('galleries.meta-image', ['gallery' => $gallery->slug]))->assertOk(); + + $directory = storage_path('meta/galleries/'); + + expect(glob($directory.'*'))->toHaveCount(3); + + Artisan::call('prune-meta-images'); + + expect(glob($directory.'/*'))->toHaveCount(1); +}); diff --git a/tests/Helpers.php b/tests/Helpers.php index 32be702d5..fbb492a34 100644 --- a/tests/Helpers.php +++ b/tests/Helpers.php @@ -3,6 +3,7 @@ declare(strict_types=1); use App\Support\PermissionRepository; +use Illuminate\Support\Facades\File; use Spatie\Permission\Models\Permission; use Spatie\Permission\Models\Role; use Spatie\Permission\PermissionRegistrar; @@ -26,3 +27,12 @@ function setUpPermissions(string $guard = 'admin'): void 'guard_name' => $guard, ])->givePermissionTo($permissions)); } + +function emptyMetaImagesFolder(): void +{ + $metaImagesDir = storage_path('meta/galleries'); + + File::deleteDirectory($metaImagesDir); + + File::makeDirectory($metaImagesDir); +} diff --git a/tests/fixtures/page-screenshot.png b/tests/fixtures/page-screenshot.png new file mode 100644 index 000000000..7ccb36f2b Binary files /dev/null and b/tests/fixtures/page-screenshot.png differ