From 90d327fdaa8fca8b43a491537c1221c3d5167fe8 Mon Sep 17 00:00:00 2001 From: Rahul Singh <27360432+rahools@users.noreply.github.com> Date: Sun, 22 Mar 2026 11:59:36 +0530 Subject: [PATCH 01/36] Added AI Assisted Information Provider --- .../Providers/AIInfoExtractor.php | 490 ++++++++++++++++++ .../Providers/ProviderCapabilities.php | 6 + .../AIExtractorSettings.php | 58 +++ .../InfoProviderSettings.php | 3 + 4 files changed, 557 insertions(+) create mode 100644 src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php create mode 100644 src/Settings/InfoProviderSystem/AIExtractorSettings.php diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php new file mode 100644 index 00000000..d075ea1d --- /dev/null +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -0,0 +1,490 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\InfoProviderSystem\Providers; + +use App\Entity\Parts\ManufacturingStatus; +use App\Services\InfoProviderSystem\DTOs\FileDTO; +use App\Services\InfoProviderSystem\DTOs\ParameterDTO; +use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; +use App\Services\InfoProviderSystem\DTOs\PriceDTO; +use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO; +use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; +use App\Settings\InfoProviderSystem\AIExtractorSettings; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +class AIInfoExtractor implements InfoProviderInterface +{ + private const DISTRIBUTOR_NAME = 'AI Extracted'; + + private readonly HttpClientInterface $httpClient; + + public function __construct(HttpClientInterface $httpClient, private readonly AIExtractorSettings $settings) + { + $this->httpClient = $httpClient->withOptions([ + 'timeout' => 30, + 'headers' => [ + 'User-Agent' => 'Mozilla/5.0 (compatible; Part-DB AI-Extractor/1.0)', + ], + ]); + } + + public function getProviderInfo(): array + { + return [ + 'name' => 'AI Information Extractor', + 'description' => 'Extract part info from any URL using OpenRouter LLM', + 'url' => 'https://openrouter.ai', + 'disabled_help' => 'Configure OpenRouter API key in settings', + 'settings_class' => AIExtractorSettings::class, + ]; + } + + public function getProviderKey(): string + { + return 'ai_extractor'; + } + + public function isActive(): bool + { + return !empty($this->settings->apiKey) && $this->settings->enabled; + } + + public function searchByKeyword(string $keyword): array + { + // Treat the keyword as a URL and return a single search result + $url = $this->normalizeURL($keyword); + + try { + $part = $this->getDetails($url); + return [ + new SearchResultDTO( + provider_key: $this->getProviderKey(), + provider_id: $url, + name: $part->name, + description: $part->description, + category: $part->category, + manufacturer: $part->manufacturer, + mpn: $part->mpn, + preview_image_url: $part->preview_image_url, + manufacturing_status: $part->manufacturing_status, + provider_url: $part->provider_url, + footprint: $part->footprint, + gtin: $part->gtin, + ), + ]; + } catch (\Throwable $e) { + // Return empty array on error + return []; + } + } + + public function getDetails(string $id): PartDetailDTO + { + $url = $this->normalizeURL($id); + + // Fetch HTML content + $response = $this->httpClient->request('GET', $url); + $html = $response->getContent(); + + // Clean HTML + $cleanedHtml = $this->cleanHTML($html); + + // Truncate to max content length + $truncatedHtml = $this->truncateHTML($cleanedHtml, $this->settings->maxContentLength); + + // Call OpenRouter API + $llmResponse = $this->callOpenRouterAPI($truncatedHtml, $url); + + // Parse JSON response + $data = json_decode($llmResponse, true, 512, JSON_THROW_ON_ERROR); + + // Build and return PartDetailDTO + return $this->buildPartDetailDTO($data, $url); + } + + public function getCapabilities(): array + { + return [ + ProviderCapabilities::BASIC, + ProviderCapabilities::PICTURE, + ProviderCapabilities::DATASHEET, + ProviderCapabilities::PRICE, + ProviderCapabilities::PARAMETERS, + ]; + } + + private function normalizeURL(string $url): string + { + // Add https:// if no protocol + if (!preg_match('/^https?:\/\//', $url)) { + $url = 'https://' . ltrim($url, '/'); + } + + // Validate URL + if (filter_var($url, FILTER_VALIDATE_URL) === false) { + throw new \InvalidArgumentException("Invalid URL: $url"); + } + + return $url; + } + + private function cleanHTML(string $html): string + { + // Remove script tags + $html = preg_replace('/]*>(.*?)<\/script>/is', '', $html); + + // Remove style tags + $html = preg_replace('/]*>(.*?)<\/style>/is', '', $html); + + // Remove nav tags + $html = preg_replace('/]*>(.*?)<\/nav>/is', '', $html); + + // Remove footer tags + $html = preg_replace('/]*>(.*?)<\/footer>/is', '', $html); + + // Remove header tags + $html = preg_replace('/]*>(.*?)<\/header>/is', '', $html); + + // Remove HTML comments + $html = preg_replace('//is', '', $html); + + return $html; + } + + private function truncateHTML(string $html, int $maxLength): string + { + if (strlen($html) <= $maxLength) { + return $html; + } + + // Truncate and find the last > or space to avoid cutting tags + $truncated = substr($html, 0, $maxLength); + + // Find the last occurrence of > or space + $lastPos = max(strrpos($truncated, '>'), strrpos($truncated, ' ')); + + if ($lastPos !== false && $lastPos > $maxLength * 0.9) { + $truncated = substr($truncated, 0, $lastPos + 1); + } + + return $truncated; + } + + private function callOpenRouterAPI(string $htmlContent, string $url): string + { + $systemPrompt = $this->buildSystemPrompt(); + + // Define the tool/function for structured output + $toolDefinition = [ + 'type' => 'function', + 'function' => [ + 'name' => 'extract_part_info', + 'description' => 'Extract electronic component information from a webpage', + 'parameters' => [ + 'type' => 'object', + 'properties' => [ + 'name' => ['type' => 'string', 'description' => 'Product name'], + 'description' => ['type' => 'string', 'description' => 'Product description'], + 'manufacturer' => ['type' => ['string', 'null'], 'description' => 'Manufacturer name'], + 'mpn' => ['type' => ['string', 'null'], 'description' => 'Manufacturer Part Number'], + 'category' => ['type' => ['string', 'null'], 'description' => 'Product category'], + 'manufacturing_status' => ['type' => ['string', 'null'], 'enum' => ['active', 'obsolete', 'nrfnd', 'discontinued', null], 'description' => 'Manufacturing status'], + 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type'], + 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass in grams'], + 'parameters' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'name' => ['type' => 'string'], + 'value' => ['type' => 'string'], + 'unit' => ['type' => ['string', 'null']], + ], + 'required' => ['name', 'value'], + ], + ], + 'datasheets' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'url' => ['type' => 'string'], + 'description' => ['type' => 'string'], + ], + 'required' => ['url'], + ], + ], + 'images' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'url' => ['type' => 'string'], + 'description' => ['type' => 'string'], + ], + 'required' => ['url'], + ], + ], + 'vendor_infos' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'distributor_name' => ['type' => 'string'], + 'order_number' => ['type' => ['string', 'null']], + 'product_url' => ['type' => 'string'], + 'prices' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'minimum_quantity' => ['type' => 'integer'], + 'price' => ['type' => 'number'], + 'currency' => ['type' => 'string'], + ], + 'required' => ['minimum_quantity', 'price', 'currency'], + ], + ], + ], + 'required' => ['distributor_name', 'product_url'], + ], + ], + 'manufacturer_product_url' => ['type' => ['string', 'null'], 'description' => 'Manufacturer product page URL'], + ], + 'required' => ['name', 'description'], + ], + ], + ]; + + $payload = [ + 'model' => $this->settings->model, + 'messages' => [ + [ + 'role' => 'system', + 'content' => $systemPrompt, + ], + [ + 'role' => 'user', + 'content' => "Extract part information from this webpage content:\n\nURL: $url\n\n$htmlContent", + ], + ], + 'tools' => [$toolDefinition], + 'tool_choice' => ['type' => 'function', 'function' => ['name' => 'extract_part_info']], + 'max_tokens' => 4096, + 'temperature' => 0.1, + ]; + + $response = $this->httpClient->request('POST', 'https://openrouter.ai/api/v1/chat/completions', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . $this->settings->apiKey, + 'Content-Type' => 'application/json', + 'HTTP-Referer' => 'https://github.com/Part-DB/Part-DB-server', + 'X-Title' => 'Part-DB AI Info Extractor', + ], + 'json' => $payload, + ]); + + $data = $response->toArray(); + + $message = $data['choices'][0]['message'] ?? null; + if ($message === null) { + throw new \RuntimeException('No response message from LLM'); + } + + // Check if the model used the tool/function call + if (isset($message['tool_calls']) && !empty($message['tool_calls'])) { + foreach ($message['tool_calls'] as $toolCall) { + if ($toolCall['function']['name'] === 'extract_part_info') { + return $toolCall['function']['arguments']; + } + } + } + + // Fallback to content if no tool call (some models might not support tool calling) + $content = $message['content'] ?? throw new \RuntimeException('No response content from LLM'); + + // Strip markdown code blocks if present (fallback for models without tool support) + $content = preg_replace('/^```(?:json)?\s*\n?/i', '', $content); + $content = preg_replace('/\n?```\s*$/i', '', $content); + $content = trim($content); + + return $content; + } + + private function buildSystemPrompt(): string + { + return <<<'PROMPT' +You are an expert at extracting electronic component information from web pages. Extract structured data in JSON format. + +Return ONLY a valid JSON object with this exact structure: +{ + "name": "string", + "description": "string", + "manufacturer": "string | null", + "mpn": "string | null", + "category": "string | null", + "manufacturing_status": "active|obsolete|nrfnd|discontinued|null", + "footprint": "string | null", + "mass": "number | null (in grams)", + "parameters": [{"name": "string", "value": "string", "unit": "string | null"}], + "datasheets": [{"url": "string", "description": "string"}], + "images": [{"url": "string", "description": "string"}], + "vendor_infos": [{ + "distributor_name": "string", + "order_number": "string | null", + "product_url": "string", + "prices": [{"minimum_quantity": int, "price": number, "currency": "string"}] + }], + "manufacturer_product_url": "string | null" +} + +Rules: +- manufacturing_status: Use "active", "obsolete", "nrfnd" (not recommended for new designs), "discontinued", or null +- parameters: Extract technical specs like voltage, current, temperature, etc. +- prices: Extract pricing tiers with minimum_quantity, price, and currency code +- URLs must be absolute (include https://...) +- If information is not found, use null +- Return ONLY the JSON, no explanation text + +For parameters, combine name, value, and unit. The unit should be separate if possible. +PROMPT; + } + + private function buildPartDetailDTO(array $data, string $url): PartDetailDTO + { + // Map manufacturing status + $manufacturingStatus = null; + if (!empty($data['manufacturing_status'])) { + $status = strtolower((string) $data['manufacturing_status']); + $manufacturingStatus = match ($status) { + 'active' => ManufacturingStatus::ACTIVE, + 'obsolete', 'discontinued' => ManufacturingStatus::DISCONTINUED, + 'nrfnd', 'not recommended for new designs' => ManufacturingStatus::NRFND, + 'eol' => ManufacturingStatus::EOL, + 'announced' => ManufacturingStatus::ANNOUNCED, + default => null, + }; + } + + // Build parameters + $parameters = null; + if (!empty($data['parameters']) && is_array($data['parameters'])) { + $parameters = []; + foreach ($data['parameters'] as $p) { + if (!empty($p['name'])) { + $value = $p['value'] ?? ''; + $unit = $p['unit'] ?? null; + // Combine value and unit for parsing + $valueWithUnit = $unit ? $value . ' ' . $unit : $value; + $parameters[] = ParameterDTO::parseValueField( + name: $p['name'], + value: $valueWithUnit + ); + } + } + } + + // Build datasheets + $datasheets = null; + if (!empty($data['datasheets']) && is_array($data['datasheets'])) { + $datasheets = []; + foreach ($data['datasheets'] as $d) { + if (!empty($d['url'])) { + $datasheets[] = new FileDTO( + url: $d['url'], + name: $d['description'] ?? 'Datasheet' + ); + } + } + } + + // Build images + $images = null; + if (!empty($data['images']) && is_array($data['images'])) { + $images = []; + foreach ($data['images'] as $i) { + if (!empty($i['url'])) { + $images[] = new FileDTO( + url: $i['url'], + name: $i['description'] ?? 'Image' + ); + } + } + } + + // Build vendor infos + $vendorInfos = null; + if (!empty($data['vendor_infos']) && is_array($data['vendor_infos'])) { + $vendorInfos = []; + foreach ($data['vendor_infos'] as $v) { + $prices = []; + if (!empty($v['prices']) && is_array($v['prices'])) { + foreach ($v['prices'] as $p) { + $prices[] = new PriceDTO( + minimum_discount_amount: (int) ($p['minimum_quantity'] ?? 1), + price: (string) ($p['price'] ?? 0), + currency_iso_code: $p['currency'] ?? 'USD', + price_related_quantity: (int) ($p['minimum_quantity'] ?? 1), + ); + } + } + + $vendorInfos[] = new PurchaseInfoDTO( + distributor_name: $v['distributor_name'] ?? self::DISTRIBUTOR_NAME, + order_number: $v['order_number'] ?? 'Unknown', + prices: $prices, + product_url: $v['product_url'] ?? $url, + ); + } + } + + // Get preview image URL + $previewImageUrl = null; + if (!empty($data['images']) && is_array($data['images']) && !empty($data['images'][0]['url'])) { + $previewImageUrl = $data['images'][0]['url']; + } + + return new PartDetailDTO( + provider_key: $this->getProviderKey(), + provider_id: $url, + name: $data['name'] ?? 'Unknown', + description: $data['description'] ?? '', + category: $data['category'] ?? null, + manufacturer: $data['manufacturer'] ?? null, + mpn: $data['mpn'] ?? null, + preview_image_url: $previewImageUrl, + manufacturing_status: $manufacturingStatus, + provider_url: $url, + footprint: $data['footprint'] ?? null, + mass: isset($data['mass']) && is_numeric($data['mass']) ? (float) $data['mass'] : null, + notes: null, + datasheets: $datasheets, + images: $images, + parameters: $parameters, + vendor_infos: $vendorInfos, + manufacturer_product_url: $data['manufacturer_product_url'] ?? null, + ); + } +} diff --git a/src/Services/InfoProviderSystem/Providers/ProviderCapabilities.php b/src/Services/InfoProviderSystem/Providers/ProviderCapabilities.php index 21fba53b..3a7d03e9 100644 --- a/src/Services/InfoProviderSystem/Providers/ProviderCapabilities.php +++ b/src/Services/InfoProviderSystem/Providers/ProviderCapabilities.php @@ -46,6 +46,9 @@ enum ProviderCapabilities /** Provider can provide GTIN for a part */ case GTIN; + /** Provider can provide parameters/specifications for a part */ + case PARAMETERS; + /** * Get the order index for displaying capabilities in a stable order. * @return int @@ -59,6 +62,7 @@ enum ProviderCapabilities self::PRICE => 4, self::FOOTPRINT => 5, self::GTIN => 6, + self::PARAMETERS => 7, }; } @@ -71,6 +75,7 @@ enum ProviderCapabilities self::DATASHEET => 'datasheet', self::PRICE => 'price', self::GTIN => 'gtin', + self::PARAMETERS => 'parameters', }; } @@ -83,6 +88,7 @@ enum ProviderCapabilities self::DATASHEET => 'fa-file-alt', self::PRICE => 'fa-money-bill-wave', self::GTIN => 'fa-barcode', + self::PARAMETERS => 'fa-list-ul', }; } } diff --git a/src/Settings/InfoProviderSystem/AIExtractorSettings.php b/src/Settings/InfoProviderSystem/AIExtractorSettings.php new file mode 100644 index 00000000..c78ca96e --- /dev/null +++ b/src/Settings/InfoProviderSystem/AIExtractorSettings.php @@ -0,0 +1,58 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Settings\InfoProviderSystem; + +use App\Settings\SettingsIcon; +use Jbtronics\SettingsBundle\Metadata\EnvVarMode; +use Jbtronics\SettingsBundle\Settings\Settings; +use Jbtronics\SettingsBundle\Settings\SettingsParameter; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\Component\Translation\TranslatableMessage as TM; + +#[Settings(name: "ai_extractor", label: new TM("settings.ips.ai_extractor"), description: new TM("settings.ips.ai_extractor.description"))] +#[SettingsIcon("fa-robot")] +class AIExtractorSettings +{ + use SettingsTrait; + + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.api_key"), description: new TM("settings.ips.ai_extractor.api_key.description"), + envVar: "string:PROVIDER_AI_EXTRACTOR_API_KEY", envVarMode: EnvVarMode::OVERWRITE + )] + public ?string $apiKey = null; + + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.model"), description: new TM("settings.ips.ai_extractor.model.description"), + envVar: "string:PROVIDER_AI_EXTRACTOR_MODEL", envVarMode: EnvVarMode::OVERWRITE + )] + public string $model = 'z-ai/glm-4.7'; + + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.enabled"), description: new TM("settings.ips.ai_extractor.enabled.description"), + envVar: "bool:PROVIDER_AI_EXTRACTOR_ENABLED", envVarMode: EnvVarMode::OVERWRITE + )] + public bool $enabled = false; + + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.max_content_length"), description: new TM("settings.ips.ai_extractor.max_content_length.description"), + envVar: "int:PROVIDER_AI_EXTRACTOR_MAX_CONTENT_LENGTH", envVarMode: EnvVarMode::OVERWRITE + )] + public int $maxContentLength = 50000; +} diff --git a/src/Settings/InfoProviderSystem/InfoProviderSettings.php b/src/Settings/InfoProviderSystem/InfoProviderSettings.php index 248fcedc..be0fe746 100644 --- a/src/Settings/InfoProviderSystem/InfoProviderSettings.php +++ b/src/Settings/InfoProviderSystem/InfoProviderSettings.php @@ -75,4 +75,7 @@ class InfoProviderSettings #[EmbeddedSettings] public ?CanopySettings $canopy = null; + + #[EmbeddedSettings] + public ?AIExtractorSettings $aiExtractor = null; } From 9cf16248e664074e9d710d4bb4ab5eece9673d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Thu, 23 Apr 2026 23:26:23 +0200 Subject: [PATCH 02/36] Use symfony AI platform for AI provider --- .env | 8 + composer.json | 3 + composer.lock | 610 +++++++++++++++++- config/bundles.php | 1 + config/packages/ai.yaml | 27 + config/packages/ai_generic_platform.yaml | 5 + config/packages/ai_lm_studio_platform.yaml | 3 + config/packages/ai_open_router_platform.yaml | 4 + config/reference.php | 464 +++++++++++++ .../Providers/AIInfoExtractor.php | 161 ++++- symfony.lock | 48 ++ 11 files changed, 1304 insertions(+), 30 deletions(-) create mode 100644 config/packages/ai.yaml create mode 100644 config/packages/ai_generic_platform.yaml create mode 100644 config/packages/ai_lm_studio_platform.yaml create mode 100644 config/packages/ai_open_router_platform.yaml diff --git a/.env b/.env index 79bdcefe..2ea04325 100644 --- a/.env +++ b/.env @@ -155,3 +155,11 @@ APP_ENV=prod APP_SECRET=a03498528f5a5fc089273ec9ae5b2849 APP_SHARE_DIR=var/share ###< symfony/framework-bundle ### + +###> symfony/ai-generic-platform ### +# GENERIC_BASE_URL=https://api.example.com/v1 +###< symfony/ai-generic-platform ### + +###> symfony/ai-open-router-platform ### +OPENROUTER_API_KEY= +###< symfony/ai-open-router-platform ### diff --git a/composer.json b/composer.json index 9d51033e..c7c52d5c 100644 --- a/composer.json +++ b/composer.json @@ -56,6 +56,9 @@ "scheb/2fa-trusted-device": "^v7.11.0", "shivas/versioning-bundle": "^4.0", "spatie/db-dumper": "^3.3.1", + "symfony/ai-bundle": "^0.8.0", + "symfony/ai-lm-studio-platform": "^0.8.0", + "symfony/ai-open-router-platform": "^0.8.0", "symfony/apache-pack": "^1.0", "symfony/asset": "7.4.*", "symfony/console": "7.4.*", diff --git a/composer.lock b/composer.lock index 3ad11a45..00b5e831 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": "8fd737684b48f8d24fcad35fce37a297", + "content-hash": "699f421ad81f8a1acacf8e2c4af66491", "packages": [ { "name": "amphp/amp", @@ -7821,6 +7821,58 @@ ], "time": "2025-12-09T10:50:49+00:00" }, + { + "name": "oskarstark/enum-helper", + "version": "1.8.4", + "source": { + "type": "git", + "url": "https://github.com/OskarStark/enum-helper.git", + "reference": "14e185f1cc259d7cd3f61eea17f9b174a886a6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/OskarStark/enum-helper/zipball/14e185f1cc259d7cd3f61eea17f9b174a886a6da", + "reference": "14e185f1cc259d7cd3f61eea17f9b174a886a6da", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "phpunit/phpunit": "<10" + }, + "require-dev": { + "ergebnis/php-cs-fixer-config": "^6.58", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.5", + "rector/rector": "^2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "OskarStark\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + } + ], + "description": "This library provides helpers for several enum operations", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/OskarStark/enum-helper/issues", + "source": "https://github.com/OskarStark/enum-helper/tree/1.8.4" + }, + "time": "2026-02-05T08:59:09+00:00" + }, { "name": "paragonie/constant_time_encoding", "version": "v3.1.3", @@ -10341,6 +10393,552 @@ ], "time": "2026-03-23T22:56:56+00:00" }, + { + "name": "symfony/ai-bundle", + "version": "v0.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-bundle.git", + "reference": "847365e0f885f8814421e9c94f03ce19e0b54bbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-bundle/zipball/847365e0f885f8814421e9c94f03ce19e0b54bbc", + "reference": "847365e0f885f8814421e9c94f03ce19e0b54bbc", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/ai-platform": "^0.8", + "symfony/clock": "^7.3|^8.0", + "symfony/config": "^7.3|^8.0", + "symfony/console": "^7.3|^8.0", + "symfony/dependency-injection": "^7.3|^8.0", + "symfony/framework-bundle": "^7.3|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.3|^8.0" + }, + "require-dev": { + "google/auth": "^1.47", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53", + "symfony/ai-agent": "^0.8", + "symfony/ai-ai-ml-api-platform": "^0.8", + "symfony/ai-albert-platform": "^0.8", + "symfony/ai-amazee-ai-platform": "^0.8", + "symfony/ai-anthropic-platform": "^0.8", + "symfony/ai-azure-platform": "^0.8", + "symfony/ai-azure-search-store": "^0.8", + "symfony/ai-bedrock-platform": "^0.8", + "symfony/ai-cache-message-store": "^0.8", + "symfony/ai-cache-platform": "^0.8", + "symfony/ai-cache-store": "^0.8", + "symfony/ai-cartesia-platform": "^0.8", + "symfony/ai-cerebras-platform": "^0.8", + "symfony/ai-chat": "^0.8", + "symfony/ai-chroma-db-store": "^0.8", + "symfony/ai-click-house-store": "^0.8", + "symfony/ai-cloudflare-message-store": "^0.8", + "symfony/ai-cloudflare-store": "^0.8", + "symfony/ai-decart-platform": "^0.8", + "symfony/ai-deep-seek-platform": "^0.8", + "symfony/ai-docker-model-runner-platform": "^0.8", + "symfony/ai-doctrine-message-store": "^0.8", + "symfony/ai-elasticsearch-store": "^0.8", + "symfony/ai-eleven-labs-platform": "^0.8", + "symfony/ai-failover-platform": "^0.8", + "symfony/ai-gemini-platform": "^0.8", + "symfony/ai-generic-platform": "^0.8", + "symfony/ai-hugging-face-platform": "^0.8", + "symfony/ai-lm-studio-platform": "^0.8", + "symfony/ai-manticore-search-store": "^0.8", + "symfony/ai-maria-db-store": "^0.8", + "symfony/ai-meilisearch-message-store": "^0.8", + "symfony/ai-meilisearch-store": "^0.8", + "symfony/ai-meta-platform": "^0.8", + "symfony/ai-milvus-store": "^0.8", + "symfony/ai-mistral-platform": "^0.8", + "symfony/ai-mongo-db-message-store": "^0.8", + "symfony/ai-mongo-db-store": "^0.8", + "symfony/ai-neo4j-store": "^0.8", + "symfony/ai-ollama-platform": "^0.8", + "symfony/ai-open-ai-platform": "^0.8", + "symfony/ai-open-responses-platform": "^0.8", + "symfony/ai-open-router-platform": "^0.8", + "symfony/ai-open-search-store": "^0.8", + "symfony/ai-perplexity-platform": "^0.8", + "symfony/ai-pinecone-store": "^0.8", + "symfony/ai-pogocache-message-store": "^0.8", + "symfony/ai-postgres-store": "^0.8", + "symfony/ai-qdrant-store": "^0.8", + "symfony/ai-redis-message-store": "^0.8", + "symfony/ai-redis-store": "^0.8", + "symfony/ai-replicate-platform": "^0.8", + "symfony/ai-s3vectors-store": "^0.8", + "symfony/ai-scaleway-platform": "^0.8", + "symfony/ai-session-message-store": "^0.8", + "symfony/ai-sqlite-store": "^0.8", + "symfony/ai-store": "^0.8", + "symfony/ai-supabase-store": "^0.8", + "symfony/ai-surreal-db-message-store": "^0.8", + "symfony/ai-surreal-db-store": "^0.8", + "symfony/ai-transformers-php-platform": "^0.8", + "symfony/ai-typesense-store": "^0.8", + "symfony/ai-vektor-store": "^0.8", + "symfony/ai-vertex-ai-platform": "^0.8", + "symfony/ai-voyage-platform": "^0.8", + "symfony/ai-weaviate-store": "^0.8", + "symfony/expression-language": "^7.3|^8.0", + "symfony/security-core": "^7.3|^8.0", + "symfony/translation": "^7.3|^8.0", + "symfony/validator": "^7.3|^8.0" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\AiBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Integration bundle for Symfony AI components", + "support": { + "source": "https://github.com/symfony/ai-bundle/tree/v0.8.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-20T21:23:24+00:00" + }, + { + "name": "symfony/ai-generic-platform", + "version": "v0.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-generic-platform.git", + "reference": "2e358c0e88c676fad0b61b3df715f9822d29a7e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-generic-platform/zipball/2e358c0e88c676fad0b61b3df715f9822d29a7e3", + "reference": "2e358c0e88c676fad0b61b3df715f9822d29a7e3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/ai-platform": "^0.8", + "symfony/http-client": "^7.3|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53" + }, + "type": "symfony-ai-platform", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Platform\\Bridge\\Generic\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic platform bridge for Symfony AI", + "keywords": [ + "Bridge", + "ai", + "generic", + "platform" + ], + "support": { + "source": "https://github.com/symfony/ai-generic-platform/tree/v0.8.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-20T21:23:24+00:00" + }, + { + "name": "symfony/ai-lm-studio-platform", + "version": "v0.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-lm-studio-platform.git", + "reference": "ad1c046dd9e7d6e474bc86554443e2d9400a7826" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-lm-studio-platform/zipball/ad1c046dd9e7d6e474bc86554443e2d9400a7826", + "reference": "ad1c046dd9e7d6e474bc86554443e2d9400a7826", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/ai-generic-platform": "^0.8", + "symfony/ai-platform": "^0.8", + "symfony/http-client": "^7.3|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53" + }, + "type": "symfony-ai-platform", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Platform\\Bridge\\LmStudio\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "LM Studio platform bridge for Symfony AI", + "keywords": [ + "Bridge", + "ai", + "lmstudio", + "local", + "platform" + ], + "support": { + "source": "https://github.com/symfony/ai-lm-studio-platform/tree/v0.8.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-20T21:23:24+00:00" + }, + { + "name": "symfony/ai-open-router-platform", + "version": "v0.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-open-router-platform.git", + "reference": "eb5ed3176b78bc489bf325c5d6bc4efc255804be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-open-router-platform/zipball/eb5ed3176b78bc489bf325c5d6bc4efc255804be", + "reference": "eb5ed3176b78bc489bf325c5d6bc4efc255804be", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/ai-generic-platform": "^0.8", + "symfony/ai-platform": "^0.8", + "symfony/http-client": "^7.3|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53" + }, + "type": "symfony-ai-platform", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Platform\\Bridge\\OpenRouter\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "OpenRouter platform bridge for Symfony AI", + "keywords": [ + "Bridge", + "OpenRouter", + "ai", + "platform" + ], + "support": { + "source": "https://github.com/symfony/ai-open-router-platform/tree/v0.8.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-20T21:23:24+00:00" + }, + { + "name": "symfony/ai-platform", + "version": "v0.8.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-platform.git", + "reference": "86ed9396f53cad02b5d1ca8092956ea74f65823f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-platform/zipball/86ed9396f53cad02b5d1ca8092956ea74f65823f", + "reference": "86ed9396f53cad02b5d1ca8092956ea74f65823f", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "oskarstark/enum-helper": "^1.5", + "php": ">=8.2", + "phpdocumentor/reflection-docblock": "^5.4|^6.0", + "phpstan/phpdoc-parser": "^2.1", + "psr/log": "^3.0", + "symfony/clock": "^7.3|^8.0", + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/property-access": "^7.3|^8.0", + "symfony/property-info": "^7.3|^8.0", + "symfony/serializer": "^7.3|^8.0", + "symfony/type-info": "^7.3|^8.0", + "symfony/uid": "^7.3|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53", + "symfony/cache": "^7.3|^8.0", + "symfony/console": "^7.3|^8.0", + "symfony/dotenv": "^7.3|^8.0", + "symfony/expression-language": "^7.3|^8.0", + "symfony/finder": "^7.3|^8.0", + "symfony/http-client": "^7.3|^8.0", + "symfony/http-client-contracts": "^3.5", + "symfony/intl": "^7.3|^8.0", + "symfony/process": "^7.3|^8.0", + "symfony/validator": "^7.3|^8.0", + "symfony/var-dumper": "^7.3|^8.0", + "symfony/yaml": "^7.3|^8.0" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Platform\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "PHP library for interacting with AI platform provider.", + "keywords": [ + "Gemini", + "OpenRouter", + "ai", + "aimlapi", + "albert", + "amazeeai", + "anthropic", + "azure", + "bedrock", + "cerebras", + "dockermodelrunner", + "elevenlabs", + "huggingface", + "inference", + "litellm", + "llama", + "lmstudio", + "meta", + "mistral", + "nova", + "ollama", + "openai", + "ovh", + "perplexity", + "replicate", + "speech", + "transformers", + "vertexai", + "voyage" + ], + "support": { + "source": "https://github.com/symfony/ai-platform/tree/v0.8.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-20T21:28:38+00:00" + }, { "name": "symfony/apache-pack", "version": "v1.0.1", @@ -19256,12 +19854,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "f41f65e527608a9a76cfbafd873756ed76c5452d" + "reference": "10b8a93511210c9bae3be31f4fe13c3ff974cad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/f41f65e527608a9a76cfbafd873756ed76c5452d", - "reference": "f41f65e527608a9a76cfbafd873756ed76c5452d", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/10b8a93511210c9bae3be31f4fe13c3ff974cad4", + "reference": "10b8a93511210c9bae3be31f4fe13c3ff974cad4", "shasum": "" }, "conflict": { @@ -19375,7 +19973,7 @@ "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "chriskacerguis/codeigniter-restserver": "<=2.7.1", "chrome-php/chrome": "<1.14", - "ci4-cms-erp/ci4ms": "<=0.31.3", + "ci4-cms-erp/ci4ms": "<0.31.5", "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", "ckeditor/ckeditor": "<4.25", "clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3", @@ -20304,7 +20902,7 @@ "type": "tidelift" } ], - "time": "2026-04-21T17:25:01+00:00" + "time": "2026-04-22T18:27:19+00:00" }, { "name": "sebastian/cli-parser", diff --git a/config/bundles.php b/config/bundles.php index ae7dc9cc..000c58a1 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -33,4 +33,5 @@ return [ Jbtronics\SettingsBundle\JbtronicsSettingsBundle::class => ['all' => true], Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true], ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], + Symfony\AI\AiBundle\AiBundle::class => ['all' => true], ]; diff --git a/config/packages/ai.yaml b/config/packages/ai.yaml new file mode 100644 index 00000000..89f8e7ae --- /dev/null +++ b/config/packages/ai.yaml @@ -0,0 +1,27 @@ +ai: + platform: + # Inference Platform configuration + # see https://github.com/symfony/ai/tree/main/src/platform#platform-bridges + + # openai: + # api_key: '%env(OPENAI_API_KEY)%' + + agent: + # Agent configuration + # see https://symfony.com/doc/current/ai/bundles/ai-bundle.html + + # default: + # platform: 'ai.platform.openai' + # model: 'gpt-5-mini' + # prompt: | + # You are a pirate and you write funny. + # tools: + # - 'Symfony\AI\Agent\Bridge\Clock\Clock' + + store: + # Store configuration + + # chromadb: + # default: + # client: 'client.service.id' + # collection: 'my_collection' diff --git a/config/packages/ai_generic_platform.yaml b/config/packages/ai_generic_platform.yaml new file mode 100644 index 00000000..c2c2e133 --- /dev/null +++ b/config/packages/ai_generic_platform.yaml @@ -0,0 +1,5 @@ +ai: + platform: + generic: + default: + base_url: '%env(GENERIC_BASE_URL)%' diff --git a/config/packages/ai_lm_studio_platform.yaml b/config/packages/ai_lm_studio_platform.yaml new file mode 100644 index 00000000..0e6e4ac0 --- /dev/null +++ b/config/packages/ai_lm_studio_platform.yaml @@ -0,0 +1,3 @@ +ai: + platform: + lmstudio: null diff --git a/config/packages/ai_open_router_platform.yaml b/config/packages/ai_open_router_platform.yaml new file mode 100644 index 00000000..bef68793 --- /dev/null +++ b/config/packages/ai_open_router_platform.yaml @@ -0,0 +1,4 @@ +ai: + platform: + openrouter: + api_key: '%env(OPENROUTER_API_KEY)%' diff --git a/config/reference.php b/config/reference.php index 77a5d432..71850e24 100644 --- a/config/reference.php +++ b/config/reference.php @@ -2674,6 +2674,465 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * ... * }, * } + * @psalm-type AiConfig = array{ + * platform?: array{ + * albert?: array{ + * api_key?: string|Param, + * base_url?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * amazeeai?: array{ + * base_url?: string|Param, + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * anthropic?: array{ + * api_key?: string|Param, + * version?: string|Param, // Default: null + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * cache_retention?: "none"|"short"|"long"|Param, // Prompt cache retention policy for Anthropic models // Default: "short" + * }, + * azure?: array, + * bedrock?: array, + * cache?: array, + * cartesia?: array{ + * api_key?: string|Param, + * version?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * cerebras?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * cohere?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * decart?: array{ + * api_key?: string|Param, + * host?: string|Param, // Default: "https://api.decart.ai/v1" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * deepseek?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * dockermodelrunner?: array{ + * host_url?: string|Param, // Default: "http://127.0.0.1:12434" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * elevenlabs?: array{ + * api_key?: string|Param, + * endpoint?: string|Param, // Default: "https://api.elevenlabs.io/v1/" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * failover?: array, + * rate_limiter?: string|Param, + * }>, + * gemini?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * generic?: array, + * huggingface?: array{ + * api_key?: string|Param, + * provider?: string|Param, // Default: "hf-inference" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * lmstudio?: array{ + * host_url?: string|Param, // Default: "http://127.0.0.1:1234" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * mistral?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * ollama?: array{ + * endpoint?: string|Param, // Endpoint for Ollama (e.g. "http://127.0.0.1:11434" for local, or a cloud endpoint). If null, the http_client is used as-is and must already be configured with a base URI. + * api_key?: string|Param, // API key for Ollama Cloud authentication (optional for local usage) + * http_client?: string|Param, // Service ID of the HTTP client to use. When "endpoint" is null, this client must be pre-configured (e.g. with a base_uri). // Default: "http_client" + * }, + * openai?: array{ + * api_key?: string|Param, + * region?: scalar|Param|null, // The region for OpenAI API (EU, US, or null for default) // Default: null + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * openrouter?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * ovh?: array{ + * api_key?: scalar|Param|null, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * perplexity?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * scaleway?: array{ + * api_key?: scalar|Param|null, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * transformersphp?: array, + * vertexai?: array{ + * location?: string|Param, // Required for the project-scoped endpoint. Must be set together with "project_id". // Default: null + * project_id?: string|Param, // Required for the project-scoped endpoint. Must be set together with "location". // Default: null + * api_key?: string|Param, // When set without "location" and "project_id", uses the global endpoint. Note: API keys only identify the project for billing and do not provide identity-based access control. For production use with IAM, audit logging, or data residency, prefer the project-scoped endpoint with service account authentication. // Default: null + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * voyage?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * }, + * model?: array|\Symfony\AI\Platform\Capability|Param>, + * }>>, + * agent?: array, + * }, + * keep_tool_messages?: bool|Param, // Keep tool messages in the conversation history // Default: false + * include_sources?: bool|Param, // Include sources exposed by tools as part of the tool result metadata // Default: false + * fault_tolerant_toolbox?: bool|Param, // Continue the agent run even if a tool call fails // Default: true + * speech?: bool|array{ // Speech (TTS/STT) decorator configuration + * enabled?: bool|Param, // Default: true + * text_to_speech_platform?: string|Param, // Service name of the TTS platform (e.g. ai.platform.elevenlabs). // Default: null + * speech_to_text_platform?: string|Param, // Service name of the STT platform (e.g. ai.platform.openai). // Default: null + * tts_model?: string|Param, // Text-to-speech model name // Default: null + * tts_options?: mixed, // Provider-specific TTS options // Default: [] + * stt_model?: string|Param, // Speech-to-text model name // Default: null + * stt_options?: mixed, // Provider-specific STT options // Default: [] + * }, + * }>, + * multi_agent?: array>, + * fallback?: string|Param, // Service ID of the fallback agent for unmatched requests + * }>, + * store?: array{ + * azuresearch?: array, + * cache?: array, + * chromadb?: array, + * clickhouse?: array, + * cloudflare?: array, + * elasticsearch?: array, + * manticoresearch?: array, + * mariadb?: array, + * meilisearch?: array, + * memory?: array, + * milvus?: array, + * mongodb?: array, + * neo4j?: array, + * opensearch?: array, + * pinecone?: array, + * top_k?: int|Param, + * }>, + * postgres?: array, + * qdrant?: array, + * redis?: array, + * s3vectors?: array, + * vector_bucket_name?: string|Param, + * index_name?: string|Param, + * filter?: array, + * top_k?: int|Param, // Default number of results to return // Default: 3 + * }>, + * sqlite?: array, + * supabase?: array, + * surrealdb?: array, + * typesense?: array, + * weaviate?: array, + * vektor?: array, + * }, + * message_store?: array{ + * cache?: array, + * cloudflare?: array, + * doctrine?: array{ + * dbal?: array, + * }, + * meilisearch?: array, + * memory?: array, + * mongodb?: array, + * pogocache?: array, + * redis?: array, + * session?: array, + * surrealdb?: array, + * }, + * chat?: array, + * vectorizer?: array, + * indexer?: array, + * filters?: list, + * vectorizer?: scalar|Param|null, // Service name of vectorizer // Default: "Symfony\\AI\\Store\\Document\\VectorizerInterface" + * store?: string|Param, // Service name of store // Default: "Symfony\\AI\\Store\\StoreInterface" + * }>, + * retriever?: array, + * } * @psalm-type ConfigType = array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -2703,6 +3162,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * nelmio_cors?: NelmioCorsConfig, * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, + * ai?: AiConfig, * "when@dev"?: array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -2736,6 +3196,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * jbtronics_settings?: JbtronicsSettingsConfig, * jbtronics_translation_editor?: JbtronicsTranslationEditorConfig, * api_platform?: ApiPlatformConfig, + * ai?: AiConfig, * }, * "when@docker"?: array{ * imports?: ImportsConfig, @@ -2766,6 +3227,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * nelmio_cors?: NelmioCorsConfig, * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, + * ai?: AiConfig, * }, * "when@prod"?: array{ * imports?: ImportsConfig, @@ -2796,6 +3258,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * nelmio_cors?: NelmioCorsConfig, * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, + * ai?: AiConfig, * }, * "when@test"?: array{ * imports?: ImportsConfig, @@ -2829,6 +3292,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * nelmio_cors?: NelmioCorsConfig, * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, + * ai?: AiConfig, * }, * ...httpClient = $httpClient->withOptions([ 'timeout' => 30, @@ -68,7 +76,8 @@ class AIInfoExtractor implements InfoProviderInterface public function isActive(): bool { - return !empty($this->settings->apiKey) && $this->settings->enabled; + return true; + //return !empty($this->settings->apiKey) && $this->settings->enabled; } public function searchByKeyword(string $keyword): array @@ -76,28 +85,28 @@ class AIInfoExtractor implements InfoProviderInterface // Treat the keyword as a URL and return a single search result $url = $this->normalizeURL($keyword); - try { - $part = $this->getDetails($url); - return [ - new SearchResultDTO( - provider_key: $this->getProviderKey(), - provider_id: $url, - name: $part->name, - description: $part->description, - category: $part->category, - manufacturer: $part->manufacturer, - mpn: $part->mpn, - preview_image_url: $part->preview_image_url, - manufacturing_status: $part->manufacturing_status, - provider_url: $part->provider_url, - footprint: $part->footprint, - gtin: $part->gtin, - ), - ]; - } catch (\Throwable $e) { - // Return empty array on error - return []; - } + //try { + $part = $this->getDetails($url); + return [ + new SearchResultDTO( + provider_key: $this->getProviderKey(), + provider_id: $url, + name: $part->name, + description: $part->description, + category: $part->category, + manufacturer: $part->manufacturer, + mpn: $part->mpn, + preview_image_url: $part->preview_image_url, + manufacturing_status: $part->manufacturing_status, + provider_url: $part->provider_url, + footprint: $part->footprint, + gtin: $part->gtin, + ), + ]; + //} catch (\Throwable $e) { + // // Return empty array on error + // return []; + //} } public function getDetails(string $id): PartDetailDTO @@ -194,6 +203,108 @@ class AIInfoExtractor implements InfoProviderInterface private function callOpenRouterAPI(string $htmlContent, string $url): string { + $input = new MessageBag( + Message::forSystem($this->buildSystemPrompt()), + Message::ofUser("Extract part information from this webpage content:\n\nURL: $url\n\n$htmlContent") + ); + + $models = $this->aiPlatform->getModelCatalog()->getModels(); + + try { + //'openai/gpt-5-mini' + $result = $this->aiPlatform->invoke('openrouter/auto', $input, [ + 'response_format' => 'json_schema', + 'json_schema' => [ + 'name' => 'clock', + 'strict' => true, + 'schema' => [ + 'type' => 'object', + 'properties' => [ + 'name' => ['type' => 'string', 'description' => 'Product name'], + 'description' => ['type' => 'string', 'description' => 'Product description'], + 'manufacturer' => ['type' => ['string', 'null'], 'description' => 'Manufacturer name'], + 'mpn' => ['type' => ['string', 'null'], 'description' => 'Manufacturer Part Number'], + 'category' => ['type' => ['string', 'null'], 'description' => 'Product category'], + 'manufacturing_status' => ['type' => ['string', 'null'], 'enum' => ['active', 'obsolete', 'nrfnd', 'discontinued', null], 'description' => 'Manufacturing status'], + 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type'], + 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass in grams'], + 'parameters' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'name' => ['type' => 'string'], + 'value' => ['type' => 'string'], + 'unit' => ['type' => ['string', 'null']], + ], + 'required' => ['name', 'value'], + ], + ], + 'datasheets' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'url' => ['type' => 'string'], + 'description' => ['type' => 'string'], + ], + 'required' => ['url'], + ], + ], + 'images' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'url' => ['type' => 'string'], + 'description' => ['type' => 'string'], + ], + 'required' => ['url'], + ], + ], + 'vendor_infos' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'distributor_name' => ['type' => 'string'], + 'order_number' => ['type' => ['string', 'null']], + 'product_url' => ['type' => 'string'], + 'prices' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'minimum_quantity' => ['type' => 'integer'], + 'price' => ['type' => 'number'], + 'currency' => ['type' => 'string'], + ], + 'required' => ['minimum_quantity', 'price', 'currency'], + ], + ], + ], + 'required' => ['distributor_name', 'product_url'], + ], + ], + 'manufacturer_product_url' => ['type' => ['string', 'null'], 'description' => 'Manufacturer product page URL'], + ], + 'required' => ['name', 'description'], + ], + ], + ]); + } catch (\Throwable $e) { + dump($e); + throw new \RuntimeException('LLM invocation failed: ' . $e->getMessage(), previous: $e); + } + + + + dump($result->getResult()->getContent()); + + return json_encode($result->getResult()->getContent()); + + /* + $systemPrompt = $this->buildSystemPrompt(); // Define the tool/function for structured output @@ -331,6 +442,8 @@ class AIInfoExtractor implements InfoProviderInterface $content = trim($content); return $content; + */ + } private function buildSystemPrompt(): string diff --git a/symfony.lock b/symfony.lock index 68de2da7..dde7df36 100644 --- a/symfony.lock +++ b/symfony.lock @@ -375,6 +375,54 @@ "shivas/versioning-bundle": { "version": "4.0.3" }, + "symfony/ai-bundle": { + "version": "0.8", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "0.1", + "ref": "2be6ccd77335c2631fdf12d1680649b072efb8ad" + }, + "files": [ + "config/packages/ai.yaml" + ] + }, + "symfony/ai-generic-platform": { + "version": "0.8", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "0.1", + "ref": "f38913b87380322d4c40c302b41626e811516bc4" + }, + "files": [ + "config/packages/ai_generic_platform.yaml" + ] + }, + "symfony/ai-lm-studio-platform": { + "version": "0.8", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "0.1", + "ref": "e35cced28f6559fc5effccb8f22597f309fedfdf" + }, + "files": [ + "config/packages/ai_lm_studio_platform.yaml" + ] + }, + "symfony/ai-open-router-platform": { + "version": "0.8", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "0.1", + "ref": "c39a146c6ec3df8b874accf6ce1cccbda431a688" + }, + "files": [ + "config/packages/ai_open_router_platform.yaml" + ] + }, "symfony/apache-pack": { "version": "1.0", "recipe": { From c0017d29a747dd66e2e8e56dd8d1ed2f68fe24ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 25 Apr 2026 22:21:06 +0200 Subject: [PATCH 03/36] Refactored and cleaned up AIInfoExtractor --- .../DTOJsonSchemaConverter.php | 239 ++++++++++ .../Providers/AIInfoExtractor.php | 428 +----------------- .../Providers/FixAndValidateUrlTrait.php | 58 +++ .../Providers/GenericWebProvider.php | 29 +- 4 files changed, 324 insertions(+), 430 deletions(-) create mode 100644 src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php create mode 100644 src/Services/InfoProviderSystem/Providers/FixAndValidateUrlTrait.php diff --git a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php new file mode 100644 index 00000000..b9208c87 --- /dev/null +++ b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php @@ -0,0 +1,239 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\InfoProviderSystem; + +use App\Entity\Parts\ManufacturingStatus; +use App\Services\InfoProviderSystem\DTOs\FileDTO; +use App\Services\InfoProviderSystem\DTOs\ParameterDTO; +use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; +use App\Services\InfoProviderSystem\DTOs\PriceDTO; +use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO; + +/** + * This class allows to convert the JSON data returned by an LLM into the DTOs used by the info provider system later. + */ +final class DTOJsonSchemaConverter +{ + /** + * Returns the JSON schema, that defines the expected structure of the JSON data returned by the LLM. + * @return array + */ + public function getJSONSchema(): array + { + return [ + 'name' => 'clock', + 'strict' => true, + 'schema' => [ + 'type' => 'object', + 'properties' => [ + 'name' => ['type' => 'string', 'description' => 'Product name'], + 'description' => ['type' => 'string', 'description' => 'Product description'], + 'manufacturer' => ['type' => ['string', 'null'], 'description' => 'Manufacturer name'], + 'mpn' => ['type' => ['string', 'null'], 'description' => 'Manufacturer Part Number'], + 'category' => ['type' => ['string', 'null'], 'description' => 'Product category'], + 'manufacturing_status' => ['type' => ['string', 'null'], 'enum' => ['active', 'obsolete', 'nrfnd', 'discontinued', null], 'description' => 'Manufacturing status'], + 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type'], + 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass in grams'], + 'parameters' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'name' => ['type' => 'string'], + 'value' => ['type' => 'string'], + 'unit' => ['type' => ['string', 'null']], + ], + 'required' => ['name', 'value'], + ], + ], + 'datasheets' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'url' => ['type' => 'string'], + 'description' => ['type' => 'string'], + ], + 'required' => ['url'], + ], + ], + 'images' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'url' => ['type' => 'string'], + 'description' => ['type' => 'string'], + ], + 'required' => ['url'], + ], + ], + 'vendor_infos' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'distributor_name' => ['type' => 'string'], + 'order_number' => ['type' => ['string', 'null']], + 'product_url' => ['type' => 'string'], + 'prices' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'object', + 'properties' => [ + 'minimum_quantity' => ['type' => 'integer'], + 'price' => ['type' => 'number'], + 'currency' => ['type' => 'string'], + ], + 'required' => ['minimum_quantity', 'price', 'currency'], + ], + ], + ], + 'required' => ['distributor_name', 'product_url'], + ], + ], + 'manufacturer_product_url' => ['type' => ['string', 'null'], 'description' => 'Manufacturer product page URL'], + ], + 'required' => ['name', 'description'], + ] + ]; + } + + public function jsonToDTO(array $data, string $providerKey, string $providerId, ?string $productUrl = null, string $distributorNameFallback = '???'): PartDetailDTO + { + // Map manufacturing status + $manufacturingStatus = null; + if (!empty($data['manufacturing_status'])) { + $status = strtolower((string) $data['manufacturing_status']); + $manufacturingStatus = match ($status) { + 'active' => ManufacturingStatus::ACTIVE, + 'obsolete', 'discontinued' => ManufacturingStatus::DISCONTINUED, + 'nrfnd', 'not recommended for new designs' => ManufacturingStatus::NRFND, + 'eol' => ManufacturingStatus::EOL, + 'announced' => ManufacturingStatus::ANNOUNCED, + default => null, + }; + } + + // Build parameters + $parameters = null; + if (!empty($data['parameters']) && is_array($data['parameters'])) { + $parameters = []; + foreach ($data['parameters'] as $p) { + if (!empty($p['name'])) { + $value = $p['value'] ?? ''; + $unit = $p['unit'] ?? null; + // Combine value and unit for parsing + $valueWithUnit = $unit ? $value . ' ' . $unit : $value; + $parameters[] = ParameterDTO::parseValueField( + name: $p['name'], + value: $valueWithUnit + ); + } + } + } + + // Build datasheets + $datasheets = null; + if (!empty($data['datasheets']) && is_array($data['datasheets'])) { + $datasheets = []; + foreach ($data['datasheets'] as $d) { + if (!empty($d['url'])) { + $datasheets[] = new FileDTO( + url: $d['url'], + name: $d['description'] ?? 'Datasheet' + ); + } + } + } + + // Build images + $images = null; + if (!empty($data['images']) && is_array($data['images'])) { + $images = []; + foreach ($data['images'] as $i) { + if (!empty($i['url'])) { + $images[] = new FileDTO( + url: $i['url'], + name: $i['description'] ?? 'Image' + ); + } + } + } + + // Build vendor infos + $vendorInfos = null; + if (!empty($data['vendor_infos']) && is_array($data['vendor_infos'])) { + $vendorInfos = []; + foreach ($data['vendor_infos'] as $v) { + $prices = []; + if (!empty($v['prices']) && is_array($v['prices'])) { + foreach ($v['prices'] as $p) { + $prices[] = new PriceDTO( + minimum_discount_amount: (int) ($p['minimum_quantity'] ?? 1), + price: (string) ($p['price'] ?? 0), + currency_iso_code: $p['currency'] ?? 'USD', + price_related_quantity: (int) ($p['minimum_quantity'] ?? 1), + ); + } + } + + $vendorInfos[] = new PurchaseInfoDTO( + distributor_name: $v['distributor_name'] ?? $distributorNameFallback, + order_number: $v['order_number'] ?? 'Unknown', + prices: $prices, + product_url: $v['product_url'] ?? $productUrl, + ); + } + } + + // Get preview image URL + $previewImageUrl = null; + if (!empty($data['images']) && is_array($data['images']) && !empty($data['images'][0]['url'])) { + $previewImageUrl = $data['images'][0]['url']; + } + + return new PartDetailDTO( + provider_key: $providerKey, + provider_id: $providerId, + name: $data['name'] ?? 'Unknown', + description: $data['description'] ?? '', + category: $data['category'] ?? null, + manufacturer: $data['manufacturer'] ?? null, + mpn: $data['mpn'] ?? null, + preview_image_url: $previewImageUrl, + manufacturing_status: $manufacturingStatus, + provider_url: $productUrl, + footprint: $data['footprint'] ?? null, + notes: null, + datasheets: $datasheets, + images: $images, + parameters: $parameters, + vendor_infos: $vendorInfos, + mass: isset($data['mass']) && is_numeric($data['mass']) ? (float) $data['mass'] : null, + manufacturer_product_url: $data['manufacturer_product_url'] ?? null, + ); + } + +} diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index c260f43e..0bf32159 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -24,32 +24,31 @@ declare(strict_types=1); namespace App\Services\InfoProviderSystem\Providers; -use App\Entity\Parts\ManufacturingStatus; -use App\Services\InfoProviderSystem\DTOs\FileDTO; -use App\Services\InfoProviderSystem\DTOs\ParameterDTO; +use App\Exceptions\ProviderIDNotSupportedException; +use App\Services\InfoProviderSystem\DTOJsonSchemaConverter; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; -use App\Services\InfoProviderSystem\DTOs\PriceDTO; -use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO; -use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; use App\Settings\InfoProviderSystem\AIExtractorSettings; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; -use Symfony\AI\Platform\Platform; use Symfony\AI\Platform\PlatformInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Contracts\HttpClient\HttpClientInterface; -class AIInfoExtractor implements InfoProviderInterface +final class AIInfoExtractor implements InfoProviderInterface { + use FixAndValidateUrlTrait; + private const DISTRIBUTOR_NAME = 'AI Extracted'; private readonly HttpClientInterface $httpClient; - public function __construct(HttpClientInterface $httpClient, private readonly AIExtractorSettings $settings, + public function __construct( + HttpClientInterface $httpClient, + private readonly AIExtractorSettings $settings, #[Autowire(service: "ai.traceable_platform.openrouter")] - private readonly PlatformInterface $aiPlatform - ) - { + private readonly PlatformInterface $aiPlatform, + private readonly DTOJsonSchemaConverter $jsonSchemaConverter, + ) { $this->httpClient = $httpClient->withOptions([ 'timeout' => 30, 'headers' => [ @@ -82,36 +81,17 @@ class AIInfoExtractor implements InfoProviderInterface public function searchByKeyword(string $keyword): array { - // Treat the keyword as a URL and return a single search result - $url = $this->normalizeURL($keyword); - - //try { - $part = $this->getDetails($url); - return [ - new SearchResultDTO( - provider_key: $this->getProviderKey(), - provider_id: $url, - name: $part->name, - description: $part->description, - category: $part->category, - manufacturer: $part->manufacturer, - mpn: $part->mpn, - preview_image_url: $part->preview_image_url, - manufacturing_status: $part->manufacturing_status, - provider_url: $part->provider_url, - footprint: $part->footprint, - gtin: $part->gtin, - ), - ]; - //} catch (\Throwable $e) { - // // Return empty array on error - // return []; - //} + try { + return [ + $this->getDetails($keyword) + ]; } catch (ProviderIDNotSupportedException $e) { + return []; + } } public function getDetails(string $id): PartDetailDTO { - $url = $this->normalizeURL($id); + $url = $this->fixAndValidateURL($id); // Fetch HTML content $response = $this->httpClient->request('GET', $url); @@ -123,14 +103,11 @@ class AIInfoExtractor implements InfoProviderInterface // Truncate to max content length $truncatedHtml = $this->truncateHTML($cleanedHtml, $this->settings->maxContentLength); - // Call OpenRouter API - $llmResponse = $this->callOpenRouterAPI($truncatedHtml, $url); - - // Parse JSON response - $data = json_decode($llmResponse, true, 512, JSON_THROW_ON_ERROR); + // Call LLM + $llmResponse = $this->callLLM($truncatedHtml, $url); // Build and return PartDetailDTO - return $this->buildPartDetailDTO($data, $url); + return $this->jsonSchemaConverter->jsonToDTO($llmResponse, $this->getProviderKey(), $url, $url, self::DISTRIBUTOR_NAME); } public function getCapabilities(): array @@ -144,21 +121,6 @@ class AIInfoExtractor implements InfoProviderInterface ]; } - private function normalizeURL(string $url): string - { - // Add https:// if no protocol - if (!preg_match('/^https?:\/\//', $url)) { - $url = 'https://' . ltrim($url, '/'); - } - - // Validate URL - if (filter_var($url, FILTER_VALIDATE_URL) === false) { - throw new \InvalidArgumentException("Invalid URL: $url"); - } - - return $url; - } - private function cleanHTML(string $html): string { // Remove script tags @@ -201,249 +163,24 @@ class AIInfoExtractor implements InfoProviderInterface return $truncated; } - private function callOpenRouterAPI(string $htmlContent, string $url): string + private function callLLM(string $htmlContent, string $url): array { $input = new MessageBag( Message::forSystem($this->buildSystemPrompt()), Message::ofUser("Extract part information from this webpage content:\n\nURL: $url\n\n$htmlContent") ); - $models = $this->aiPlatform->getModelCatalog()->getModels(); - try { //'openai/gpt-5-mini' $result = $this->aiPlatform->invoke('openrouter/auto', $input, [ 'response_format' => 'json_schema', - 'json_schema' => [ - 'name' => 'clock', - 'strict' => true, - 'schema' => [ - 'type' => 'object', - 'properties' => [ - 'name' => ['type' => 'string', 'description' => 'Product name'], - 'description' => ['type' => 'string', 'description' => 'Product description'], - 'manufacturer' => ['type' => ['string', 'null'], 'description' => 'Manufacturer name'], - 'mpn' => ['type' => ['string', 'null'], 'description' => 'Manufacturer Part Number'], - 'category' => ['type' => ['string', 'null'], 'description' => 'Product category'], - 'manufacturing_status' => ['type' => ['string', 'null'], 'enum' => ['active', 'obsolete', 'nrfnd', 'discontinued', null], 'description' => 'Manufacturing status'], - 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type'], - 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass in grams'], - 'parameters' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'name' => ['type' => 'string'], - 'value' => ['type' => 'string'], - 'unit' => ['type' => ['string', 'null']], - ], - 'required' => ['name', 'value'], - ], - ], - 'datasheets' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'url' => ['type' => 'string'], - 'description' => ['type' => 'string'], - ], - 'required' => ['url'], - ], - ], - 'images' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'url' => ['type' => 'string'], - 'description' => ['type' => 'string'], - ], - 'required' => ['url'], - ], - ], - 'vendor_infos' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'distributor_name' => ['type' => 'string'], - 'order_number' => ['type' => ['string', 'null']], - 'product_url' => ['type' => 'string'], - 'prices' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'minimum_quantity' => ['type' => 'integer'], - 'price' => ['type' => 'number'], - 'currency' => ['type' => 'string'], - ], - 'required' => ['minimum_quantity', 'price', 'currency'], - ], - ], - ], - 'required' => ['distributor_name', 'product_url'], - ], - ], - 'manufacturer_product_url' => ['type' => ['string', 'null'], 'description' => 'Manufacturer product page URL'], - ], - 'required' => ['name', 'description'], - ], - ], + 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), ]); } catch (\Throwable $e) { - dump($e); - throw new \RuntimeException('LLM invocation failed: ' . $e->getMessage(), previous: $e); + throw new \RuntimeException('LLM invocation failed: '.$e->getMessage(), previous: $e); } - - - dump($result->getResult()->getContent()); - - return json_encode($result->getResult()->getContent()); - - /* - - $systemPrompt = $this->buildSystemPrompt(); - - // Define the tool/function for structured output - $toolDefinition = [ - 'type' => 'function', - 'function' => [ - 'name' => 'extract_part_info', - 'description' => 'Extract electronic component information from a webpage', - 'parameters' => [ - 'type' => 'object', - 'properties' => [ - 'name' => ['type' => 'string', 'description' => 'Product name'], - 'description' => ['type' => 'string', 'description' => 'Product description'], - 'manufacturer' => ['type' => ['string', 'null'], 'description' => 'Manufacturer name'], - 'mpn' => ['type' => ['string', 'null'], 'description' => 'Manufacturer Part Number'], - 'category' => ['type' => ['string', 'null'], 'description' => 'Product category'], - 'manufacturing_status' => ['type' => ['string', 'null'], 'enum' => ['active', 'obsolete', 'nrfnd', 'discontinued', null], 'description' => 'Manufacturing status'], - 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type'], - 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass in grams'], - 'parameters' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'name' => ['type' => 'string'], - 'value' => ['type' => 'string'], - 'unit' => ['type' => ['string', 'null']], - ], - 'required' => ['name', 'value'], - ], - ], - 'datasheets' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'url' => ['type' => 'string'], - 'description' => ['type' => 'string'], - ], - 'required' => ['url'], - ], - ], - 'images' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'url' => ['type' => 'string'], - 'description' => ['type' => 'string'], - ], - 'required' => ['url'], - ], - ], - 'vendor_infos' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'distributor_name' => ['type' => 'string'], - 'order_number' => ['type' => ['string', 'null']], - 'product_url' => ['type' => 'string'], - 'prices' => [ - 'type' => 'array', - 'items' => [ - 'type' => 'object', - 'properties' => [ - 'minimum_quantity' => ['type' => 'integer'], - 'price' => ['type' => 'number'], - 'currency' => ['type' => 'string'], - ], - 'required' => ['minimum_quantity', 'price', 'currency'], - ], - ], - ], - 'required' => ['distributor_name', 'product_url'], - ], - ], - 'manufacturer_product_url' => ['type' => ['string', 'null'], 'description' => 'Manufacturer product page URL'], - ], - 'required' => ['name', 'description'], - ], - ], - ]; - - $payload = [ - 'model' => $this->settings->model, - 'messages' => [ - [ - 'role' => 'system', - 'content' => $systemPrompt, - ], - [ - 'role' => 'user', - 'content' => "Extract part information from this webpage content:\n\nURL: $url\n\n$htmlContent", - ], - ], - 'tools' => [$toolDefinition], - 'tool_choice' => ['type' => 'function', 'function' => ['name' => 'extract_part_info']], - 'max_tokens' => 4096, - 'temperature' => 0.1, - ]; - - $response = $this->httpClient->request('POST', 'https://openrouter.ai/api/v1/chat/completions', [ - 'headers' => [ - 'Authorization' => 'Bearer ' . $this->settings->apiKey, - 'Content-Type' => 'application/json', - 'HTTP-Referer' => 'https://github.com/Part-DB/Part-DB-server', - 'X-Title' => 'Part-DB AI Info Extractor', - ], - 'json' => $payload, - ]); - - $data = $response->toArray(); - - $message = $data['choices'][0]['message'] ?? null; - if ($message === null) { - throw new \RuntimeException('No response message from LLM'); - } - - // Check if the model used the tool/function call - if (isset($message['tool_calls']) && !empty($message['tool_calls'])) { - foreach ($message['tool_calls'] as $toolCall) { - if ($toolCall['function']['name'] === 'extract_part_info') { - return $toolCall['function']['arguments']; - } - } - } - - // Fallback to content if no tool call (some models might not support tool calling) - $content = $message['content'] ?? throw new \RuntimeException('No response content from LLM'); - - // Strip markdown code blocks if present (fallback for models without tool support) - $content = preg_replace('/^```(?:json)?\s*\n?/i', '', $content); - $content = preg_replace('/\n?```\s*$/i', '', $content); - $content = trim($content); - - return $content; - */ - + return $result->getResult()->getContent(); } private function buildSystemPrompt(): string @@ -485,119 +222,4 @@ For parameters, combine name, value, and unit. The unit should be separate if po PROMPT; } - private function buildPartDetailDTO(array $data, string $url): PartDetailDTO - { - // Map manufacturing status - $manufacturingStatus = null; - if (!empty($data['manufacturing_status'])) { - $status = strtolower((string) $data['manufacturing_status']); - $manufacturingStatus = match ($status) { - 'active' => ManufacturingStatus::ACTIVE, - 'obsolete', 'discontinued' => ManufacturingStatus::DISCONTINUED, - 'nrfnd', 'not recommended for new designs' => ManufacturingStatus::NRFND, - 'eol' => ManufacturingStatus::EOL, - 'announced' => ManufacturingStatus::ANNOUNCED, - default => null, - }; - } - - // Build parameters - $parameters = null; - if (!empty($data['parameters']) && is_array($data['parameters'])) { - $parameters = []; - foreach ($data['parameters'] as $p) { - if (!empty($p['name'])) { - $value = $p['value'] ?? ''; - $unit = $p['unit'] ?? null; - // Combine value and unit for parsing - $valueWithUnit = $unit ? $value . ' ' . $unit : $value; - $parameters[] = ParameterDTO::parseValueField( - name: $p['name'], - value: $valueWithUnit - ); - } - } - } - - // Build datasheets - $datasheets = null; - if (!empty($data['datasheets']) && is_array($data['datasheets'])) { - $datasheets = []; - foreach ($data['datasheets'] as $d) { - if (!empty($d['url'])) { - $datasheets[] = new FileDTO( - url: $d['url'], - name: $d['description'] ?? 'Datasheet' - ); - } - } - } - - // Build images - $images = null; - if (!empty($data['images']) && is_array($data['images'])) { - $images = []; - foreach ($data['images'] as $i) { - if (!empty($i['url'])) { - $images[] = new FileDTO( - url: $i['url'], - name: $i['description'] ?? 'Image' - ); - } - } - } - - // Build vendor infos - $vendorInfos = null; - if (!empty($data['vendor_infos']) && is_array($data['vendor_infos'])) { - $vendorInfos = []; - foreach ($data['vendor_infos'] as $v) { - $prices = []; - if (!empty($v['prices']) && is_array($v['prices'])) { - foreach ($v['prices'] as $p) { - $prices[] = new PriceDTO( - minimum_discount_amount: (int) ($p['minimum_quantity'] ?? 1), - price: (string) ($p['price'] ?? 0), - currency_iso_code: $p['currency'] ?? 'USD', - price_related_quantity: (int) ($p['minimum_quantity'] ?? 1), - ); - } - } - - $vendorInfos[] = new PurchaseInfoDTO( - distributor_name: $v['distributor_name'] ?? self::DISTRIBUTOR_NAME, - order_number: $v['order_number'] ?? 'Unknown', - prices: $prices, - product_url: $v['product_url'] ?? $url, - ); - } - } - - // Get preview image URL - $previewImageUrl = null; - if (!empty($data['images']) && is_array($data['images']) && !empty($data['images'][0]['url'])) { - $previewImageUrl = $data['images'][0]['url']; - } - - return new PartDetailDTO( - provider_key: $this->getProviderKey(), - provider_id: $url, - name: $data['name'] ?? 'Unknown', - description: $data['description'] ?? '', - category: $data['category'] ?? null, - manufacturer: $data['manufacturer'] ?? null, - mpn: $data['mpn'] ?? null, - preview_image_url: $previewImageUrl, - manufacturing_status: $manufacturingStatus, - provider_url: $url, - footprint: $data['footprint'] ?? null, - mass: isset($data['mass']) && is_numeric($data['mass']) ? (float) $data['mass'] : null, - notes: null, - datasheets: $datasheets, - images: $images, - parameters: $parameters, - vendor_infos: $vendorInfos, - manufacturer_product_url: $data['manufacturer_product_url'] ?? null, - ); - } } diff --git a/src/Services/InfoProviderSystem/Providers/FixAndValidateUrlTrait.php b/src/Services/InfoProviderSystem/Providers/FixAndValidateUrlTrait.php new file mode 100644 index 00000000..c9395a46 --- /dev/null +++ b/src/Services/InfoProviderSystem/Providers/FixAndValidateUrlTrait.php @@ -0,0 +1,58 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\InfoProviderSystem\Providers; + +use App\Exceptions\ProviderIDNotSupportedException; + +trait FixAndValidateUrlTrait +{ + private function fixAndValidateURL(string $url): string + { + $originalUrl = $url; + + //Add scheme if missing + if (!preg_match('/^https?:\/\//', $url)) { + //Remove any leading slashes + $url = ltrim($url, '/'); + + //If the URL starts with https:/ or http:/, add the missing slash + //Traefik removes the double slash as secruity measure, so we want to be forgiving and add it back if needed + //See https://github.com/Part-DB/Part-DB-server/issues/1296 + if (preg_match('/^https?:\/[^\/]/', $url)) { + $url = preg_replace('/^(https?:)\/([^\/])/', '$1//$2', $url); + } else { + $url = 'https://'.$url; + } + } + + //If this is not a valid URL with host, domain and path, throw an exception + if (filter_var($url, FILTER_VALIDATE_URL) === false || + parse_url($url, PHP_URL_HOST) === null || + parse_url($url, PHP_URL_PATH) === null) { + throw new ProviderIDNotSupportedException("The given ID is not a valid URL: ".$originalUrl); + } + + return $url; + } +} diff --git a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php index b5a150f8..90268c9c 100644 --- a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php +++ b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php @@ -48,6 +48,8 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; class GenericWebProvider implements InfoProviderInterface { + use FixAndValidateUrlTrait; + public const DISTRIBUTOR_NAME = 'Website'; private readonly HttpClientInterface $httpClient; @@ -308,34 +310,7 @@ class GenericWebProvider implements InfoProviderInterface return null; } - private function fixAndValidateURL(string $url): string - { - $originalUrl = $url; - //Add scheme if missing - if (!preg_match('/^https?:\/\//', $url)) { - //Remove any leading slashes - $url = ltrim($url, '/'); - - //If the URL starts with https:/ or http:/, add the missing slash - //Traefik removes the double slash as secruity measure, so we want to be forgiving and add it back if needed - //See https://github.com/Part-DB/Part-DB-server/issues/1296 - if (preg_match('/^https?:\/[^\/]/', $url)) { - $url = preg_replace('/^(https?:)\/([^\/])/', '$1//$2', $url); - } else { - $url = 'https://'.$url; - } - } - - //If this is not a valid URL with host, domain and path, throw an exception - if (filter_var($url, FILTER_VALIDATE_URL) === false || - parse_url($url, PHP_URL_HOST) === null || - parse_url($url, PHP_URL_PATH) === null) { - throw new ProviderIDNotSupportedException("The given ID is not a valid URL: ".$originalUrl); - } - - return $url; - } public function getDetails(string $id, bool $check_for_delegation = true): PartDetailDTO { From 2631ff4bee1ab5e780859e898303a57fec6672f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 25 Apr 2026 23:29:22 +0200 Subject: [PATCH 04/36] Introduced subsystem to configure AI providers and allow services to select them dynamiclly --- config/packages/ai_lm_studio_platform.yaml | 3 +- config/packages/ai_open_router_platform.yaml | 2 +- src/Services/AI/AIPlatformRegistry.php | 95 +++++++++++++++++++ .../AI/AIPlatformSettingsInterface.php | 33 +++++++ src/Services/AI/AIPlatforms.php | 57 +++++++++++ .../Providers/AIInfoExtractor.php | 9 +- src/Settings/AISettings/AISettings.php | 43 +++++++++ src/Settings/AISettings/LMStudioSettings.php | 51 ++++++++++ .../AISettings/OpenRouterSettings.php | 50 ++++++++++ src/Settings/AppSettings.php | 4 + 10 files changed, 342 insertions(+), 5 deletions(-) create mode 100644 src/Services/AI/AIPlatformRegistry.php create mode 100644 src/Services/AI/AIPlatformSettingsInterface.php create mode 100644 src/Services/AI/AIPlatforms.php create mode 100644 src/Settings/AISettings/AISettings.php create mode 100644 src/Settings/AISettings/LMStudioSettings.php create mode 100644 src/Settings/AISettings/OpenRouterSettings.php diff --git a/config/packages/ai_lm_studio_platform.yaml b/config/packages/ai_lm_studio_platform.yaml index 0e6e4ac0..0e4287e0 100644 --- a/config/packages/ai_lm_studio_platform.yaml +++ b/config/packages/ai_lm_studio_platform.yaml @@ -1,3 +1,4 @@ ai: platform: - lmstudio: null + lmstudio: + host_url: '%env(string:settings:ai_lmstudio:hostURL)%' diff --git a/config/packages/ai_open_router_platform.yaml b/config/packages/ai_open_router_platform.yaml index bef68793..d34de592 100644 --- a/config/packages/ai_open_router_platform.yaml +++ b/config/packages/ai_open_router_platform.yaml @@ -1,4 +1,4 @@ ai: platform: openrouter: - api_key: '%env(OPENROUTER_API_KEY)%' + api_key: '%env(string:settings:ai_openrouter:apiKey)%' diff --git a/src/Services/AI/AIPlatformRegistry.php b/src/Services/AI/AIPlatformRegistry.php new file mode 100644 index 00000000..bf1d355c --- /dev/null +++ b/src/Services/AI/AIPlatformRegistry.php @@ -0,0 +1,95 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\AI; + +use Jbtronics\SettingsBundle\Manager\SettingsManagerInterface; +use Symfony\AI\Platform\PlatformInterface; +use Symfony\Component\DependencyInjection\Attribute\AutowireIterator; + +final readonly class AIPlatformRegistry +{ + /** + * All registered platforms, indexed by their service tag name (e.g. "openrouter", "lmstudio") + * @var array $allPlatforms + */ + private array $allPlatforms; + + /** + * All registered platforms, indexed by their AIPlatforms enum value (e.g. AIPlatforms::OPENROUTER->value) + * @var array $enabledPlatforms + */ + private array $enabledPlatforms; + + public function __construct( + SettingsManagerInterface $settingsManager, + + #[AutowireIterator(tag: 'ai.platform', indexAttribute: 'name')] + iterable $platforms, + ) { + $this->allPlatforms = iterator_to_array($platforms); + + //Check which platforms are active based on the settings and store them in $activePlatforms + $tmp = []; + foreach (AIPlatforms::cases() as $platform) { + if (isset($this->allPlatforms[$platform->toServiceTagName()])) { + //Check if the platform is active by calling its isActive() on the settings class + $settings = $settingsManager->get($platform->toSettingsClass()); + if (!$settings->isAIPlatformEnabled()) { + continue; + } + + $tmp[$platform->value] = $this->allPlatforms[$platform->toServiceTagName()]; + } + } + $this->enabledPlatforms = $tmp; + } + + public function getPlatform(AIPlatforms $platform): PlatformInterface + { + if (!isset($this->enabledPlatforms[$platform->value])) { + throw new \InvalidArgumentException(sprintf('AI platform "%s" is not active or does not exist.', $platform->name)); + } + + return $this->enabledPlatforms[$platform->value]; + } + + /** + * Check if the given platform is active (i.e. it is registered and its settings are properly configured) + * @param AIPlatforms $platform + * @return bool + */ + public function isEnabled(AIPlatforms $platform): bool + { + return isset($this->enabledPlatforms[$platform->value]); + } + + /** + * Returns an array of all active platforms, indexed by their AIPlatforms enum value (e.g. AIPlatforms::OPENROUTER->value) + * @return PlatformInterface[] + */ + public function getEnabledPlatforms(): array + { + return $this->enabledPlatforms; + } +} diff --git a/src/Services/AI/AIPlatformSettingsInterface.php b/src/Services/AI/AIPlatformSettingsInterface.php new file mode 100644 index 00000000..c400db46 --- /dev/null +++ b/src/Services/AI/AIPlatformSettingsInterface.php @@ -0,0 +1,33 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\AI; + +interface AIPlatformSettingsInterface +{ + /** + * Returns true, if the AI platform is enabled in the settings and can be used, false otherwise. + * @return bool + */ + public function isAIPlatformEnabled(): bool; +} diff --git a/src/Services/AI/AIPlatforms.php b/src/Services/AI/AIPlatforms.php new file mode 100644 index 00000000..9a1480e4 --- /dev/null +++ b/src/Services/AI/AIPlatforms.php @@ -0,0 +1,57 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\AI; + +use App\Settings\AISettings\LMStudioSettings; +use App\Settings\AISettings\OpenRouterSettings; + +enum AIPlatforms: string +{ + case OPENROUTER = 'openrouter'; + case LMSTUDIO = 'lmstudio'; + + /** + * Returns the name attribute of the service tag for this platform, which is used to register the platform in the AIPlatformRegistry + * @return string + */ + public function toServiceTagName(): string + { + return $this->value; + } + + /** + * Returns the class name of the settings class for this platform, which implements AIPlatformSettingsInterface + * @return string + * @phpstan-return class-string + */ + public function toSettingsClass(): string + { + return match ($this) { + self::LMSTUDIO => LMStudioSettings::class, + self::OPENROUTER => OpenRouterSettings::class, + + default => throw new \InvalidArgumentException(sprintf('No settings class defined for AI platform "%s".', $this->name)), + }; + } +} diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 0bf32159..7472c87f 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -25,6 +25,8 @@ declare(strict_types=1); namespace App\Services\InfoProviderSystem\Providers; use App\Exceptions\ProviderIDNotSupportedException; +use App\Services\AI\AIPlatformRegistry; +use App\Services\AI\AIPlatforms; use App\Services\InfoProviderSystem\DTOJsonSchemaConverter; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Settings\InfoProviderSystem\AIExtractorSettings; @@ -45,8 +47,7 @@ final class AIInfoExtractor implements InfoProviderInterface public function __construct( HttpClientInterface $httpClient, private readonly AIExtractorSettings $settings, - #[Autowire(service: "ai.traceable_platform.openrouter")] - private readonly PlatformInterface $aiPlatform, + private readonly AIPlatformRegistry $AIPlatformRegistry, private readonly DTOJsonSchemaConverter $jsonSchemaConverter, ) { $this->httpClient = $httpClient->withOptions([ @@ -171,8 +172,10 @@ final class AIInfoExtractor implements InfoProviderInterface ); try { + $aiPlatform = $this->AIPlatformRegistry->getPlatform(AIPlatforms::OPENROUTER); + //'openai/gpt-5-mini' - $result = $this->aiPlatform->invoke('openrouter/auto', $input, [ + $result = $aiPlatform->invoke('openrouter/auto', $input, [ 'response_format' => 'json_schema', 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), ]); diff --git a/src/Settings/AISettings/AISettings.php b/src/Settings/AISettings/AISettings.php new file mode 100644 index 00000000..0e99d6fc --- /dev/null +++ b/src/Settings/AISettings/AISettings.php @@ -0,0 +1,43 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Settings\AISettings; + +use App\Settings\SettingsIcon; +use Jbtronics\SettingsBundle\Settings\EmbeddedSettings; +use Jbtronics\SettingsBundle\Settings\Settings; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\Component\Translation\TranslatableMessage as TM; + +#[Settings(label: new TM("settings.ai"), description: "settings.ai.help")] +#[SettingsIcon("fa-brain")] +class AISettings +{ + use SettingsTrait; + + #[EmbeddedSettings] + public ?OpenRouterSettings $openRouter = null; + + #[EmbeddedSettings] + public ?LMStudioSettings $lmstudio = null; +} diff --git a/src/Settings/AISettings/LMStudioSettings.php b/src/Settings/AISettings/LMStudioSettings.php new file mode 100644 index 00000000..ea6b9681 --- /dev/null +++ b/src/Settings/AISettings/LMStudioSettings.php @@ -0,0 +1,51 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Settings\AISettings; + +use App\Form\Type\APIKeyType; +use App\Services\AI\AIPlatformSettingsInterface; +use App\Settings\SettingsIcon; +use Jbtronics\SettingsBundle\Metadata\EnvVarMode; +use Jbtronics\SettingsBundle\Settings\Settings; +use Jbtronics\SettingsBundle\Settings\SettingsParameter; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\Component\Form\Extension\Core\Type\UrlType; +use Symfony\Component\Translation\TranslatableMessage as TM; + +#[Settings(name: 'ai_lmstudio', label: new TM("settings.ai.openrouter"), description: "settings.ai.lmstudio.help")] +#[SettingsIcon("fa-brain")] +class LMStudioSettings implements AIPlatformSettingsInterface +{ + use SettingsTrait; + + #[SettingsParameter(label: new TM("settings.ai.lmstudio.hosturl"), + formType: UrlType::class, + envVar: "AI_LMSTUDIO_HOSTURL", envVarMode: EnvVarMode::OVERWRITE)] + public ?string $hostURL = null; + + public function isAIPlatformEnabled(): bool + { + return $this->hostURL !== null && $this->hostURL !== ""; + } +} diff --git a/src/Settings/AISettings/OpenRouterSettings.php b/src/Settings/AISettings/OpenRouterSettings.php new file mode 100644 index 00000000..7b96c1d9 --- /dev/null +++ b/src/Settings/AISettings/OpenRouterSettings.php @@ -0,0 +1,50 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Settings\AISettings; + +use App\Form\Type\APIKeyType; +use App\Services\AI\AIPlatformSettingsInterface; +use App\Settings\SettingsIcon; +use Jbtronics\SettingsBundle\Metadata\EnvVarMode; +use Jbtronics\SettingsBundle\Settings\Settings; +use Jbtronics\SettingsBundle\Settings\SettingsParameter; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\Component\Translation\TranslatableMessage as TM; + +#[Settings(name: 'ai_openrouter', label: new TM("settings.ai.openrouter"), description: "settings.ai.openrouter.help")] +#[SettingsIcon("fa-brain")] +class OpenRouterSettings implements AIPlatformSettingsInterface +{ + use SettingsTrait; + + #[SettingsParameter(label: new TM("settings.ips.element14.apiKey"), + formType: APIKeyType::class, + formOptions: ["help_html" => true], envVar: "AI_OPENROUTER_KEY", envVarMode: EnvVarMode::OVERWRITE)] + public ?string $apiKey = null; + + public function isAIPlatformEnabled(): bool + { + return $this->apiKey !== null && $this->apiKey !== ""; + } +} diff --git a/src/Settings/AppSettings.php b/src/Settings/AppSettings.php index 14d9395e..085f7ffe 100644 --- a/src/Settings/AppSettings.php +++ b/src/Settings/AppSettings.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\Settings; +use App\Settings\AISettings\AISettings; use App\Settings\BehaviorSettings\BehaviorSettings; use App\Settings\InfoProviderSystem\InfoProviderSettings; use App\Settings\MiscSettings\MiscSettings; @@ -50,6 +51,9 @@ class AppSettings #[EmbeddedSettings] public ?SynonymSettings $synonyms = null; + #[EmbeddedSettings] + public ?AISettings $ai = null; + #[EmbeddedSettings()] public ?MiscSettings $miscSettings = null; From c9d20449495ed977d841fb8f95ad7eda56152ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 00:40:17 +0200 Subject: [PATCH 05/36] Fixed structured output response format --- .../InfoProviderSystem/Providers/AIInfoExtractor.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 7472c87f..973987de 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -176,8 +176,10 @@ final class AIInfoExtractor implements InfoProviderInterface //'openai/gpt-5-mini' $result = $aiPlatform->invoke('openrouter/auto', $input, [ - 'response_format' => 'json_schema', - 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), + 'response_format' => [ + 'type' => 'json_schema', + 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), + ] ]); } catch (\Throwable $e) { throw new \RuntimeException('LLM invocation failed: '.$e->getMessage(), previous: $e); From 18bf07b19f18ba059931330cfdb346bafb13c741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 01:10:00 +0200 Subject: [PATCH 06/36] Added an AI platform selector for settings --- src/Form/Settings/AiPlatformChoiceType.php | 54 +++++++++++++++++++ src/Services/AI/AIPlatforms.php | 11 +++- .../Providers/AIInfoExtractor.php | 10 ++-- .../AIExtractorSettings.php | 7 ++- 4 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 src/Form/Settings/AiPlatformChoiceType.php diff --git a/src/Form/Settings/AiPlatformChoiceType.php b/src/Form/Settings/AiPlatformChoiceType.php new file mode 100644 index 00000000..b28f217d --- /dev/null +++ b/src/Form/Settings/AiPlatformChoiceType.php @@ -0,0 +1,54 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Form\Settings; + +use App\Services\AI\AIPlatformRegistry; +use App\Services\AI\AIPlatforms; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\EnumType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +final class AiPlatformChoiceType extends AbstractType +{ + public function __construct(private readonly AIPlatformRegistry $platformRegistry) + { + } + + public function getParent(): ?string + { + return EnumType::class; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $choices = array_map(static fn(string $val) => AIPlatforms::from($val), array_keys($this->platformRegistry->getEnabledPlatforms())); + + $resolver->setDefaults([ + 'class' => AIPlatforms::class, + 'choices' => $choices, + 'required' => false, + ]); + } +} diff --git a/src/Services/AI/AIPlatforms.php b/src/Services/AI/AIPlatforms.php index 9a1480e4..ec772cf3 100644 --- a/src/Services/AI/AIPlatforms.php +++ b/src/Services/AI/AIPlatforms.php @@ -25,8 +25,10 @@ namespace App\Services\AI; use App\Settings\AISettings\LMStudioSettings; use App\Settings\AISettings\OpenRouterSettings; +use Symfony\Contracts\Translation\TranslatableInterface; +use Symfony\Contracts\Translation\TranslatorInterface; -enum AIPlatforms: string +enum AIPlatforms: string implements TranslatableInterface { case OPENROUTER = 'openrouter'; case LMSTUDIO = 'lmstudio'; @@ -54,4 +56,11 @@ enum AIPlatforms: string default => throw new \InvalidArgumentException(sprintf('No settings class defined for AI platform "%s".', $this->name)), }; } + + public function trans(TranslatorInterface $translator, ?string $locale = null): string + { + $key = 'settings.ai.' . $this->value; + + return $translator->trans($key, locale: $locale); + } } diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 973987de..d5be0267 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -26,14 +26,11 @@ namespace App\Services\InfoProviderSystem\Providers; use App\Exceptions\ProviderIDNotSupportedException; use App\Services\AI\AIPlatformRegistry; -use App\Services\AI\AIPlatforms; use App\Services\InfoProviderSystem\DTOJsonSchemaConverter; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Settings\InfoProviderSystem\AIExtractorSettings; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; -use Symfony\AI\Platform\PlatformInterface; -use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Contracts\HttpClient\HttpClientInterface; final class AIInfoExtractor implements InfoProviderInterface @@ -76,8 +73,7 @@ final class AIInfoExtractor implements InfoProviderInterface public function isActive(): bool { - return true; - //return !empty($this->settings->apiKey) && $this->settings->enabled; + return $this->settings->platform !== null && $this->settings->model !== ''; } public function searchByKeyword(string $keyword): array @@ -172,10 +168,10 @@ final class AIInfoExtractor implements InfoProviderInterface ); try { - $aiPlatform = $this->AIPlatformRegistry->getPlatform(AIPlatforms::OPENROUTER); + $aiPlatform = $this->AIPlatformRegistry->getPlatform($this->settings->platform ?? throw new \RuntimeException('No AI platform selected') ); //'openai/gpt-5-mini' - $result = $aiPlatform->invoke('openrouter/auto', $input, [ + $result = $aiPlatform->invoke($this->settings->model, $input, [ 'response_format' => [ 'type' => 'json_schema', 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), diff --git a/src/Settings/InfoProviderSystem/AIExtractorSettings.php b/src/Settings/InfoProviderSystem/AIExtractorSettings.php index c78ca96e..69b02637 100644 --- a/src/Settings/InfoProviderSystem/AIExtractorSettings.php +++ b/src/Settings/InfoProviderSystem/AIExtractorSettings.php @@ -23,6 +23,8 @@ declare(strict_types=1); namespace App\Settings\InfoProviderSystem; +use App\Form\Settings\AiPlatformChoiceType; +use App\Services\AI\AIPlatforms; use App\Settings\SettingsIcon; use Jbtronics\SettingsBundle\Metadata\EnvVarMode; use Jbtronics\SettingsBundle\Settings\Settings; @@ -36,10 +38,11 @@ class AIExtractorSettings { use SettingsTrait; - #[SettingsParameter(label: new TM("settings.ips.ai_extractor.api_key"), description: new TM("settings.ips.ai_extractor.api_key.description"), + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.ai_platform"), description: new TM("settings.ips.ai_extractor.ai_platform.help"), + formType: AiPlatformChoiceType::class, envVar: "string:PROVIDER_AI_EXTRACTOR_API_KEY", envVarMode: EnvVarMode::OVERWRITE )] - public ?string $apiKey = null; + public ?AIPlatforms $platform = null; #[SettingsParameter(label: new TM("settings.ips.ai_extractor.model"), description: new TM("settings.ips.ai_extractor.model.description"), envVar: "string:PROVIDER_AI_EXTRACTOR_MODEL", envVarMode: EnvVarMode::OVERWRITE From 25ced0d660a9871c3803271900f88e1c58f20d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 01:19:25 +0200 Subject: [PATCH 07/36] Added workaround to make lmstudio accept all models --- src/Services/AI/AcceptAllModelsCatalog.php | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/Services/AI/AcceptAllModelsCatalog.php diff --git a/src/Services/AI/AcceptAllModelsCatalog.php b/src/Services/AI/AcceptAllModelsCatalog.php new file mode 100644 index 00000000..b3b68135 --- /dev/null +++ b/src/Services/AI/AcceptAllModelsCatalog.php @@ -0,0 +1,59 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\AI; + +use Symfony\AI\Platform\Exception\ModelNotFoundException; +use Symfony\AI\Platform\Model; +use Symfony\AI\Platform\ModelCatalog\ModelCatalogInterface; +use Symfony\Component\DependencyInjection\Attribute\AsDecorator; + +/** + * This is a wrapper, to allow accepting all models, even if they are not contained in the decorated ModelCatalogInterface. + * This is a workaround for outdated/incomplete model catalogs provided by AI platforms, which do not contain all available models, or do not update their catalogs frequently enough. + */ +#[AsDecorator('ai.platform.model_catalog.lmstudio')] +final readonly class AcceptAllModelsCatalog implements ModelCatalogInterface +{ + + public function __construct(private ModelCatalogInterface $decorated) + { + } + + public function getModel(string $modelName): Model + { + //Use the actual values when its available. + try { + return $this->decorated->getModel($modelName); + } catch (ModelNotFoundException $e) { + //If the model is not found, return a generic model with the given name and no capabilities. + return new Model($modelName, []); + } + } + + public function getModels(): array + { + //Return the actual models catalog here for correct autocompletition + return $this->decorated->getModels(); + } +} From 67cb6fb8a21f513f6b319311d9fb84d4311a0ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 01:27:25 +0200 Subject: [PATCH 08/36] AcceptAllModels return CompletitionsModels as fallback --- src/Services/AI/AcceptAllModelsCatalog.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Services/AI/AcceptAllModelsCatalog.php b/src/Services/AI/AcceptAllModelsCatalog.php index b3b68135..bf590128 100644 --- a/src/Services/AI/AcceptAllModelsCatalog.php +++ b/src/Services/AI/AcceptAllModelsCatalog.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\Services\AI; +use Symfony\AI\Platform\Bridge\Generic\CompletionsModel; use Symfony\AI\Platform\Exception\ModelNotFoundException; use Symfony\AI\Platform\Model; use Symfony\AI\Platform\ModelCatalog\ModelCatalogInterface; @@ -47,7 +48,7 @@ final readonly class AcceptAllModelsCatalog implements ModelCatalogInterface return $this->decorated->getModel($modelName); } catch (ModelNotFoundException $e) { //If the model is not found, return a generic model with the given name and no capabilities. - return new Model($modelName, []); + return new CompletionsModel($modelName, []); } } From 9d389309fc0cc880e4aeded9bb95a73661770e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 15:19:52 +0200 Subject: [PATCH 09/36] Added an custom form type for model selection with autocompletition --- .../ai_model_autocomplete_controller.js | 152 ++++++++++++++++++ src/Controller/TypeaheadController.php | 22 +++ src/Form/Settings/AiModelsType.php | 62 +++++++ src/Form/Settings/AiPlatformChoiceType.php | 11 ++ .../AIExtractorSettings.php | 6 +- 5 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 assets/controllers/elements/ai_model_autocomplete_controller.js create mode 100644 src/Form/Settings/AiModelsType.php diff --git a/assets/controllers/elements/ai_model_autocomplete_controller.js b/assets/controllers/elements/ai_model_autocomplete_controller.js new file mode 100644 index 00000000..e36e6b1f --- /dev/null +++ b/assets/controllers/elements/ai_model_autocomplete_controller.js @@ -0,0 +1,152 @@ +/* + * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony). + * + * Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import {Controller} from "@hotwired/stimulus"; + +import "tom-select/dist/css/tom-select.bootstrap5.css"; +import '../../css/components/tom-select_extensions.css'; +import TomSelect from "tom-select"; + +import TomSelect_click_to_edit from '../../tomselect/click_to_edit/click_to_edit' +import TomSelect_autoselect_typed from '../../tomselect/autoselect_typed/autoselect_typed' + +TomSelect.define('click_to_edit', TomSelect_click_to_edit) +TomSelect.define('autoselect_typed', TomSelect_autoselect_typed) + +export default class extends Controller { + _tomSelect; + + _platformSelector; + + connect() { + + let dropdownParent = "body"; + if (this.element.closest('.modal')) { + dropdownParent = null + } + + //Try to find the platform selector + const platformSelector = document.querySelector("select[data-platform-selector-label='" + this.element.dataset.platformSelector + "']"); + //Clear tomselect options, if the platform selector changes + if (platformSelector) { + this.platformSelector = platformSelector; + platformSelector.addEventListener('change', () => { + //Force reload of options by clearing the cache and options of TomSelect and triggering a search with an empty string + this._tomSelect.clearOptions(); + this._tomSelect.clearCache(); + this._tomSelect.load(''); + }); + } + + let settings = { + persistent: false, + create: true, + maxItems: 1, + preload: 'focus', + createOnBlur: true, + selectOnTab: true, + clearAfterSelect: true, + shouldLoad: ((query) => true), + maxOptions: null, + //This a an ugly solution to disable the delimiter parsing of the TomSelect plugin + delimiter: 'VERY_L0NG_D€LIMITER_WHICH_WILL_NEVER_BE_ENCOUNTERED_IN_A_STRING', + dropdownParent: dropdownParent, + render: { + item: (data, escape) => { + return '' + escape(data.label) + ''; + }, + option: (data, escape) => { + if (data.image) { + return "
" + data.label + "
" + } + return '
' + escape(data.label) + '
'; + } + }, + plugins: { + 'autoselect_typed': {}, + 'click_to_edit': {}, + 'clear_button': {}, + "restore_on_backspace": {} + } + }; + + if(this.element.dataset.urlTemplate) { + const base_url = this.element.dataset.urlTemplate; + settings.searchField = "label"; + settings.sortField = "label"; + settings.valueField = "label"; + settings.load = (query, callback) => { + + + if (!this.platformSelector) { + console.error("Platform selector not found for AI model autocomplete"); + callback(); + return; + } + + //Platform is the selected option + const platform = this.platformSelector.value; + if (!platform) { + callback(); + return; + } + + const self = this; + + //Only fetch each platform once + if(self.platformLoaded === platform) { + callback(); + } + + + const url = base_url.replace('__PLATFORM__', encodeURIComponent(platform)); + + fetch(url) + .then(response => response.json()) + .then(json => { + + self.platformLoaded = platform; + + var data = []; + + for (const name in json) { + data.push({ + "label": name, + "capabilities": json[name].capabilities, + }); + } + + callback(data); + }).catch(()=>{ + callback(); + }); + }; + } + this._tomSelect = new TomSelect(this.element, settings); + } + + disconnect() { + super.disconnect(); + //Destroy the TomSelect instance + this._tomSelect.destroy(); + } + +} + + diff --git a/src/Controller/TypeaheadController.php b/src/Controller/TypeaheadController.php index 95480329..cca7df98 100644 --- a/src/Controller/TypeaheadController.php +++ b/src/Controller/TypeaheadController.php @@ -23,7 +23,10 @@ declare(strict_types=1); namespace App\Controller; use App\Entity\Parameters\AbstractParameter; +use App\Services\AI\AIPlatformRegistry; +use App\Services\AI\AIPlatforms; use App\Settings\MiscSettings\IpnSuggestSettings; +use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\HttpFoundation\Response; use App\Entity\Attachments\Attachment; use App\Entity\Parts\Category; @@ -54,6 +57,8 @@ use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; +use Symfony\Contracts\Cache\CacheInterface; +use Symfony\Contracts\Cache\ItemInterface; /** * In this controller the endpoints for the typeaheads are collected. @@ -223,4 +228,21 @@ class TypeaheadController extends AbstractController return new JsonResponse($ipnSuggestions); } + + #[Route(path: '/ai/{platform}/models', name: 'typeahead_ai_models', requirements: ['platform' => '.+'])] + public function aiModels( + AIPlatforms $platform, + AIPlatformRegistry $platformRegistry, + CacheInterface $cache, + ): JsonResponse { + + $this->denyAccessUnlessGranted('@config.change_system_settings'); + + $models = $cache->get('ai_models_'.$platform->value, function(ItemInterface $item) use ($platformRegistry, $platform) { + $item->expiresAfter(3600); //Cache for 1 hour + return $platformRegistry->getPlatform($platform)->getModelCatalog()->getModels(); + }); + + return new JsonResponse($models); + } } diff --git a/src/Form/Settings/AiModelsType.php b/src/Form/Settings/AiModelsType.php new file mode 100644 index 00000000..78b088ed --- /dev/null +++ b/src/Form/Settings/AiModelsType.php @@ -0,0 +1,62 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Form\Settings; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +/** + * An text input with autocomplete for AI models from the given platform. + * The platform is determined by the value of another form field, which is specified by the "platform_selector" option. This allows to filter the available models based on the selected platform. + */ +final class AiModelsType extends AbstractType +{ + public function __construct(private readonly UrlGeneratorInterface $urlGenerator) + { + } + + public function getParent(): string + { + return TextType::class; + } + + public function configureOptions(OptionsResolver $resolver): void + { + //The target label of the platform select, which is used to filter the models for the selected platform. + $resolver->setRequired('platform_selector'); + $resolver->setAllowedTypes('platform_selector', 'string'); + } + + public function finishView(FormView $view, FormInterface $form, array $options): void + { + $view->vars['attr']['data-url-template'] = $this->urlGenerator->generate('typeahead_ai_models', ['platform' => '__PLATFORM__']); + $view->vars['attr']['data-controller'] = 'elements--ai-model-autocomplete'; + + $view->vars['attr']['data-platform-selector'] = $options['platform_selector']; + } +} diff --git a/src/Form/Settings/AiPlatformChoiceType.php b/src/Form/Settings/AiPlatformChoiceType.php index b28f217d..eb48d933 100644 --- a/src/Form/Settings/AiPlatformChoiceType.php +++ b/src/Form/Settings/AiPlatformChoiceType.php @@ -28,8 +28,13 @@ use App\Services\AI\AIPlatforms; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\EnumType; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * Allow to choose an AI platform from the enabled platforms in the system. This is used in the settings to choose the default platform for AI features. + */ final class AiPlatformChoiceType extends AbstractType { public function __construct(private readonly AIPlatformRegistry $platformRegistry) @@ -49,6 +54,12 @@ final class AiPlatformChoiceType extends AbstractType 'class' => AIPlatforms::class, 'choices' => $choices, 'required' => false, + 'platform_selector_label' => null ]); } + + public function finishView(FormView $view, FormInterface $form, array $options): void + { + $view->vars['attr']['data-platform-selector-label'] = $options['platform_selector_label'] ?? $view->vars['id'].'_label'; + } } diff --git a/src/Settings/InfoProviderSystem/AIExtractorSettings.php b/src/Settings/InfoProviderSystem/AIExtractorSettings.php index 69b02637..0852d2ec 100644 --- a/src/Settings/InfoProviderSystem/AIExtractorSettings.php +++ b/src/Settings/InfoProviderSystem/AIExtractorSettings.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\Settings\InfoProviderSystem; +use App\Form\Settings\AiModelsType; use App\Form\Settings\AiPlatformChoiceType; use App\Services\AI\AIPlatforms; use App\Settings\SettingsIcon; @@ -36,15 +37,18 @@ use Symfony\Component\Translation\TranslatableMessage as TM; #[SettingsIcon("fa-robot")] class AIExtractorSettings { + private const MODEL_SELECTOR_LABEL = 'ai_extractor'; + use SettingsTrait; #[SettingsParameter(label: new TM("settings.ips.ai_extractor.ai_platform"), description: new TM("settings.ips.ai_extractor.ai_platform.help"), - formType: AiPlatformChoiceType::class, + formType: AiPlatformChoiceType::class, formOptions: ['platform_selector_label' => self::MODEL_SELECTOR_LABEL], envVar: "string:PROVIDER_AI_EXTRACTOR_API_KEY", envVarMode: EnvVarMode::OVERWRITE )] public ?AIPlatforms $platform = null; #[SettingsParameter(label: new TM("settings.ips.ai_extractor.model"), description: new TM("settings.ips.ai_extractor.model.description"), + formType: AiModelsType::class, formOptions: ['platform_selector' => self::MODEL_SELECTOR_LABEL], envVar: "string:PROVIDER_AI_EXTRACTOR_MODEL", envVarMode: EnvVarMode::OVERWRITE )] public string $model = 'z-ai/glm-4.7'; From 368dd14785975b339a7afd346142e681f4829c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 15:39:52 +0200 Subject: [PATCH 10/36] Allow to add selectors to ai model selects and only show models supporting structured output for AI extractor --- src/Controller/TypeaheadController.php | 54 ++++++++++++------- src/Form/Settings/AiModelsType.php | 12 ++++- .../AIExtractorSettings.php | 3 +- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/Controller/TypeaheadController.php b/src/Controller/TypeaheadController.php index cca7df98..c4cd5607 100644 --- a/src/Controller/TypeaheadController.php +++ b/src/Controller/TypeaheadController.php @@ -22,37 +22,37 @@ declare(strict_types=1); namespace App\Controller; -use App\Entity\Parameters\AbstractParameter; -use App\Services\AI\AIPlatformRegistry; -use App\Services\AI\AIPlatforms; -use App\Settings\MiscSettings\IpnSuggestSettings; -use Symfony\Component\Cache\Adapter\AdapterInterface; -use Symfony\Component\HttpFoundation\Response; use App\Entity\Attachments\Attachment; -use App\Entity\Parts\Category; -use App\Entity\Parts\Footprint; +use App\Entity\Parameters\AbstractParameter; use App\Entity\Parameters\AttachmentTypeParameter; use App\Entity\Parameters\CategoryParameter; -use App\Entity\Parameters\ProjectParameter; use App\Entity\Parameters\FootprintParameter; use App\Entity\Parameters\GroupParameter; use App\Entity\Parameters\ManufacturerParameter; use App\Entity\Parameters\MeasurementUnitParameter; use App\Entity\Parameters\PartParameter; +use App\Entity\Parameters\ProjectParameter; use App\Entity\Parameters\StorageLocationParameter; use App\Entity\Parameters\SupplierParameter; +use App\Entity\Parts\Category; +use App\Entity\Parts\Footprint; use App\Entity\Parts\Part; use App\Entity\PriceInformations\Currency; use App\Repository\ParameterRepository; +use App\Services\AI\AIPlatformRegistry; +use App\Services\AI\AIPlatforms; use App\Services\Attachments\AttachmentURLGenerator; use App\Services\Attachments\BuiltinAttachmentsFinder; use App\Services\Attachments\PartPreviewGenerator; use App\Services\Tools\TagFinder; +use App\Settings\MiscSettings\IpnSuggestSettings; use Doctrine\ORM\EntityManagerInterface; +use Symfony\AI\Platform\Capability; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Asset\Packages; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; @@ -126,9 +126,12 @@ class TypeaheadController extends AbstractController } #[Route(path: '/parts/search/{query}', name: 'typeahead_parts')] - public function parts(EntityManagerInterface $entityManager, PartPreviewGenerator $previewGenerator, - AttachmentURLGenerator $attachmentURLGenerator, string $query = ""): JsonResponse - { + public function parts( + EntityManagerInterface $entityManager, + PartPreviewGenerator $previewGenerator, + AttachmentURLGenerator $attachmentURLGenerator, + string $query = "" + ): JsonResponse { $this->denyAccessUnlessGranted('@parts.read'); $repo = $entityManager->getRepository(Part::class); @@ -139,7 +142,7 @@ class TypeaheadController extends AbstractController foreach ($parts as $part) { //Determine the picture to show: $preview_attachment = $previewGenerator->getTablePreviewAttachment($part); - if($preview_attachment instanceof Attachment) { + if ($preview_attachment instanceof Attachment) { $preview_url = $attachmentURLGenerator->getThumbnailURL($preview_attachment, 'thumbnail_sm'); } else { $preview_url = ''; @@ -153,7 +156,7 @@ class TypeaheadController extends AbstractController 'footprint' => $part->getFootprint() instanceof Footprint ? $part->getFootprint()->getName() : '', 'description' => mb_strimwidth($part->getDescription(), 0, 127, '...'), 'image' => $preview_url, - ]; + ]; } return new JsonResponse($data); @@ -224,7 +227,8 @@ class TypeaheadController extends AbstractController $partRepository = $entityManager->getRepository(Part::class); - $ipnSuggestions = $partRepository->autoCompleteIpn($clonedPart, $description, $this->ipnSuggestSettings->suggestPartDigits); + $ipnSuggestions = $partRepository->autoCompleteIpn($clonedPart, $description, + $this->ipnSuggestSettings->suggestPartDigits); return new JsonResponse($ipnSuggestions); } @@ -232,16 +236,26 @@ class TypeaheadController extends AbstractController #[Route(path: '/ai/{platform}/models', name: 'typeahead_ai_models', requirements: ['platform' => '.+'])] public function aiModels( AIPlatforms $platform, + Request $request, AIPlatformRegistry $platformRegistry, CacheInterface $cache, ): JsonResponse { - $this->denyAccessUnlessGranted('@config.change_system_settings'); - $models = $cache->get('ai_models_'.$platform->value, function(ItemInterface $item) use ($platformRegistry, $platform) { - $item->expiresAfter(3600); //Cache for 1 hour - return $platformRegistry->getPlatform($platform)->getModelCatalog()->getModels(); - }); + $capability_filter = $request->query->getEnum('capability', Capability::class); + + $models = $cache->get('ai_models_'.$platform->value.'_'.($capability_filter?->value ?? 'all'), + function (ItemInterface $item) use ($platformRegistry, $platform, $capability_filter) { + $item->expiresAfter(3600); //Cache for 1 hour + if ($capability_filter === null) { + return $platformRegistry->getPlatform($platform)->getModelCatalog()->getModels(); + } + + //Otherwise filter the models by the capability + return array_filter($platformRegistry->getPlatform($platform)->getModelCatalog()->getModels(), + static fn(array $model) => in_array($capability_filter, $model['capabilities'] ?? [], true) + ); + }); return new JsonResponse($models); } diff --git a/src/Form/Settings/AiModelsType.php b/src/Form/Settings/AiModelsType.php index 78b088ed..5228bb47 100644 --- a/src/Form/Settings/AiModelsType.php +++ b/src/Form/Settings/AiModelsType.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\Form\Settings; +use Symfony\AI\Platform\Capability; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormInterface; @@ -50,11 +51,20 @@ final class AiModelsType extends AbstractType //The target label of the platform select, which is used to filter the models for the selected platform. $resolver->setRequired('platform_selector'); $resolver->setAllowedTypes('platform_selector', 'string'); + + //Only show models, that have the given capability. This is used to only show models that support structured output for the AI extractor settings. + $resolver->setDefault('filter_capability', null); + $resolver->setAllowedTypes('filter_capability', ['null', Capability::class]); } public function finishView(FormView $view, FormInterface $form, array $options): void { - $view->vars['attr']['data-url-template'] = $this->urlGenerator->generate('typeahead_ai_models', ['platform' => '__PLATFORM__']); + $urlOptions = ['platform' => '__PLATFORM__']; + if ($options['filter_capability'] !== null) { + $urlOptions['capability'] = $options['filter_capability']->value; + } + + $view->vars['attr']['data-url-template'] = $this->urlGenerator->generate('typeahead_ai_models', $urlOptions); $view->vars['attr']['data-controller'] = 'elements--ai-model-autocomplete'; $view->vars['attr']['data-platform-selector'] = $options['platform_selector']; diff --git a/src/Settings/InfoProviderSystem/AIExtractorSettings.php b/src/Settings/InfoProviderSystem/AIExtractorSettings.php index 0852d2ec..2efd6717 100644 --- a/src/Settings/InfoProviderSystem/AIExtractorSettings.php +++ b/src/Settings/InfoProviderSystem/AIExtractorSettings.php @@ -31,6 +31,7 @@ use Jbtronics\SettingsBundle\Metadata\EnvVarMode; use Jbtronics\SettingsBundle\Settings\Settings; use Jbtronics\SettingsBundle\Settings\SettingsParameter; use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\AI\Platform\Capability; use Symfony\Component\Translation\TranslatableMessage as TM; #[Settings(name: "ai_extractor", label: new TM("settings.ips.ai_extractor"), description: new TM("settings.ips.ai_extractor.description"))] @@ -48,7 +49,7 @@ class AIExtractorSettings public ?AIPlatforms $platform = null; #[SettingsParameter(label: new TM("settings.ips.ai_extractor.model"), description: new TM("settings.ips.ai_extractor.model.description"), - formType: AiModelsType::class, formOptions: ['platform_selector' => self::MODEL_SELECTOR_LABEL], + formType: AiModelsType::class, formOptions: ['platform_selector' => self::MODEL_SELECTOR_LABEL, 'filter_capability' => Capability::OUTPUT_STRUCTURED], envVar: "string:PROVIDER_AI_EXTRACTOR_MODEL", envVarMode: EnvVarMode::OVERWRITE )] public string $model = 'z-ai/glm-4.7'; From af98fc10795599f886e512176fd91e40545f4c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 15:48:17 +0200 Subject: [PATCH 11/36] Added translations to AI settings --- .../Providers/AIInfoExtractor.php | 6 +- src/Settings/AISettings/AISettings.php | 2 +- src/Settings/AISettings/LMStudioSettings.php | 4 +- .../AISettings/OpenRouterSettings.php | 2 +- .../AIExtractorSettings.php | 19 ++--- translations/messages.en.xlf | 72 ++++++++++++++----- 6 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index d5be0267..c8eff0a4 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -60,7 +60,7 @@ final class AIInfoExtractor implements InfoProviderInterface return [ 'name' => 'AI Information Extractor', 'description' => 'Extract part info from any URL using OpenRouter LLM', - 'url' => 'https://openrouter.ai', + //'url' => 'https://openrouter.ai', 'disabled_help' => 'Configure OpenRouter API key in settings', 'settings_class' => AIExtractorSettings::class, ]; @@ -73,7 +73,7 @@ final class AIInfoExtractor implements InfoProviderInterface public function isActive(): bool { - return $this->settings->platform !== null && $this->settings->model !== ''; + return $this->settings->platform !== null && $this->settings->model !== null && $this->settings->model !== ''; } public function searchByKeyword(string $keyword): array @@ -171,7 +171,7 @@ final class AIInfoExtractor implements InfoProviderInterface $aiPlatform = $this->AIPlatformRegistry->getPlatform($this->settings->platform ?? throw new \RuntimeException('No AI platform selected') ); //'openai/gpt-5-mini' - $result = $aiPlatform->invoke($this->settings->model, $input, [ + $result = $aiPlatform->invoke($this->settings->model ?? throw new \RuntimeException('No model selected'), $input, [ 'response_format' => [ 'type' => 'json_schema', 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), diff --git a/src/Settings/AISettings/AISettings.php b/src/Settings/AISettings/AISettings.php index 0e99d6fc..732eb597 100644 --- a/src/Settings/AISettings/AISettings.php +++ b/src/Settings/AISettings/AISettings.php @@ -29,7 +29,7 @@ use Jbtronics\SettingsBundle\Settings\Settings; use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\Component\Translation\TranslatableMessage as TM; -#[Settings(label: new TM("settings.ai"), description: "settings.ai.help")] +#[Settings(label: new TM("settings.ai"))] #[SettingsIcon("fa-brain")] class AISettings { diff --git a/src/Settings/AISettings/LMStudioSettings.php b/src/Settings/AISettings/LMStudioSettings.php index ea6b9681..627961a9 100644 --- a/src/Settings/AISettings/LMStudioSettings.php +++ b/src/Settings/AISettings/LMStudioSettings.php @@ -33,8 +33,8 @@ use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\Translation\TranslatableMessage as TM; -#[Settings(name: 'ai_lmstudio', label: new TM("settings.ai.openrouter"), description: "settings.ai.lmstudio.help")] -#[SettingsIcon("fa-brain")] +#[Settings(name: 'ai_lmstudio', label: new TM("settings.ai.lmstudio"))] +#[SettingsIcon("fa-robot")] class LMStudioSettings implements AIPlatformSettingsInterface { use SettingsTrait; diff --git a/src/Settings/AISettings/OpenRouterSettings.php b/src/Settings/AISettings/OpenRouterSettings.php index 7b96c1d9..e083513a 100644 --- a/src/Settings/AISettings/OpenRouterSettings.php +++ b/src/Settings/AISettings/OpenRouterSettings.php @@ -33,7 +33,7 @@ use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\Component\Translation\TranslatableMessage as TM; #[Settings(name: 'ai_openrouter', label: new TM("settings.ai.openrouter"), description: "settings.ai.openrouter.help")] -#[SettingsIcon("fa-brain")] +#[SettingsIcon("fa-robot")] class OpenRouterSettings implements AIPlatformSettingsInterface { use SettingsTrait; diff --git a/src/Settings/InfoProviderSystem/AIExtractorSettings.php b/src/Settings/InfoProviderSystem/AIExtractorSettings.php index 2efd6717..876c687f 100644 --- a/src/Settings/InfoProviderSystem/AIExtractorSettings.php +++ b/src/Settings/InfoProviderSystem/AIExtractorSettings.php @@ -35,32 +35,25 @@ use Symfony\AI\Platform\Capability; use Symfony\Component\Translation\TranslatableMessage as TM; #[Settings(name: "ai_extractor", label: new TM("settings.ips.ai_extractor"), description: new TM("settings.ips.ai_extractor.description"))] -#[SettingsIcon("fa-robot")] +#[SettingsIcon("fa-plug")] class AIExtractorSettings { private const MODEL_SELECTOR_LABEL = 'ai_extractor'; use SettingsTrait; - #[SettingsParameter(label: new TM("settings.ips.ai_extractor.ai_platform"), description: new TM("settings.ips.ai_extractor.ai_platform.help"), + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.ai_platform"), formType: AiPlatformChoiceType::class, formOptions: ['platform_selector_label' => self::MODEL_SELECTOR_LABEL], - envVar: "string:PROVIDER_AI_EXTRACTOR_API_KEY", envVarMode: EnvVarMode::OVERWRITE )] public ?AIPlatforms $platform = null; - #[SettingsParameter(label: new TM("settings.ips.ai_extractor.model"), description: new TM("settings.ips.ai_extractor.model.description"), + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.model"), description: new TM("settings.ips.ai_extractor.model.help"), formType: AiModelsType::class, formOptions: ['platform_selector' => self::MODEL_SELECTOR_LABEL, 'filter_capability' => Capability::OUTPUT_STRUCTURED], - envVar: "string:PROVIDER_AI_EXTRACTOR_MODEL", envVarMode: EnvVarMode::OVERWRITE )] - public string $model = 'z-ai/glm-4.7'; + public ?string $model = null; - #[SettingsParameter(label: new TM("settings.ips.ai_extractor.enabled"), description: new TM("settings.ips.ai_extractor.enabled.description"), - envVar: "bool:PROVIDER_AI_EXTRACTOR_ENABLED", envVarMode: EnvVarMode::OVERWRITE - )] - public bool $enabled = false; - - #[SettingsParameter(label: new TM("settings.ips.ai_extractor.max_content_length"), description: new TM("settings.ips.ai_extractor.max_content_length.description"), - envVar: "int:PROVIDER_AI_EXTRACTOR_MAX_CONTENT_LENGTH", envVarMode: EnvVarMode::OVERWRITE + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.max_content_length"), + description: new TM("settings.ips.ai_extractor.max_content_length.description"), )] public int $maxContentLength = 50000; } diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index 4da88512..e16a6d69 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -2780,7 +2780,7 @@ If you have done this incorrectly or if a computer is no longer trusted, you can Name - + part.table.si_value SI Value @@ -7218,13 +7218,13 @@ Element 1 -> Element 1.2 Subprojects - + project.info.total_build_price Total build price - + project.info.per_unit_price per unit @@ -7254,7 +7254,7 @@ Element 1 -> Element 1.2 Price - + project.bom.ext_price Extended Price @@ -10053,85 +10053,85 @@ Please note, that you can not impersonate a disabled user. If you try you will g When enabled, the datasheet field in KiCad will link to the actual PDF file (if found). When disabled, it will link to the Part-DB page instead. The Part-DB page link is always available as a separate "Part-DB URL" field. - + settings.misc.kicad_eda.editor.title KiCad autocomplete lists - + settings.misc.kicad_eda.editor.link Autocomplete settings - + settings.misc.kicad_eda.editor.description Configure whether KiCad autocomplete uses the autogenerated default lists or your custom override files. The custom files are editable here, while the default files are shown read-only for reference. - + settings.misc.kicad_eda.editor.footprints Footprints list - + settings.misc.kicad_eda.editor.footprints.help One entry per line. Used as autocomplete suggestions for KiCad footprint fields. - + settings.misc.kicad_eda.editor.symbols Symbols list - + settings.misc.kicad_eda.editor.symbols.help One entry per line. Used as autocomplete suggestions for KiCad symbol fields. - + settings.misc.kicad_eda.use_custom_list Use custom autocomplete lists - + settings.misc.kicad_eda.use_custom_list.help When enabled, KiCad autocomplete uses public/kicad/footprints_custom.txt and public/kicad/symbols_custom.txt instead of the autogenerated default files. - + settings.misc.kicad_eda.editor.custom_footprints Custom footprints list - + settings.misc.kicad_eda.editor.custom_symbols Custom symbols list - + settings.misc.kicad_eda.editor.default_footprints Default footprints list - + settings.misc.kicad_eda.editor.default_symbols Default symbols list - + settings.misc.kicad_eda.editor.default_files_help Autogenerated file shown for reference only. Changes must be made in the custom list. @@ -13067,5 +13067,41 @@ Buerklin-API Authentication server: Mapping error: Check if you have selected the right delimiter! + + + settings.ai + AI + + + + + settings.ai.openrouter + OpenRouter + + + + + settings.ai.lmstudio + LMStudio + + + + + settings.ips.ai_extractor.model + AI Model + + + + + settings.ips.ai_extractor.ai_platform + AI Platform + + + + + settings.ips.ai_extractor.model.help + The AI model that should be used for extraction. Must support structured output. + + From 4dbd92ac4d5d806f4f37275d66ad9a3bbbbb7d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 19:36:03 +0200 Subject: [PATCH 12/36] Use markdown as input for the LLM and add extracted microdata separatley --- composer.json | 7 + composer.lock | 466 +++++++++++++++--- .../DTOJsonSchemaConverter.php | 14 +- .../Providers/AIInfoExtractor.php | 85 ++-- symfony.lock | 6 - 5 files changed, 481 insertions(+), 97 deletions(-) diff --git a/composer.json b/composer.json index c7c52d5c..c4b3cb59 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "jbtronics/dompdf-font-loader-bundle": "^1.0.0", "jbtronics/settings-bundle": "^3.0.0", "jfcherng/php-diff": "^6.14", + "jkphl/micrometa": "dev-master", "knpuniversity/oauth2-client-bundle": "^2.15", "league/commonmark": "^2.7", "league/csv": "^9.8.0", @@ -159,6 +160,12 @@ "App\\Tests\\": "tests/" } }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/jbtronics/micrometa" + } + ], "scripts": { "auto-scripts": { "cache:clear": "symfony-cmd", diff --git a/composer.lock b/composer.lock index 00b5e831..1963342f 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": "699f421ad81f8a1acacf8e2c4af66491", + "content-hash": "7c76e3af5fd042105a3208fdcb300a11", "packages": [ { "name": "amphp/amp", @@ -3883,16 +3883,16 @@ }, { "name": "doctrine/migrations", - "version": "3.9.6", + "version": "3.9.7", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "ffd8355cdd8505fc650d9604f058bf62aedd80a1" + "reference": "96cb2a89b56c9efb0bac38e606dc0b0f13e650ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/ffd8355cdd8505fc650d9604f058bf62aedd80a1", - "reference": "ffd8355cdd8505fc650d9604f058bf62aedd80a1", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/96cb2a89b56c9efb0bac38e606dc0b0f13e650ec", + "reference": "96cb2a89b56c9efb0bac38e606dc0b0f13e650ec", "shasum": "" }, "require": { @@ -3966,7 +3966,7 @@ ], "support": { "issues": "https://github.com/doctrine/migrations/issues", - "source": "https://github.com/doctrine/migrations/tree/3.9.6" + "source": "https://github.com/doctrine/migrations/tree/3.9.7" }, "funding": [ { @@ -3982,7 +3982,7 @@ "type": "tidelift" } ], - "time": "2026-02-11T06:46:11+00:00" + "time": "2026-04-23T19:33:20+00:00" }, { "name": "doctrine/orm", @@ -4074,19 +4074,20 @@ }, { "name": "doctrine/persistence", - "version": "4.1.1", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "b9c49ad3558bb77ef973f4e173f2e9c2eca9be09" + "reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/b9c49ad3558bb77ef973f4e173f2e9c2eca9be09", - "reference": "b9c49ad3558bb77ef973f4e173f2e9c2eca9be09", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b", + "reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b", "shasum": "" }, "require": { + "doctrine/deprecations": "^1", "doctrine/event-manager": "^1 || ^2", "php": "^8.1", "psr/cache": "^1.0 || ^2.0 || ^3.0" @@ -4097,13 +4098,13 @@ "phpstan/phpstan-phpunit": "^2", "phpstan/phpstan-strict-rules": "^2", "phpunit/phpunit": "^10.5.58 || ^12", - "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0", - "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0" + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0", + "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Persistence\\": "src/Persistence" + "Doctrine\\Persistence\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4147,7 +4148,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/4.1.1" + "source": "https://github.com/doctrine/persistence/tree/4.2.0" }, "funding": [ { @@ -4163,7 +4164,7 @@ "type": "tidelift" } ], - "time": "2025-10-16T20:13:18+00:00" + "time": "2026-04-26T12:12:52+00:00" }, { "name": "doctrine/sql-formatter", @@ -5534,6 +5535,191 @@ ], "time": "2023-05-21T07:57:08+00:00" }, + { + "name": "jkphl/dom-factory", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/jkphl/dom-factory.git", + "reference": "dd32b8b2cc800f065c0eff8bb621d9f80147d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jkphl/dom-factory/zipball/dd32b8b2cc800f065c0eff8bb621d9f80147d45e", + "reference": "dd32b8b2cc800f065c0eff8bb621d9f80147d45e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "guzzlehttp/guzzle": "^6.0||^7.0", + "masterminds/html5": "^2.7", + "php": ">=7.2" + }, + "require-dev": { + "clue/graph-composer": "^1.1", + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.0||^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jkphl\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joschi Kuphal", + "email": "joschi@kuphal.net", + "homepage": "https://jkphl.is", + "role": "Developer" + } + ], + "description": "Simple HTML5/XML DOM factory", + "homepage": "https://github.com/jkphl/dom-factory", + "support": { + "email": "joschi@kuphal.net", + "issues": "https://github.com/jkphl/dom-factory/issues", + "source": "https://github.com/jkphl/dom-factory" + }, + "time": "2021-06-28T11:49:36+00:00" + }, + { + "name": "jkphl/micrometa", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/jbtronics/micrometa.git", + "reference": "720f409151c2cc20add9478b7a0a635fa1707021" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jbtronics/micrometa/zipball/720f409151c2cc20add9478b7a0a635fa1707021", + "reference": "720f409151c2cc20add9478b7a0a635fa1707021", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "jkphl/dom-factory": "^1", + "jkphl/rdfa-lite-microdata": "^0.4.4", + "league/uri": "^5.0|^6.5|^7.0", + "mf2/mf2": "^0.4", + "ml/json-ld": "^1.2", + "monolog/monolog": "^1.24 || ^2 || ^3", + "php": ">=7.1.3", + "psr/cache": "^1.0|^2|^3", + "psr/log": "^1.1|^2|^3", + "symfony/cache": "^4.0|^5.0|^6.0|^7.0|^8.0" + }, + "require-dev": { + "clue/graph-composer": "^1.1", + "mf2/tests": "@dev", + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^7.0 || ^8.5", + "squizlabs/php_codesniffer": "^3.3" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Jkphl\\": "src/" + } + }, + "scripts": { + "phpunit": [ + "vendor/bin/phpunit --configuration phpunit.xml.dist" + ], + "depgraph": [ + "vendor/bin/graph-composer --no-dev export . doc/dependencies.svg" + ], + "check-style": [ + "vendor/bin/phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src" + ], + "fix-style": [ + "vendor/bin/phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src" + ], + "test": [ + "@phpunit" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joschi Kuphal", + "email": "joschi@tollwerk.de", + "homepage": "https://jkphl.is", + "role": "Developer" + } + ], + "description": "A meta parser for extracting micro information out of web documents, currently supporting Microformats 1+2, HTML Microdata, RDFa Lite 1.1 and JSON-LD", + "homepage": "https://jkphl.is/projects/micrometa/", + "support": { + "email": "joschi@tollwerk.de", + "source": "https://github.com/jkphl/micrometa", + "issues": "https://github.com/jkphl/micrometa/issues" + }, + "time": "2026-04-26T17:25:19+00:00" + }, + { + "name": "jkphl/rdfa-lite-microdata", + "version": "v0.4.7", + "source": { + "type": "git", + "url": "https://github.com/jkphl/rdfa-lite-microdata.git", + "reference": "ffc4940e8be55798257a03da7ed7d4506a13c3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jkphl/rdfa-lite-microdata/zipball/ffc4940e8be55798257a03da7ed7d4506a13c3e5", + "reference": "ffc4940e8be55798257a03da7ed7d4506a13c3e5", + "shasum": "" + }, + "require": { + "jkphl/dom-factory": "^1", + "php": ">=5.5" + }, + "require-dev": { + "clue/graph-composer": "dev-master", + "codeclimate/php-test-reporter": "^0.4.4", + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^2.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jkphl\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joschi Kuphal", + "email": "joschi@tollwerk.de", + "homepage": "https://jkphl.is", + "role": "Developer" + } + ], + "description": "RDFa Lite 1.1 and HTML Microdata parser for web documents (HTML, SVG, XML)", + "homepage": "https://github.com/jkphl/rdfa-lite-microdata", + "support": { + "email": "joschi@tollwerk.de", + "issues": "https://github.com/jkphl/rdfa-lite-microdata/issues", + "source": "https://github.com/jkphl/rdfa-lite-microdata" + }, + "time": "2023-01-27T13:29:45+00:00" + }, { "name": "kelunik/certificate", "version": "v1.1.3", @@ -6899,6 +7085,170 @@ }, "time": "2025-07-25T09:04:22+00:00" }, + { + "name": "mf2/mf2", + "version": "0.4.6", + "source": { + "type": "git", + "url": "https://github.com/microformats/php-mf2.git", + "reference": "00b70ee7eb7f5b0585b1bd467f6c9cbd75055d23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/microformats/php-mf2/zipball/00b70ee7eb7f5b0585b1bd467f6c9cbd75055d23", + "reference": "00b70ee7eb7f5b0585b1bd467f6c9cbd75055d23", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "mf2/tests": "@dev", + "phpdocumentor/phpdocumentor": "v2.8.4", + "phpunit/phpunit": "4.8.*" + }, + "suggest": { + "barnabywalters/mf-cleaner": "To more easily handle the canonical data php-mf2 gives you", + "masterminds/html5": "Alternative HTML parser for PHP, for better HTML5 support." + }, + "bin": [ + "bin/fetch-mf2", + "bin/parse-mf2" + ], + "type": "library", + "autoload": { + "files": [ + "Mf2/Parser.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "CC0-1.0" + ], + "authors": [ + { + "name": "Barnaby Walters", + "homepage": "http://waterpigs.co.uk" + } + ], + "description": "A pure, generic microformats2 parser — makes HTML as easy to consume as a JSON API", + "keywords": [ + "html", + "microformats", + "microformats 2", + "parser", + "semantic" + ], + "support": { + "issues": "https://github.com/microformats/php-mf2/issues", + "source": "https://github.com/microformats/php-mf2/tree/master" + }, + "time": "2018-08-24T14:47:04+00:00" + }, + { + "name": "ml/iri", + "version": "1.1.4", + "target-dir": "ML/IRI", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/IRI.git", + "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/IRI/zipball/cbd44fa913e00ea624241b38cefaa99da8d71341", + "reference": "cbd44fa913e00ea624241b38cefaa99da8d71341", + "shasum": "" + }, + "require": { + "lib-pcre": ">=4.0", + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "ML\\IRI": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Lanthaler", + "email": "mail@markus-lanthaler.com", + "homepage": "http://www.markus-lanthaler.com", + "role": "Developer" + } + ], + "description": "IRI handling for PHP", + "homepage": "http://www.markus-lanthaler.com", + "keywords": [ + "URN", + "iri", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/lanthaler/IRI/issues", + "source": "https://github.com/lanthaler/IRI/tree/master" + }, + "time": "2014-01-21T13:43:39+00:00" + }, + { + "name": "ml/json-ld", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/lanthaler/JsonLD.git", + "reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/537e68e87a6bce23e57c575cd5dcac1f67ce25d8", + "reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ml/iri": "^1.1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "json-ld/tests": "1.0", + "phpunit/phpunit": "^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ML\\JsonLD\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Lanthaler", + "email": "mail@markus-lanthaler.com", + "homepage": "http://www.markus-lanthaler.com", + "role": "Developer" + } + ], + "description": "JSON-LD Processor for PHP", + "homepage": "http://www.markus-lanthaler.com", + "keywords": [ + "JSON-LD", + "jsonld" + ], + "support": { + "issues": "https://github.com/lanthaler/JsonLD/issues", + "source": "https://github.com/lanthaler/JsonLD/tree/1.2.1" + }, + "time": "2022-09-29T08:45:17+00:00" + }, { "name": "monolog/monolog", "version": "3.10.0", @@ -9409,16 +9759,16 @@ }, { "name": "rhukster/dom-sanitizer", - "version": "1.0.10", + "version": "1.0.11", "source": { "type": "git", "url": "https://github.com/rhukster/dom-sanitizer.git", - "reference": "49a98046b708a4c92f754f5b0ef1720bb85142e2" + "reference": "02d08ec8b36b93b04517d74fe82b715ef06273bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rhukster/dom-sanitizer/zipball/49a98046b708a4c92f754f5b0ef1720bb85142e2", - "reference": "49a98046b708a4c92f754f5b0ef1720bb85142e2", + "url": "https://api.github.com/repos/rhukster/dom-sanitizer/zipball/02d08ec8b36b93b04517d74fe82b715ef06273bd", + "reference": "02d08ec8b36b93b04517d74fe82b715ef06273bd", "shasum": "" }, "require": { @@ -9448,9 +9798,9 @@ "description": "A simple but effective DOM/SVG/MathML Sanitizer for PHP 7.4+", "support": { "issues": "https://github.com/rhukster/dom-sanitizer/issues", - "source": "https://github.com/rhukster/dom-sanitizer/tree/1.0.10" + "source": "https://github.com/rhukster/dom-sanitizer/tree/1.0.11" }, - "time": "2026-04-10T17:00:11+00:00" + "time": "2026-04-23T22:56:32+00:00" }, { "name": "robrichards/xmlseclibs", @@ -13693,7 +14043,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -13752,7 +14102,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -13776,16 +14126,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df" + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/ad1b7b9092976d6c948b8a187cec9faaea9ec1df", - "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", "shasum": "" }, "require": { @@ -13834,7 +14184,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" }, "funding": [ { @@ -13854,11 +14204,11 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:19:22+00:00" + "time": "2026-04-26T13:13:48+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", @@ -13922,7 +14272,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.37.0" }, "funding": [ { @@ -13946,7 +14296,7 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -14009,7 +14359,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0" }, "funding": [ { @@ -14033,7 +14383,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -14094,7 +14444,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" }, "funding": [ { @@ -14118,7 +14468,7 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", @@ -14174,7 +14524,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0" }, "funding": [ { @@ -14198,7 +14548,7 @@ }, { "name": "symfony/polyfill-php84", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", @@ -14254,7 +14604,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" }, "funding": [ { @@ -14278,16 +14628,16 @@ }, { "name": "symfony/polyfill-php85", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "2c408a6bb0313e6001a83628dc5506100474254e" + "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/2c408a6bb0313e6001a83628dc5506100474254e", - "reference": "2c408a6bb0313e6001a83628dc5506100474254e", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee", + "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee", "shasum": "" }, "require": { @@ -14334,7 +14684,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0" }, "funding": [ { @@ -14354,11 +14704,11 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:50:15+00:00" + "time": "2026-04-26T13:10:57+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.36.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", @@ -14417,7 +14767,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.36.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" }, "funding": [ { @@ -19854,12 +20204,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "10b8a93511210c9bae3be31f4fe13c3ff974cad4" + "reference": "08cd07f04fb07fb4d316e956801d57b700cf7096" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/10b8a93511210c9bae3be31f4fe13c3ff974cad4", - "reference": "10b8a93511210c9bae3be31f4fe13c3ff974cad4", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/08cd07f04fb07fb4d316e956801d57b700cf7096", + "reference": "08cd07f04fb07fb4d316e956801d57b700cf7096", "shasum": "" }, "conflict": { @@ -19882,6 +20232,7 @@ "alextselegidis/easyappointments": "<=1.5.2", "alexusmai/laravel-file-manager": "<=3.3.1", "algolia/algoliasearch-magento-2": "<=3.16.1|>=3.17.0.0-beta1,<=3.17.1", + "almirhodzic/nova-toggle-5": "<1.3", "alt-design/alt-redirect": "<1.6.4", "altcha-org/altcha": "<1.3.1", "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", @@ -19978,7 +20329,7 @@ "ckeditor/ckeditor": "<4.25", "clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3", "co-stack/fal_sftp": "<0.2.6", - "cockpit-hq/cockpit": "<2.13.5", + "cockpit-hq/cockpit": "<2.14", "code16/sharp": "<9.20", "codeception/codeception": "<3.1.3|>=4,<4.1.22", "codeigniter/framework": "<3.1.10", @@ -20141,7 +20492,7 @@ "fisharebest/webtrees": "<=2.1.18", "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", "fixpunkt/fp-newsletter": "<1.1.1|>=1.2,<2.1.2|>=2.2,<3.2.6", - "flarum/core": "<1.8.10", + "flarum/core": "<=1.8.15|>=2.0.0.0-beta1,<=2.0.0.0-beta8", "flarum/flarum": "<0.1.0.0-beta8", "flarum/framework": "<1.8.10", "flarum/mentions": "<1.6.3", @@ -20178,7 +20529,7 @@ "geshi/geshi": "<=1.0.9.1", "getformwork/formwork": "<=2.3.3", "getgrav/grav": "<1.11.0.0-beta1", - "getkirby/cms": "<=5.2.1", + "getkirby/cms": "<5.4", "getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", @@ -20276,7 +20627,7 @@ "kelvinmo/simplexrd": "<3.1.1", "kevinpapst/kimai2": "<1.16.7", "khodakhah/nodcms": "<=3.4.1", - "kimai/kimai": "<=2.53", + "kimai/kimai": "<2.54", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", "knplabs/knp-snappy": "<=1.4.2", @@ -20720,7 +21071,7 @@ "twig/twig": "<3.11.2|>=3.12,<3.14.1|>=3.16,<3.19", "typicms/core": "<16.1.7", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", - "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", + "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1|==14.2", "typo3/cms-belog": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", "typo3/cms-beuser": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", "typo3/cms-core": "<=8.7.56|>=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", @@ -20902,7 +21253,7 @@ "type": "tidelift" } ], - "time": "2026-04-22T18:27:19+00:00" + "time": "2026-04-24T17:22:29+00:00" }, { "name": "sebastian/cli-parser", @@ -22418,6 +22769,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "jkphl/micrometa": 20, "roave/security-advisories": 20 }, "prefer-stable": false, diff --git a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php index b9208c87..2d297243 100644 --- a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php +++ b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php @@ -54,7 +54,8 @@ final class DTOJsonSchemaConverter 'category' => ['type' => ['string', 'null'], 'description' => 'Product category'], 'manufacturing_status' => ['type' => ['string', 'null'], 'enum' => ['active', 'obsolete', 'nrfnd', 'discontinued', null], 'description' => 'Manufacturing status'], 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type'], - 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass in grams'], + 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass of the product in grams'], + 'gtin' => ['type' => ['string', 'null'], 'description' => 'Global Trade Item Number (GTIN) / EAN / UPC code'], 'parameters' => [ 'type' => 'array', 'items' => [ @@ -94,17 +95,17 @@ final class DTOJsonSchemaConverter 'items' => [ 'type' => 'object', 'properties' => [ - 'distributor_name' => ['type' => 'string'], - 'order_number' => ['type' => ['string', 'null']], + 'distributor_name' => ['type' => 'string', 'description' => 'Name of the distributor or vendor. Typically the shop name'], + 'order_number' => ['type' => ['string', 'null'], 'description' => 'The order number or SKU used by the distributor. Optional, but can help to find the product on the distributor website.'], 'product_url' => ['type' => 'string'], 'prices' => [ 'type' => 'array', 'items' => [ 'type' => 'object', 'properties' => [ - 'minimum_quantity' => ['type' => 'integer'], - 'price' => ['type' => 'number'], - 'currency' => ['type' => 'string'], + 'minimum_quantity' => ['type' => 'integer', 'description' => 'Minimum quantity for this price tier. 1 when no tiered pricing is available.'], + 'price' => ['type' => 'number', 'description' => 'Price for the given minimum quantity.'], + 'currency' => ['type' => 'string', 'description' => 'Currency ISO code, e.g. USD'], ], 'required' => ['minimum_quantity', 'price', 'currency'], ], @@ -226,6 +227,7 @@ final class DTOJsonSchemaConverter manufacturing_status: $manufacturingStatus, provider_url: $productUrl, footprint: $data['footprint'] ?? null, + gtin: $data['gtin'] ?? null, notes: null, datasheets: $datasheets, images: $images, diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index c8eff0a4..7ae858a6 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -29,10 +29,15 @@ use App\Services\AI\AIPlatformRegistry; use App\Services\InfoProviderSystem\DTOJsonSchemaConverter; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Settings\InfoProviderSystem\AIExtractorSettings; +use Brick\Schema\SchemaReader; +use Jkphl\Micrometa; +use League\HTMLToMarkdown\HtmlConverter; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; +use Symfony\Component\DomCrawler\Crawler; use Symfony\Contracts\HttpClient\HttpClientInterface; + final class AIInfoExtractor implements InfoProviderInterface { use FixAndValidateUrlTrait; @@ -95,16 +100,56 @@ final class AIInfoExtractor implements InfoProviderInterface $html = $response->getContent(); // Clean HTML - $cleanedHtml = $this->cleanHTML($html); + /*$cleanedHtml = $this->cleanHTML($html); // Truncate to max content length - $truncatedHtml = $this->truncateHTML($cleanedHtml, $this->settings->maxContentLength); + $truncatedHtml = $this->truncateHTML($cleanedHtml, $this->settings->maxContentLength);*/ + + $markdown = $this->htmlToMarkdown($html); + + //Extract structured data using traditional methods, to provide additional context to the LLM. This can help improve accuracy, especially for technical specifications that might be in tables or specific formats. + $structuredData = $this->extractStructuredData($html, $url); // Call LLM - $llmResponse = $this->callLLM($truncatedHtml, $url); + $llmResponse = $this->callLLM($markdown, $url, $structuredData); // Build and return PartDetailDTO - return $this->jsonSchemaConverter->jsonToDTO($llmResponse, $this->getProviderKey(), $url, $url, self::DISTRIBUTOR_NAME); + $result = $this->jsonSchemaConverter->jsonToDTO($llmResponse, $this->getProviderKey(), $url, $url, self::DISTRIBUTOR_NAME); + + return $result; + } + + /** + * Extracts structured data from the HTML using microformats. + * @param string $html + * @param string $url + * @return string JSON encoded structured data + */ + private function extractStructuredData(string $html, string $url): string + { + $micrometa = new Micrometa\Ports\Parser(); + $items = $micrometa($url, $html); + + return json_encode($items->toObject(), JSON_THROW_ON_ERROR); + } + + private function htmlToMarkdown(string $html): string + { + //Extract only the main content of the page to avoid overwhelming the LLM with irrelevant information. + $crawler = new Crawler($html); + $mainContent = $crawler->filter('main, article, #content')->first(); + + // If we found a specific content area, get its HTML; otherwise, use the whole body. + $htmlToConvert = $mainContent->count() ? $mainContent->html() : $html; + + //Concert to markdown + $converter = new HtmlConverter([ + 'strip_tags' => true, // Removes tags that aren't Markdown-compatible (like
) + 'hard_break' => true, // Preserves line breaks + 'remove_nodes' => 'nav footer script style' // Extra safety layer + ]); + + return $converter->convert($htmlToConvert); } public function getCapabilities(): array @@ -160,13 +205,18 @@ final class AIInfoExtractor implements InfoProviderInterface return $truncated; } - private function callLLM(string $htmlContent, string $url): array + private function callLLM(string $htmlContent, string $url, ?string $structuredData = null): array { $input = new MessageBag( Message::forSystem($this->buildSystemPrompt()), Message::ofUser("Extract part information from this webpage content:\n\nURL: $url\n\n$htmlContent") ); + if ($structuredData) { + $input->add(Message::ofUser("Following data was extracted using traditional methods, but might be incomplete or inaccurate. + Enrich it with the actual website data:\n\n".$structuredData)); + } + try { $aiPlatform = $this->AIPlatformRegistry->getPlatform($this->settings->platform ?? throw new \RuntimeException('No AI platform selected') ); @@ -187,29 +237,8 @@ final class AIInfoExtractor implements InfoProviderInterface private function buildSystemPrompt(): string { return <<<'PROMPT' -You are an expert at extracting electronic component information from web pages. Extract structured data in JSON format. - -Return ONLY a valid JSON object with this exact structure: -{ - "name": "string", - "description": "string", - "manufacturer": "string | null", - "mpn": "string | null", - "category": "string | null", - "manufacturing_status": "active|obsolete|nrfnd|discontinued|null", - "footprint": "string | null", - "mass": "number | null (in grams)", - "parameters": [{"name": "string", "value": "string", "unit": "string | null"}], - "datasheets": [{"url": "string", "description": "string"}], - "images": [{"url": "string", "description": "string"}], - "vendor_infos": [{ - "distributor_name": "string", - "order_number": "string | null", - "product_url": "string", - "prices": [{"minimum_quantity": int, "price": number, "currency": "string"}] - }], - "manufacturer_product_url": "string | null" -} +You are an expert at extracting electronic component information from web pages. Extract structured data in JSON format, from markdown extracted from a product page. +Focus on the main content of the page, such as product descriptions, specifications, and tables. Ignore navigation menus, footers, and sidebars. Rules: - manufacturing_status: Use "active", "obsolete", "nrfnd" (not recommended for new designs), "discontinued", or null diff --git a/symfony.lock b/symfony.lock index dde7df36..f8f88675 100644 --- a/symfony.lock +++ b/symfony.lock @@ -441,12 +441,6 @@ "symfony/browser-kit": { "version": "v4.2.3" }, - "symfony/cache": { - "version": "v4.2.3" - }, - "symfony/cache-contracts": { - "version": "v1.1.5" - }, "symfony/config": { "version": "v4.2.3" }, From 4a45b5d5a9c439a81c0c99d3bedc2dbf1825a002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 21:31:07 +0200 Subject: [PATCH 13/36] Improved markdown conversion and add ability to extract notes --- .../DTOJsonSchemaConverter.php | 17 ++--- .../Providers/AIInfoExtractor.php | 62 ++++++------------- 2 files changed, 28 insertions(+), 51 deletions(-) diff --git a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php index 2d297243..759c3d12 100644 --- a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php +++ b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php @@ -48,14 +48,15 @@ final class DTOJsonSchemaConverter 'type' => 'object', 'properties' => [ 'name' => ['type' => 'string', 'description' => 'Product name'], - 'description' => ['type' => 'string', 'description' => 'Product description'], + 'description' => ['type' => 'string', 'description' => 'A short description of the product, maybe containing the most important things. Onnly One line.'], 'manufacturer' => ['type' => ['string', 'null'], 'description' => 'Manufacturer name'], 'mpn' => ['type' => ['string', 'null'], 'description' => 'Manufacturer Part Number'], - 'category' => ['type' => ['string', 'null'], 'description' => 'Product category'], + 'category' => ['type' => ['string', 'null'], 'description' => 'Product category, e.g. "Passive components -> Resistors"'], 'manufacturing_status' => ['type' => ['string', 'null'], 'enum' => ['active', 'obsolete', 'nrfnd', 'discontinued', null], 'description' => 'Manufacturing status'], - 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type'], + 'footprint' => ['type' => ['string', 'null'], 'description' => 'Package/footprint type, like "SOT-23", "DIP-8", "QFN-32" etc.'], 'mass' => ['type' => ['number', 'null'], 'description' => 'Mass of the product in grams'], - 'gtin' => ['type' => ['string', 'null'], 'description' => 'Global Trade Item Number (GTIN) / EAN / UPC code'], + 'gtin' => ['type' => ['string', 'null'], 'description' => 'Global Trade Item Number (GTIN) / EAN / UPC code for barcodes'], + 'notes' => ['type' => ['string', 'null'], 'description' => 'Optional long description of the part with more details than description. Can be markdown formatted.'], 'parameters' => [ 'type' => 'array', 'items' => [ @@ -98,6 +99,7 @@ final class DTOJsonSchemaConverter 'distributor_name' => ['type' => 'string', 'description' => 'Name of the distributor or vendor. Typically the shop name'], 'order_number' => ['type' => ['string', 'null'], 'description' => 'The order number or SKU used by the distributor. Optional, but can help to find the product on the distributor website.'], 'product_url' => ['type' => 'string'], + 'prices_include_vat' => ['type' => ['boolean', 'null'], 'description' => 'Whether the prices include VAT or not. Null if unknown.'], 'prices' => [ 'type' => 'array', 'items' => [ @@ -194,8 +196,8 @@ final class DTOJsonSchemaConverter $prices[] = new PriceDTO( minimum_discount_amount: (int) ($p['minimum_quantity'] ?? 1), price: (string) ($p['price'] ?? 0), - currency_iso_code: $p['currency'] ?? 'USD', - price_related_quantity: (int) ($p['minimum_quantity'] ?? 1), + currency_iso_code: $p['currency'] ?? null, + price_related_quantity: 1, ); } } @@ -205,6 +207,7 @@ final class DTOJsonSchemaConverter order_number: $v['order_number'] ?? 'Unknown', prices: $prices, product_url: $v['product_url'] ?? $productUrl, + prices_include_vat: $v['prices_include_vat'] ?? null, ); } } @@ -228,7 +231,7 @@ final class DTOJsonSchemaConverter provider_url: $productUrl, footprint: $data['footprint'] ?? null, gtin: $data['gtin'] ?? null, - notes: null, + notes: $data['notes'], datasheets: $datasheets, images: $images, parameters: $parameters, diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 7ae858a6..92ed4e19 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -37,6 +37,8 @@ use Symfony\AI\Platform\Message\MessageBag; use Symfony\Component\DomCrawler\Crawler; use Symfony\Contracts\HttpClient\HttpClientInterface; +use function Symfony\Component\String\u; + final class AIInfoExtractor implements InfoProviderInterface { @@ -105,7 +107,10 @@ final class AIInfoExtractor implements InfoProviderInterface // Truncate to max content length $truncatedHtml = $this->truncateHTML($cleanedHtml, $this->settings->maxContentLength);*/ + //Convert html to markdown, to provide a cleaner input to the LLM. $markdown = $this->htmlToMarkdown($html); + //Truncate markdown to max content length, if needed + $markdown = u($markdown)->truncate($this->settings->maxContentLength, '... [truncated]')->toString(); //Extract structured data using traditional methods, to provide additional context to the LLM. This can help improve accuracy, especially for technical specifications that might be in tables or specific formats. $structuredData = $this->extractStructuredData($html, $url); @@ -137,10 +142,21 @@ final class AIInfoExtractor implements InfoProviderInterface { //Extract only the main content of the page to avoid overwhelming the LLM with irrelevant information. $crawler = new Crawler($html); - $mainContent = $crawler->filter('main, article, #content')->first(); + $mainContent = $crawler->filter('main, article, #content'); // If we found a specific content area, get its HTML; otherwise, use the whole body. - $htmlToConvert = $mainContent->count() ? $mainContent->html() : $html; + //Concat the html of all matched nodes, to provide more context to the LLM, especially for pages that use multiple sections for product info. + if ($mainContent->count() > 0) { + $htmlToConvert = ''; + foreach ($mainContent as $node) { + $htmlToConvert .= $node->ownerDocument->saveHTML($node); + $htmlToConvert .= "\n\n"; // Add some spacing between sections + } + } else { + //Use the whole body content, as it might contain relevant information, especially for simpler pages that don't have a clear main/content section. + $htmlToConvert = $html; + } + //Concert to markdown $converter = new HtmlConverter([ @@ -163,48 +179,6 @@ final class AIInfoExtractor implements InfoProviderInterface ]; } - private function cleanHTML(string $html): string - { - // Remove script tags - $html = preg_replace('/]*>(.*?)<\/script>/is', '', $html); - - // Remove style tags - $html = preg_replace('/]*>(.*?)<\/style>/is', '', $html); - - // Remove nav tags - $html = preg_replace('/]*>(.*?)<\/nav>/is', '', $html); - - // Remove footer tags - $html = preg_replace('/]*>(.*?)<\/footer>/is', '', $html); - - // Remove header tags - $html = preg_replace('/]*>(.*?)<\/header>/is', '', $html); - - // Remove HTML comments - $html = preg_replace('//is', '', $html); - - return $html; - } - - private function truncateHTML(string $html, int $maxLength): string - { - if (strlen($html) <= $maxLength) { - return $html; - } - - // Truncate and find the last > or space to avoid cutting tags - $truncated = substr($html, 0, $maxLength); - - // Find the last occurrence of > or space - $lastPos = max(strrpos($truncated, '>'), strrpos($truncated, ' ')); - - if ($lastPos !== false && $lastPos > $maxLength * 0.9) { - $truncated = substr($truncated, 0, $lastPos + 1); - } - - return $truncated; - } - private function callLLM(string $htmlContent, string $url, ?string $structuredData = null): array { $input = new MessageBag( From 7117926584186c462056f4cad8dc4945ed770c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 21:32:19 +0200 Subject: [PATCH 14/36] Fixed error when notes are not defined --- src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php index 759c3d12..bfc41121 100644 --- a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php +++ b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php @@ -231,7 +231,7 @@ final class DTOJsonSchemaConverter provider_url: $productUrl, footprint: $data['footprint'] ?? null, gtin: $data['gtin'] ?? null, - notes: $data['notes'], + notes: $data['notes'] ?? null, datasheets: $datasheets, images: $images, parameters: $parameters, From 0ca5a41298796ba6a8ec56c15f87747f218472a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 22:11:27 +0200 Subject: [PATCH 15/36] Added option for translating AI extracted output --- .../Providers/AIInfoExtractor.php | 11 ++++++++- .../AIExtractorSettings.php | 8 +++++++ translations/messages.en.xlf | 24 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 92ed4e19..2032f634 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -35,6 +35,7 @@ use League\HTMLToMarkdown\HtmlConverter; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; use Symfony\Component\DomCrawler\Crawler; +use Symfony\Component\Intl\Languages; use Symfony\Contracts\HttpClient\HttpClientInterface; use function Symfony\Component\String\u; @@ -210,7 +211,7 @@ final class AIInfoExtractor implements InfoProviderInterface private function buildSystemPrompt(): string { - return <<<'PROMPT' + $tmp = <<<'PROMPT' You are an expert at extracting electronic component information from web pages. Extract structured data in JSON format, from markdown extracted from a product page. Focus on the main content of the page, such as product descriptions, specifications, and tables. Ignore navigation menus, footers, and sidebars. @@ -224,6 +225,14 @@ Rules: For parameters, combine name, value, and unit. The unit should be separate if possible. PROMPT; + + if ($this->settings->outputLanguage === null) { + $tmp .= "\n\nProvide the response in the same language of the webpage."; + } else { + $tmp .= "\n\nThe response must be in ". Languages::getName($this->settings->outputLanguage, 'en') ." language. Translate texts if needed."; + } + + return $tmp; } } diff --git a/src/Settings/InfoProviderSystem/AIExtractorSettings.php b/src/Settings/InfoProviderSystem/AIExtractorSettings.php index 876c687f..4ef9a1fa 100644 --- a/src/Settings/InfoProviderSystem/AIExtractorSettings.php +++ b/src/Settings/InfoProviderSystem/AIExtractorSettings.php @@ -32,7 +32,9 @@ use Jbtronics\SettingsBundle\Settings\Settings; use Jbtronics\SettingsBundle\Settings\SettingsParameter; use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\AI\Platform\Capability; +use Symfony\Component\Form\Extension\Core\Type\LanguageType; use Symfony\Component\Translation\TranslatableMessage as TM; +use Symfony\Component\Validator\Constraints\Language; #[Settings(name: "ai_extractor", label: new TM("settings.ips.ai_extractor"), description: new TM("settings.ips.ai_extractor.description"))] #[SettingsIcon("fa-plug")] @@ -56,4 +58,10 @@ class AIExtractorSettings description: new TM("settings.ips.ai_extractor.max_content_length.description"), )] public int $maxContentLength = 50000; + + #[Language] + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.output_language"), description: new TM("settings.ips.ai_extractor.output_language.description"), + formType: LanguageType::class, + )] + public ?string $outputLanguage = null; } diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index e16a6d69..c0bf8b60 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13103,5 +13103,29 @@ Buerklin-API Authentication server: The AI model that should be used for extraction. Must support structured output. + + + settings.ips.ai_extractor.max_content_length + Max. Website Content length + + + + + settings.ips.ai_extractor.max_content_length.description + The maximum number of characters of the website that are sent to the AI service. + + + + + settings.ips.ai_extractor.output_language + Output language + + + + + settings.ips.ai_extractor.output_language.description + By default, the providers returns information in the same language as the website. With that option you can ask the AI to translate it for you. Might only work with certain models. + + From ad096aa6ff89bdae1cd090e0cbbd0992d05152f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 23:15:29 +0200 Subject: [PATCH 16/36] Improved parameter extraction & extraction of other infos --- .../DTOJsonSchemaConverter.php | 26 ++++++++++++------- .../Providers/AIInfoExtractor.php | 7 +++-- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php index bfc41121..a61e7465 100644 --- a/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php +++ b/src/Services/InfoProviderSystem/DTOJsonSchemaConverter.php @@ -63,13 +63,19 @@ final class DTOJsonSchemaConverter 'type' => 'object', 'properties' => [ 'name' => ['type' => 'string'], - 'value' => ['type' => 'string'], - 'unit' => ['type' => ['string', 'null']], + 'symbol' => ['type' => ['string', 'null'], 'description' => 'An optional quantity symbol for the parameter in latex code, like R_1'], + 'value_typical' => ['type' => ['number', 'null'], 'description' => 'The typical value of the parameter. For example, for a resistor this could be 100 for a 100 Ohm resistor. Also used if only one numeric value is given. If used an unit should be given'], + 'value_min' => ['type' => ['number', 'null'], 'description' => 'If a range is given for the parameter, this is the minimum value. Null if no range is given.'], + 'value_max' => ['type' => ['number', 'null'], 'description' => 'If a range is given for the parameter, this is the maximum value. Null if not a range.'], + 'value_text' => ['type' => ['string', 'null'], 'description' => 'When a value is not numeric it can be put here as text. Only use if it does not fit in value_min, value_typical or value_max. E.g. "Yes", "Red", etc.'], + 'group' => ['type' => ['string', 'null'], 'description' => 'An optional group name for the parameter, e.g. "Electrical parameters", "Mechanical parameters" etc.'], + 'unit' => ['type' => ['string', 'null'], 'description' => 'The unit of the parameter values, e.g. kg, Ohm, V, etc.'], ], - 'required' => ['name', 'value'], + 'required' => ['name', 'value_typical', 'value_min', 'value_max', 'value_text'] ], ], 'datasheets' => [ + 'description' => 'A list of datasheets, manuals, or other technical documents related to the product. Not images, but actual documents, preferably PDFs.', 'type' => 'array', 'items' => [ 'type' => 'object', @@ -145,13 +151,15 @@ final class DTOJsonSchemaConverter $parameters = []; foreach ($data['parameters'] as $p) { if (!empty($p['name'])) { - $value = $p['value'] ?? ''; - $unit = $p['unit'] ?? null; - // Combine value and unit for parsing - $valueWithUnit = $unit ? $value . ' ' . $unit : $value; - $parameters[] = ParameterDTO::parseValueField( + $parameters[] = new ParameterDTO( name: $p['name'], - value: $valueWithUnit + value_text: $p['value_text'] ?? null, + value_typ: isset($p['value_typical']) && is_numeric($p['value_typical']) ? (float) $p['value_typical'] : null, + value_min: isset($p['value_min']) && is_numeric($p['value_min']) ? (float) $p['value_min'] : null, + value_max: isset($p['value_max']) && is_numeric($p['value_max']) ? (float) $p['value_max'] : null, + unit: $p['unit'] ?? null, + symbol: $p['symbol'] ?? null, + group: $p['group'] ?? null, ); } } diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 2032f634..379d97cc 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -217,13 +217,12 @@ Focus on the main content of the page, such as product descriptions, specificati Rules: - manufacturing_status: Use "active", "obsolete", "nrfnd" (not recommended for new designs), "discontinued", or null -- parameters: Extract technical specs like voltage, current, temperature, etc. +- parameters: Extract technical specs like voltage, current, temperature, etc. and put them into the fields according to the JSON schema. Include units if available. - prices: Extract pricing tiers with minimum_quantity, price, and currency code - URLs must be absolute (include https://...) - If information is not found, use null -- Return ONLY the JSON, no explanation text - -For parameters, combine name, value, and unit. The unit should be separate if possible. +- Try to avoid duplicating parameters, if the same parameter is mentioned multiple times, or if it is already used in another field. +- Include only the 1 to 3 most relevant images, such as the main product image or important diagrams. Ignore decorative images, logos, or icons. PROMPT; if ($this->settings->outputLanguage === null) { From 5edcc60d410628287dc9a73ffecb6065835fe54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 23:18:09 +0200 Subject: [PATCH 17/36] Randomize UserAgent and prevent access to private networks for AI extractor --- .../Providers/AIInfoExtractor.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 379d97cc..0c2f19d9 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace App\Services\InfoProviderSystem\Providers; use App\Exceptions\ProviderIDNotSupportedException; +use App\Helpers\RandomizeUseragentHttpClient; use App\Services\AI\AIPlatformRegistry; use App\Services\InfoProviderSystem\DTOJsonSchemaConverter; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; @@ -35,6 +36,7 @@ use League\HTMLToMarkdown\HtmlConverter; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; use Symfony\Component\DomCrawler\Crawler; +use Symfony\Component\HttpClient\NoPrivateNetworkHttpClient; use Symfony\Component\Intl\Languages; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -55,12 +57,12 @@ final class AIInfoExtractor implements InfoProviderInterface private readonly AIPlatformRegistry $AIPlatformRegistry, private readonly DTOJsonSchemaConverter $jsonSchemaConverter, ) { - $this->httpClient = $httpClient->withOptions([ - 'timeout' => 30, - 'headers' => [ - 'User-Agent' => 'Mozilla/5.0 (compatible; Part-DB AI-Extractor/1.0)', - ], - ]); + //Use NoPrivateNetworkHttpClient to prevent SSRF vulnerabilities, and RandomizeUseragentHttpClient to make it harder for servers to block us + $this->httpClient = (new RandomizeUseragentHttpClient(new NoPrivateNetworkHttpClient($httpClient)))->withOptions( + [ + 'timeout' => 15, + ] + ); } public function getProviderInfo(): array @@ -199,7 +201,7 @@ final class AIInfoExtractor implements InfoProviderInterface $result = $aiPlatform->invoke($this->settings->model ?? throw new \RuntimeException('No model selected'), $input, [ 'response_format' => [ 'type' => 'json_schema', - 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), + 'json_schema' => $this->jsonSchemaConverter->getJSONSchema(), ] ]); } catch (\Throwable $e) { From cf34de67729c28666b2c4e46a60064e543611379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 26 Apr 2026 23:24:51 +0200 Subject: [PATCH 18/36] Allow to pass additional instructions to the AI model --- .../InfoProviderSystem/Providers/AIInfoExtractor.php | 4 ++++ .../InfoProviderSystem/AIExtractorSettings.php | 6 ++++++ .../InfoProviderSystem/InfoProviderSettings.php | 5 +++-- translations/messages.en.xlf | 12 ++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index 0c2f19d9..ef7f05a5 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -233,6 +233,10 @@ PROMPT; $tmp .= "\n\nThe response must be in ". Languages::getName($this->settings->outputLanguage, 'en') ." language. Translate texts if needed."; } + if ($this->settings->additionalInstructions) { + $tmp .= "\n\nAdditional instructions:\n" . $this->settings->additionalInstructions; + } + return $tmp; } diff --git a/src/Settings/InfoProviderSystem/AIExtractorSettings.php b/src/Settings/InfoProviderSystem/AIExtractorSettings.php index 4ef9a1fa..da5ef0f9 100644 --- a/src/Settings/InfoProviderSystem/AIExtractorSettings.php +++ b/src/Settings/InfoProviderSystem/AIExtractorSettings.php @@ -33,6 +33,7 @@ use Jbtronics\SettingsBundle\Settings\SettingsParameter; use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\AI\Platform\Capability; use Symfony\Component\Form\Extension\Core\Type\LanguageType; +use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Translation\TranslatableMessage as TM; use Symfony\Component\Validator\Constraints\Language; @@ -64,4 +65,9 @@ class AIExtractorSettings formType: LanguageType::class, )] public ?string $outputLanguage = null; + + #[SettingsParameter(label: new TM("settings.ips.ai_extractor.additional_instructions"), description: new TM("settings.ips.ai_extractor.additional_instructions.description"), + formType: TextareaType::class, + )] + public ?string $additionalInstructions = null; } diff --git a/src/Settings/InfoProviderSystem/InfoProviderSettings.php b/src/Settings/InfoProviderSystem/InfoProviderSettings.php index be0fe746..3e2a27ef 100644 --- a/src/Settings/InfoProviderSystem/InfoProviderSettings.php +++ b/src/Settings/InfoProviderSystem/InfoProviderSettings.php @@ -40,6 +40,9 @@ class InfoProviderSettings #[EmbeddedSettings] public ?GenericWebProviderSettings $genericWebProvider = null; + #[EmbeddedSettings] + public ?AIExtractorSettings $aiExtractor = null; + #[EmbeddedSettings] public ?DigikeySettings $digikey = null; @@ -76,6 +79,4 @@ class InfoProviderSettings #[EmbeddedSettings] public ?CanopySettings $canopy = null; - #[EmbeddedSettings] - public ?AIExtractorSettings $aiExtractor = null; } diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index c0bf8b60..d2c4bc47 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13127,5 +13127,17 @@ Buerklin-API Authentication server: By default, the providers returns information in the same language as the website. With that option you can ask the AI to translate it for you. Might only work with certain models. + + + settings.ips.ai_extractor.additional_instructions + Additional instructions + + + + + settings.ips.ai_extractor.additional_instructions.description + The additional instructions will be appended to the system prompt. + + From 4f67f21b33a6c35f5950da76cc115457d6ee6639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Mon, 27 Apr 2026 22:37:05 +0200 Subject: [PATCH 19/36] Allow to pass options to info providers --- .../Providers/AIInfoExtractor.php | 4 +-- .../Providers/BatchInfoProviderInterface.php | 3 ++- .../Providers/BuerklinProvider.php | 25 +++++++++++-------- .../Providers/CanopyProvider.php | 4 +-- .../Providers/ConradProvider.php | 4 +-- .../Providers/DigikeyProvider.php | 4 +-- .../Providers/Element14Provider.php | 4 +-- .../Providers/EmptyProvider.php | 4 +-- .../Providers/GenericWebProvider.php | 2 +- .../Providers/InfoProviderInterface.php | 6 +++-- .../Providers/LCSCProvider.php | 9 ++++--- .../Providers/OEMSecretsProvider.php | 10 +++++--- .../Providers/OctopartProvider.php | 4 +-- .../Providers/PollinProvider.php | 4 +-- .../Providers/ReicheltProvider.php | 4 +-- .../Providers/TMEProvider.php | 4 +-- .../Providers/TestProvider.php | 6 ++--- 17 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php index ef7f05a5..bf1ce37c 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php @@ -86,7 +86,7 @@ final class AIInfoExtractor implements InfoProviderInterface return $this->settings->platform !== null && $this->settings->model !== null && $this->settings->model !== ''; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { try { return [ @@ -96,7 +96,7 @@ final class AIInfoExtractor implements InfoProviderInterface } } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { $url = $this->fixAndValidateURL($id); diff --git a/src/Services/InfoProviderSystem/Providers/BatchInfoProviderInterface.php b/src/Services/InfoProviderSystem/Providers/BatchInfoProviderInterface.php index 549f117a..cd918439 100644 --- a/src/Services/InfoProviderSystem/Providers/BatchInfoProviderInterface.php +++ b/src/Services/InfoProviderSystem/Providers/BatchInfoProviderInterface.php @@ -34,7 +34,8 @@ interface BatchInfoProviderInterface extends InfoProviderInterface * Search for multiple keywords in a single batch operation and return the results, ordered by the keywords. * This allows for a more efficient search compared to running multiple single searches. * @param string[] $keywords + * @param array $options An associative array of options which can be used to modify the search behavior. The supported options depend on the provider and should be documented in the provider's documentation. * @return array An associative array where the key is the keyword and the value is the search results for that keyword */ - public function searchByKeywordsBatch(array $keywords): array; + public function searchByKeywordsBatch(array $keywords, array $options = []): array; } diff --git a/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php b/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php index c2291107..e5017eb2 100644 --- a/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php +++ b/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php @@ -461,9 +461,11 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv } /** + * @param string $keyword + * @param array $options * @return PartDetailDTO[] */ - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $keyword = strtoupper(trim($keyword)); if ($keyword === '') { @@ -493,7 +495,7 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv } } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { // Detail endpoint is /products/{code}/ $response = $this->getProduct($id); @@ -588,10 +590,11 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv } /** - * @param string[] $keywords + * @param array $keywords + * @param array $options * @return array */ - public function searchByKeywordsBatch(array $keywords): array + public function searchByKeywordsBatch(array $keywords, array $options = []): array { /** @var array $results */ $results = []; @@ -643,27 +646,27 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv public function getIDFromURL(string $url): ?string { - //Inputs: - //https://www.buerklin.com/de/p/bkl-electronic/niedervoltsteckverbinder/072341-l/40F1332/ + //Inputs: + //https://www.buerklin.com/de/p/bkl-electronic/niedervoltsteckverbinder/072341-l/40F1332/ //https://www.buerklin.com/de/p/40F1332/ //https://www.buerklin.com/en/p/bkl-electronic/dc-connectors/072341-l/40F1332/ //https://www.buerklin.com/en/p/40F1332/ //The ID is the last part after the manufacturer/category/mpn segment and before the final slash //https://www.buerklin.com/de/p/bkl-electronic/niedervoltsteckverbinder/072341-l/40F1332/#download should also work - + $path = parse_url($url, PHP_URL_PATH); - + if (!$path) { return null; } - + // Ensure it's actually a product URL if (strpos($path, '/p/') === false) { return null; } - + $id = basename(rtrim($path, '/')); - + return $id !== '' && $id !== 'p' ? $id : null; } diff --git a/src/Services/InfoProviderSystem/Providers/CanopyProvider.php b/src/Services/InfoProviderSystem/Providers/CanopyProvider.php index 18864a49..d826c765 100644 --- a/src/Services/InfoProviderSystem/Providers/CanopyProvider.php +++ b/src/Services/InfoProviderSystem/Providers/CanopyProvider.php @@ -111,7 +111,7 @@ class CanopyProvider implements InfoProviderInterface return null; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $response = $this->httpClient->request('GET', self::SEARCH_API_URL, [ 'query' => [ @@ -177,7 +177,7 @@ class CanopyProvider implements InfoProviderInterface return new PurchaseInfoDTO(self::DISTRIBUTOR_NAME, order_number: $asin, prices: $priceDtos, product_url: $this->productPageFromASIN($asin)); } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { //Check that the id is a valid ASIN (10 characters, letters and numbers) if (!preg_match('/^[A-Z0-9]{10}$/', $id)) { diff --git a/src/Services/InfoProviderSystem/Providers/ConradProvider.php b/src/Services/InfoProviderSystem/Providers/ConradProvider.php index 39de1e23..2e6708be 100644 --- a/src/Services/InfoProviderSystem/Providers/ConradProvider.php +++ b/src/Services/InfoProviderSystem/Providers/ConradProvider.php @@ -88,7 +88,7 @@ readonly class ConradProvider implements InfoProviderInterface, URLHandlerInfoPr return null; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $url = $this->settings->shopID->getAPIRoot() . self::SEARCH_ENDPOINT . '/' . $this->settings->shopID->getDomainEnd() . '/' . $this->settings->shopID->getLanguage() @@ -279,7 +279,7 @@ readonly class ConradProvider implements InfoProviderInterface, URLHandlerInfoPr ); } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { $productInfoURL = $this->settings->shopID->getAPIRoot() . '/product/1/service/' . $this->settings->shopID->getShopID() . '/product/' . $id; diff --git a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php index d7eb6e4f..e7a62aa4 100644 --- a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php +++ b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php @@ -106,7 +106,7 @@ class DigikeyProvider implements InfoProviderInterface return $this->settings->clientId !== null && $this->settings->clientId !== '' && $this->authTokenManager->hasToken(self::OAUTH_APP_NAME); } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $request = [ 'Keywords' => $keyword, @@ -159,7 +159,7 @@ class DigikeyProvider implements InfoProviderInterface return $result; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { try { $response = $this->digikeyClient->request('GET', '/products/v4/search/' . urlencode($id) . '/productdetails', [ diff --git a/src/Services/InfoProviderSystem/Providers/Element14Provider.php b/src/Services/InfoProviderSystem/Providers/Element14Provider.php index 9ae45728..1d9e092c 100644 --- a/src/Services/InfoProviderSystem/Providers/Element14Provider.php +++ b/src/Services/InfoProviderSystem/Providers/Element14Provider.php @@ -282,12 +282,12 @@ class Element14Provider implements InfoProviderInterface, URLHandlerInfoProvider }; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { return $this->queryByTerm('any:' . $keyword); } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { $tmp = $this->queryByTerm('id:' . $id); if (count($tmp) === 0) { diff --git a/src/Services/InfoProviderSystem/Providers/EmptyProvider.php b/src/Services/InfoProviderSystem/Providers/EmptyProvider.php index e0de9772..915a118c 100644 --- a/src/Services/InfoProviderSystem/Providers/EmptyProvider.php +++ b/src/Services/InfoProviderSystem/Providers/EmptyProvider.php @@ -54,7 +54,7 @@ class EmptyProvider implements InfoProviderInterface return true; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { return [ @@ -69,7 +69,7 @@ class EmptyProvider implements InfoProviderInterface ]; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { throw new \RuntimeException('No part details available'); } diff --git a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php index 90268c9c..d428910d 100644 --- a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php +++ b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php @@ -87,7 +87,7 @@ class GenericWebProvider implements InfoProviderInterface return $this->settings->enabled; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $url = $this->fixAndValidateURL($keyword); diff --git a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php index 1f787559..feb3466f 100644 --- a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php +++ b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php @@ -61,16 +61,18 @@ interface InfoProviderInterface /** * Searches for a keyword and returns a list of search results * @param string $keyword The keyword to search for + * @param array $options An associative array of options for the search, which can be used to pass additional parameters to the provider (e.g. filters, pagination, etc.). The content of this array is provider specific and not defined by the interface * @return SearchResultDTO[] A list of search results */ - public function searchByKeyword(string $keyword): array; + public function searchByKeyword(string $keyword, array $options = []): array; /** * Returns detailed information about the part with the given id * @param string $id + * @param array $options An associative array of options for the search, which can be used to pass additional parameters to the provider (e.g. filters, pagination, etc.). The content of this array is provider specific and not defined by the interface * @return PartDetailDTO */ - public function getDetails(string $id): PartDetailDTO; + public function getDetails(string $id, array $options = []): PartDetailDTO; /** * A list of capabilities this provider supports (which kind of data it can provide). diff --git a/src/Services/InfoProviderSystem/Providers/LCSCProvider.php b/src/Services/InfoProviderSystem/Providers/LCSCProvider.php index 1b807eff..8bdd776e 100755 --- a/src/Services/InfoProviderSystem/Providers/LCSCProvider.php +++ b/src/Services/InfoProviderSystem/Providers/LCSCProvider.php @@ -349,17 +349,18 @@ class LCSCProvider implements BatchInfoProviderInterface, URLHandlerInfoProvider return $result; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { return $this->queryByTerm($keyword, true); // Use lightweight mode for search } /** * Batch search multiple keywords asynchronously (like JavaScript Promise.all) - * @param array $keywords Array of keywords to search + * @param array $keywords + * @param array $options * @return array Results indexed by keyword */ - public function searchByKeywordsBatch(array $keywords): array + public function searchByKeywordsBatch(array $keywords, array $options = []): array { if (empty($keywords)) { return []; @@ -428,7 +429,7 @@ class LCSCProvider implements BatchInfoProviderInterface, URLHandlerInfoProvider return $result; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { $tmp = $this->queryByTerm($id, false); if (count($tmp) === 0) { diff --git a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php index f7048a87..2c98e6e5 100644 --- a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php +++ b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php @@ -278,12 +278,13 @@ class OEMSecretsProvider implements InfoProviderInterface * and debugging with local JSON files. The results are processed, cached, and then sorted based * on the keyword and specified criteria. * - * @param string $keyword The part number to search for + * @param string $keyword + * @param array $options * @return array An array of processed product details, sorted by relevance and additional criteria. * * @throws \Exception If the JSON file used for debugging is not found or contains errors. */ - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { /* oemsecrets Part Search API 3.0.1 @@ -414,12 +415,13 @@ class OEMSecretsProvider implements InfoProviderInterface * found in the cache, they are returned. If not, an exception is thrown indicating that * the details could not be found. * - * @param string $id The unique identifier of the provider or part. + * @param string $id + * @param array $options * @return PartDetailDTO The detailed information about the part. * * @throws \Exception If no details are found for the given provider ID. */ - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { $cacheKey = $this->getCacheKey($id); $cacheItem = $this->partInfoCache->getItem($cacheKey); diff --git a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php index 1142f4ef..684e4ff0 100644 --- a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php +++ b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php @@ -326,7 +326,7 @@ class OctopartProvider implements InfoProviderInterface ); } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $graphQL = sprintf(<<<'GRAPHQL' query partSearch($keyword: String, $limit: Int, $currency: String!, $country: String!, $authorizedOnly: Boolean!) { @@ -367,7 +367,7 @@ class OctopartProvider implements InfoProviderInterface return $tmp; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { //Check if we have the part cached $cached = $this->getFromCache($id); diff --git a/src/Services/InfoProviderSystem/Providers/PollinProvider.php b/src/Services/InfoProviderSystem/Providers/PollinProvider.php index 6ac969d3..7acecc3a 100644 --- a/src/Services/InfoProviderSystem/Providers/PollinProvider.php +++ b/src/Services/InfoProviderSystem/Providers/PollinProvider.php @@ -66,7 +66,7 @@ class PollinProvider implements InfoProviderInterface, URLHandlerInfoProviderInt return $this->settings->enabled; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $response = $this->client->request('GET', 'https://www.pollin.de/search', [ 'query' => [ @@ -110,7 +110,7 @@ class PollinProvider implements InfoProviderInterface, URLHandlerInfoProviderInt }; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { //Ensure that $id is numeric if (!is_numeric($id)) { diff --git a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php index 81f0a449..9dfb099f 100644 --- a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php +++ b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php @@ -69,7 +69,7 @@ class ReicheltProvider implements InfoProviderInterface return $this->settings->enabled; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $response = $this->client->request('GET', sprintf($this->getBaseURL() . '/shop/search/%s', $keyword)); $html = $response->getContent(); @@ -108,7 +108,7 @@ class ReicheltProvider implements InfoProviderInterface return $results; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { //Check that the ID is a number if (!is_numeric($id)) { diff --git a/src/Services/InfoProviderSystem/Providers/TMEProvider.php b/src/Services/InfoProviderSystem/Providers/TMEProvider.php index 93222517..24ba0ea7 100644 --- a/src/Services/InfoProviderSystem/Providers/TMEProvider.php +++ b/src/Services/InfoProviderSystem/Providers/TMEProvider.php @@ -69,7 +69,7 @@ class TMEProvider implements InfoProviderInterface, URLHandlerInfoProviderInterf return $this->tmeClient->isUsable(); } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { $response = $this->tmeClient->makeRequest('Products/Search', [ 'Country' => $this->settings->country, @@ -99,7 +99,7 @@ class TMEProvider implements InfoProviderInterface, URLHandlerInfoProviderInterf return $result; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { $response = $this->tmeClient->makeRequest('Products/GetProducts', [ 'Country' => $this->settings->country, diff --git a/src/Services/InfoProviderSystem/Providers/TestProvider.php b/src/Services/InfoProviderSystem/Providers/TestProvider.php index 8b78c95a..42927abd 100644 --- a/src/Services/InfoProviderSystem/Providers/TestProvider.php +++ b/src/Services/InfoProviderSystem/Providers/TestProvider.php @@ -55,7 +55,7 @@ class TestProvider implements InfoProviderInterface return true; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { return [ new SearchResultDTO(provider_key: $this->getProviderKey(), provider_id: 'element1', name: 'Element 1', description: 'fd'), @@ -72,7 +72,7 @@ class TestProvider implements InfoProviderInterface ]; } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { return new PartDetailDTO( provider_key: $this->getProviderKey(), @@ -92,4 +92,4 @@ class TestProvider implements InfoProviderInterface ] ); } -} \ No newline at end of file +} From 4cbb167e5cb440239753ef5693cadfec18f0cf5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Fri, 1 May 2026 20:11:56 +0200 Subject: [PATCH 20/36] Fixed errors --- .../InfoProviderSystem/Providers/GenericWebProvider.php | 8 ++++++-- .../InfoProviderSystem/Providers/MouserProvider.php | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php index d428910d..23eee528 100644 --- a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php +++ b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php @@ -50,6 +50,8 @@ class GenericWebProvider implements InfoProviderInterface use FixAndValidateUrlTrait; + public const OPTION_CHECK_FOR_DELEGATION = 'check_for_delegation'; + public const DISTRIBUTOR_NAME = 'Website'; private readonly HttpClientInterface $httpClient; @@ -99,7 +101,7 @@ class GenericWebProvider implements InfoProviderInterface try { return [ - $this->getDetails($keyword, false) //We already tried delegation + $this->getDetails($keyword, [self::OPTION_CHECK_FOR_DELEGATION => false]) //We already tried delegation ]; } catch (ProviderIDNotSupportedException $e) { return []; } @@ -312,8 +314,10 @@ class GenericWebProvider implements InfoProviderInterface - public function getDetails(string $id, bool $check_for_delegation = true): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { + //We check for delegation by default + $check_for_delegation = $options[self::OPTION_CHECK_FOR_DELEGATION] ?? true; $url = $this->fixAndValidateURL($id); if ($check_for_delegation) { diff --git a/src/Services/InfoProviderSystem/Providers/MouserProvider.php b/src/Services/InfoProviderSystem/Providers/MouserProvider.php index 3171c994..49ca2d50 100644 --- a/src/Services/InfoProviderSystem/Providers/MouserProvider.php +++ b/src/Services/InfoProviderSystem/Providers/MouserProvider.php @@ -76,7 +76,7 @@ class MouserProvider implements InfoProviderInterface return $this->settings->apiKey !== '' && $this->settings->apiKey !== null; } - public function searchByKeyword(string $keyword): array + public function searchByKeyword(string $keyword, array $options = []): array { /* SearchByKeywordRequest description: @@ -144,7 +144,7 @@ class MouserProvider implements InfoProviderInterface return $this->responseToDTOArray($response); } - public function getDetails(string $id): PartDetailDTO + public function getDetails(string $id, array $options = []): PartDetailDTO { /* SearchByPartRequest description: From e576ded86bed61ee904c23b2f3a2bb65c9d64388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Fri, 1 May 2026 20:16:58 +0200 Subject: [PATCH 21/36] Updated composer dependencies and use upstream version for micrometa packag --- composer.json | 8 +- composer.lock | 685 +++++----- config/reference.php | 2944 +++++++++++++++++++++--------------------- 3 files changed, 1829 insertions(+), 1808 deletions(-) diff --git a/composer.json b/composer.json index c4b3cb59..b23ea92b 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "jbtronics/dompdf-font-loader-bundle": "^1.0.0", "jbtronics/settings-bundle": "^3.0.0", "jfcherng/php-diff": "^6.14", - "jkphl/micrometa": "dev-master", + "jkphl/micrometa": "^v3.4.0", "knpuniversity/oauth2-client-bundle": "^2.15", "league/commonmark": "^2.7", "league/csv": "^9.8.0", @@ -160,12 +160,6 @@ "App\\Tests\\": "tests/" } }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/jbtronics/micrometa" - } - ], "scripts": { "auto-scripts": { "cache:clear": "symfony-cmd", diff --git a/composer.lock b/composer.lock index 1963342f..52eb5562 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": "7c76e3af5fd042105a3208fdcb300a11", + "content-hash": "31a276e9a2b45a04facbe2d88f4a042f", "packages": [ { "name": "amphp/amp", @@ -977,16 +977,16 @@ }, { "name": "api-platform/doctrine-common", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/doctrine-common.git", - "reference": "0b0e9328e08f38ff381afd7cba68976ed1dc714a" + "reference": "2072247e3c8126d815f20324e7aaa97c2b5ee889" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/doctrine-common/zipball/0b0e9328e08f38ff381afd7cba68976ed1dc714a", - "reference": "0b0e9328e08f38ff381afd7cba68976ed1dc714a", + "url": "https://api.github.com/repos/api-platform/doctrine-common/zipball/2072247e3c8126d815f20324e7aaa97c2b5ee889", + "reference": "2072247e3c8126d815f20324e7aaa97c2b5ee889", "shasum": "" }, "require": { @@ -1004,7 +1004,7 @@ "doctrine/mongodb-odm": "^2.10", "doctrine/orm": "^2.17 || ^3.0", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/type-info": "^7.3 || ^8.0" }, "suggest": { @@ -1061,22 +1061,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/doctrine-common/tree/v4.3.3" + "source": "https://github.com/api-platform/doctrine-common/tree/v4.3.4" }, - "time": "2026-03-27T06:51:10+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/doctrine-orm", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/doctrine-orm.git", - "reference": "553f7fe120c840a8db08d8e970860e209f40ebc2" + "reference": "3dc88ee48ffcdb6eee45ec1d3e9f25ea2aad4eaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/doctrine-orm/zipball/553f7fe120c840a8db08d8e970860e209f40ebc2", - "reference": "553f7fe120c840a8db08d8e970860e209f40ebc2", + "url": "https://api.github.com/repos/api-platform/doctrine-orm/zipball/3dc88ee48ffcdb6eee45ec1d3e9f25ea2aad4eaa", + "reference": "3dc88ee48ffcdb6eee45ec1d3e9f25ea2aad4eaa", "shasum": "" }, "require": { @@ -1091,7 +1091,7 @@ "require-dev": { "doctrine/doctrine-bundle": "^2.11 || ^3.1", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "ramsey/uuid": "^4.7", "ramsey/uuid-doctrine": "^2.0", "symfony/cache": "^6.4 || ^7.0 || ^8.0", @@ -1150,22 +1150,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/doctrine-orm/tree/v4.3.3" + "source": "https://github.com/api-platform/doctrine-orm/tree/v4.3.4" }, - "time": "2026-03-27T06:51:10+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/documentation", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/documentation.git", - "reference": "a63a3a7f020b6a001b1228c5bd916e1a76887d1d" + "reference": "f07b444aef1f75bb07beb9f8d799213f05070e5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/documentation/zipball/a63a3a7f020b6a001b1228c5bd916e1a76887d1d", - "reference": "a63a3a7f020b6a001b1228c5bd916e1a76887d1d", + "url": "https://api.github.com/repos/api-platform/documentation/zipball/f07b444aef1f75bb07beb9f8d799213f05070e5f", + "reference": "f07b444aef1f75bb07beb9f8d799213f05070e5f", "shasum": "" }, "require": { @@ -1173,7 +1173,7 @@ "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^12.2" + "phpunit/phpunit": "^11.5 || ^12.2" }, "type": "project", "extra": { @@ -1213,22 +1213,22 @@ ], "description": "API Platform documentation controller.", "support": { - "source": "https://github.com/api-platform/documentation/tree/v4.3.3" + "source": "https://github.com/api-platform/documentation/tree/v4.3.4" }, - "time": "2026-03-06T15:07:49+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/http-cache", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/http-cache.git", - "reference": "9ffbe58f8872932ed7c2afca8207c2d68629e037" + "reference": "dd7c092b9abee06e72fd58544fe714b6c2a61efa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/http-cache/zipball/9ffbe58f8872932ed7c2afca8207c2d68629e037", - "reference": "9ffbe58f8872932ed7c2afca8207c2d68629e037", + "url": "https://api.github.com/repos/api-platform/http-cache/zipball/dd7c092b9abee06e72fd58544fe714b6c2a61efa", + "reference": "dd7c092b9abee06e72fd58544fe714b6c2a61efa", "shasum": "" }, "require": { @@ -1240,7 +1240,7 @@ "require-dev": { "guzzlehttp/guzzle": "^6.0 || ^7.0 || ^8.0", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/dependency-injection": "^6.4 || ^7.0 || ^8.0", "symfony/http-client": "^6.4 || ^7.0 || ^8.0", "symfony/type-info": "^7.3 || ^8.0" @@ -1293,22 +1293,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/http-cache/tree/v4.3.3" + "source": "https://github.com/api-platform/http-cache/tree/v4.3.4" }, - "time": "2026-03-06T15:07:49+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/hydra", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/hydra.git", - "reference": "bb9f7107a0bbfbe6e7b93130bde9829f0cc71529" + "reference": "9b0a677b21ee4f2ec255386a84bdcf1d12ea7bc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/hydra/zipball/bb9f7107a0bbfbe6e7b93130bde9829f0cc71529", - "reference": "bb9f7107a0bbfbe6e7b93130bde9829f0cc71529", + "url": "https://api.github.com/repos/api-platform/hydra/zipball/9b0a677b21ee4f2ec255386a84bdcf1d12ea7bc4", + "reference": "9b0a677b21ee4f2ec255386a84bdcf1d12ea7bc4", "shasum": "" }, "require": { @@ -1328,7 +1328,7 @@ "api-platform/doctrine-orm": "^4.3", "phpspec/prophecy": "^1.19", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2" + "phpunit/phpunit": "^11.5 || ^12.2" }, "type": "library", "extra": { @@ -1380,22 +1380,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/hydra/tree/v4.3.3" + "source": "https://github.com/api-platform/hydra/tree/v4.3.4" }, - "time": "2026-03-20T09:00:10+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/json-api", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/json-api.git", - "reference": "64bf11cbcaaf5cba3f6fceb243ed57d1ed6e2827" + "reference": "30e399ea2266403d04fd93df83c6983cf0a30e5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/json-api/zipball/64bf11cbcaaf5cba3f6fceb243ed57d1ed6e2827", - "reference": "64bf11cbcaaf5cba3f6fceb243ed57d1ed6e2827", + "url": "https://api.github.com/repos/api-platform/json-api/zipball/30e399ea2266403d04fd93df83c6983cf0a30e5d", + "reference": "30e399ea2266403d04fd93df83c6983cf0a30e5d", "shasum": "" }, "require": { @@ -1412,7 +1412,7 @@ "require-dev": { "phpspec/prophecy": "^1.19", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/type-info": "^7.3 || ^8.0" }, "type": "library", @@ -1462,22 +1462,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/json-api/tree/v4.3.3" + "source": "https://github.com/api-platform/json-api/tree/v4.3.4" }, - "time": "2026-03-13T11:03:46+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/json-schema", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/json-schema.git", - "reference": "0f66e93719fd65938528aeff900737471acb515a" + "reference": "23dc2c388a08f2006b9189a0883a08f8837d7249" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/json-schema/zipball/0f66e93719fd65938528aeff900737471acb515a", - "reference": "0f66e93719fd65938528aeff900737471acb515a", + "url": "https://api.github.com/repos/api-platform/json-schema/zipball/23dc2c388a08f2006b9189a0883a08f8837d7249", + "reference": "23dc2c388a08f2006b9189a0883a08f8837d7249", "shasum": "" }, "require": { @@ -1491,7 +1491,7 @@ }, "require-dev": { "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2" + "phpunit/phpunit": "^11.5 || ^12.2" }, "type": "library", "extra": { @@ -1543,22 +1543,22 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/json-schema/tree/v4.3.3" + "source": "https://github.com/api-platform/json-schema/tree/v4.3.4" }, - "time": "2026-03-06T15:07:49+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/jsonld", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/jsonld.git", - "reference": "64bd84ac44d6c6c51142a26bfa7d4c6237d20593" + "reference": "20ca6d7b5c11674c3046d710aaa0c9bc1795e54b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/jsonld/zipball/64bd84ac44d6c6c51142a26bfa7d4c6237d20593", - "reference": "64bd84ac44d6c6c51142a26bfa7d4c6237d20593", + "url": "https://api.github.com/repos/api-platform/jsonld/zipball/20ca6d7b5c11674c3046d710aaa0c9bc1795e54b", + "reference": "20ca6d7b5c11674c3046d710aaa0c9bc1795e54b", "shasum": "" }, "require": { @@ -1568,7 +1568,7 @@ "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/type-info": "^7.3 || ^8.0" }, "type": "library", @@ -1623,22 +1623,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/jsonld/tree/v4.3.3" + "source": "https://github.com/api-platform/jsonld/tree/v4.3.4" }, - "time": "2026-03-13T08:23:46+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/metadata", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/metadata.git", - "reference": "e5d54902ad9817f1734ef39fe5b34d3c9b505f27" + "reference": "e93caa26e7992ca138f2d12f79b5b25d2d091b7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/metadata/zipball/e5d54902ad9817f1734ef39fe5b34d3c9b505f27", - "reference": "e5d54902ad9817f1734ef39fe5b34d3c9b505f27", + "url": "https://api.github.com/repos/api-platform/metadata/zipball/e93caa26e7992ca138f2d12f79b5b25d2d091b7b", + "reference": "e93caa26e7992ca138f2d12f79b5b25d2d091b7b", "shasum": "" }, "require": { @@ -1656,7 +1656,7 @@ "api-platform/state": "^4.3", "phpspec/prophecy-phpunit": "^2.2", "phpstan/phpdoc-parser": "^1.29 || ^2.0", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/config": "^6.4 || ^7.0 || ^8.0", "symfony/routing": "^6.4 || ^7.0 || ^8.0", "symfony/var-dumper": "^6.4 || ^7.0 || ^8.0", @@ -1721,22 +1721,22 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/metadata/tree/v4.3.3" + "source": "https://github.com/api-platform/metadata/tree/v4.3.4" }, - "time": "2026-03-27T06:51:10+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/openapi", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/openapi.git", - "reference": "6ae725b4d2cee60972c18c4bd6148b63ccf16785" + "reference": "1562617e7500a50c2b6e6f43a0fb29a6a47e83a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/openapi/zipball/6ae725b4d2cee60972c18c4bd6148b63ccf16785", - "reference": "6ae725b4d2cee60972c18c4bd6148b63ccf16785", + "url": "https://api.github.com/repos/api-platform/openapi/zipball/1562617e7500a50c2b6e6f43a0fb29a6a47e83a2", + "reference": "1562617e7500a50c2b6e6f43a0fb29a6a47e83a2", "shasum": "" }, "require": { @@ -1756,7 +1756,7 @@ "api-platform/doctrine-orm": "^4.3", "api-platform/serializer": "^4.3", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/type-info": "^7.3 || ^8.0" }, "type": "library", @@ -1812,22 +1812,22 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/openapi/tree/v4.3.3" + "source": "https://github.com/api-platform/openapi/tree/v4.3.4" }, - "time": "2026-03-29T07:20:23+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/serializer", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/serializer.git", - "reference": "c8a62096d277b89b0f146aa90c65eeaeb1412900" + "reference": "bd7c26cc8e6858abc9661d677c15eaf4c61e08e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/serializer/zipball/c8a62096d277b89b0f146aa90c65eeaeb1412900", - "reference": "c8a62096d277b89b0f146aa90c65eeaeb1412900", + "url": "https://api.github.com/repos/api-platform/serializer/zipball/bd7c26cc8e6858abc9661d677c15eaf4c61e08e3", + "reference": "bd7c26cc8e6858abc9661d677c15eaf4c61e08e3", "shasum": "" }, "require": { @@ -1847,7 +1847,7 @@ "api-platform/openapi": "^4.3", "doctrine/collections": "^2.1", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "sebastian/exporter": "^6.3.2 || ^7.0.2", "symfony/mercure-bundle": "*", "symfony/type-info": "^7.3 || ^8.0", @@ -1906,22 +1906,22 @@ "serializer" ], "support": { - "source": "https://github.com/api-platform/serializer/tree/v4.3.3" + "source": "https://github.com/api-platform/serializer/tree/v4.3.4" }, - "time": "2026-03-27T06:51:10+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/state", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/state.git", - "reference": "5387afbb9e79027b34dab731bc90e810fdd6ca60" + "reference": "dda8789e95b1627a6427edb48f9024b306fdf5ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/state/zipball/5387afbb9e79027b34dab731bc90e810fdd6ca60", - "reference": "5387afbb9e79027b34dab731bc90e810fdd6ca60", + "url": "https://api.github.com/repos/api-platform/state/zipball/dda8789e95b1627a6427edb48f9024b306fdf5ff", + "reference": "dda8789e95b1627a6427edb48f9024b306fdf5ff", "shasum": "" }, "require": { @@ -1936,7 +1936,7 @@ "require-dev": { "api-platform/serializer": "^4.3", "api-platform/validator": "^4.3.1", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/http-foundation": "^6.4.14 || ^7.0 || ^8.0", "symfony/object-mapper": "^7.4 || ^8.0", "symfony/type-info": "^7.4 || ^8.0", @@ -2003,22 +2003,22 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/state/tree/v4.3.3" + "source": "https://github.com/api-platform/state/tree/v4.3.4" }, - "time": "2026-03-29T06:54:13+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/symfony", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/symfony.git", - "reference": "69070b33f11ed7c163ba75ecfea192e460b89ce0" + "reference": "532063884e3f91a8a831322a572220cc55501a2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/symfony/zipball/69070b33f11ed7c163ba75ecfea192e460b89ce0", - "reference": "69070b33f11ed7c163ba75ecfea192e460b89ce0", + "url": "https://api.github.com/repos/api-platform/symfony/zipball/532063884e3f91a8a831322a572220cc55501a2f", + "reference": "532063884e3f91a8a831322a572220cc55501a2f", "shasum": "" }, "require": { @@ -2049,7 +2049,7 @@ "api-platform/graphql": "^4.3", "api-platform/hal": "^4.3", "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2", + "phpunit/phpunit": "^11.5 || ^12.2", "symfony/expression-language": "^6.4 || ^7.0 || ^8.0", "symfony/intl": "^6.4 || ^7.0 || ^8.0", "symfony/mercure-bundle": "*", @@ -2131,22 +2131,22 @@ "symfony" ], "support": { - "source": "https://github.com/api-platform/symfony/tree/v4.3.3" + "source": "https://github.com/api-platform/symfony/tree/v4.3.4" }, - "time": "2026-03-27T06:51:10+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "api-platform/validator", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/api-platform/validator.git", - "reference": "3c0d486a12d7ab9b8fcfb727437b5322dc619663" + "reference": "22693bc3d3538af700cf274b99c834c37b1d1a68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/validator/zipball/3c0d486a12d7ab9b8fcfb727437b5322dc619663", - "reference": "3c0d486a12d7ab9b8fcfb727437b5322dc619663", + "url": "https://api.github.com/repos/api-platform/validator/zipball/22693bc3d3538af700cf274b99c834c37b1d1a68", + "reference": "22693bc3d3538af700cf274b99c834c37b1d1a68", "shasum": "" }, "require": { @@ -2160,7 +2160,7 @@ }, "require-dev": { "phpspec/prophecy-phpunit": "^2.2", - "phpunit/phpunit": "^12.2" + "phpunit/phpunit": "^11.5 || ^12.2" }, "type": "library", "extra": { @@ -2207,9 +2207,9 @@ "validator" ], "support": { - "source": "https://github.com/api-platform/validator/tree/v4.3.3" + "source": "https://github.com/api-platform/validator/tree/v4.3.4" }, - "time": "2026-03-17T15:23:21+00:00" + "time": "2026-04-30T12:21:24+00:00" }, { "name": "beberlei/assert", @@ -5202,16 +5202,16 @@ }, { "name": "jbtronics/settings-bundle", - "version": "v3.3.0", + "version": "v3.3.1", "source": { "type": "git", "url": "https://github.com/jbtronics/settings-bundle.git", - "reference": "9cce001eef4570ca3b2766da6a8a4abd327ea438" + "reference": "ca90a8b2255482d11f10cb30c49791a7dabd5d40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jbtronics/settings-bundle/zipball/9cce001eef4570ca3b2766da6a8a4abd327ea438", - "reference": "9cce001eef4570ca3b2766da6a8a4abd327ea438", + "url": "https://api.github.com/repos/jbtronics/settings-bundle/zipball/ca90a8b2255482d11f10cb30c49791a7dabd5d40", + "reference": "ca90a8b2255482d11f10cb30c49791a7dabd5d40", "shasum": "" }, "require": { @@ -5284,7 +5284,7 @@ ], "support": { "issues": "https://github.com/jbtronics/settings-bundle/issues", - "source": "https://github.com/jbtronics/settings-bundle/tree/v3.3.0" + "source": "https://github.com/jbtronics/settings-bundle/tree/v3.3.1" }, "funding": [ { @@ -5296,7 +5296,7 @@ "type": "github" } ], - "time": "2026-04-21T21:26:26+00:00" + "time": "2026-04-28T10:57:15+00:00" }, { "name": "jfcherng/php-color-output", @@ -5592,16 +5592,16 @@ }, { "name": "jkphl/micrometa", - "version": "dev-master", + "version": "v3.4.0", "source": { "type": "git", - "url": "https://github.com/jbtronics/micrometa.git", - "reference": "720f409151c2cc20add9478b7a0a635fa1707021" + "url": "https://github.com/jkphl/micrometa.git", + "reference": "003583fa91eab9c62e5a47e9d4f909b2fad44de2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jbtronics/micrometa/zipball/720f409151c2cc20add9478b7a0a635fa1707021", - "reference": "720f409151c2cc20add9478b7a0a635fa1707021", + "url": "https://api.github.com/repos/jkphl/micrometa/zipball/003583fa91eab9c62e5a47e9d4f909b2fad44de2", + "reference": "003583fa91eab9c62e5a47e9d4f909b2fad44de2", "shasum": "" }, "require": { @@ -5624,30 +5624,13 @@ "phpunit/phpunit": "^7.0 || ^8.5", "squizlabs/php_codesniffer": "^3.3" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { "Jkphl\\": "src/" } }, - "scripts": { - "phpunit": [ - "vendor/bin/phpunit --configuration phpunit.xml.dist" - ], - "depgraph": [ - "vendor/bin/graph-composer --no-dev export . doc/dependencies.svg" - ], - "check-style": [ - "vendor/bin/phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src" - ], - "fix-style": [ - "vendor/bin/phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src" - ], - "test": [ - "@phpunit" - ] - }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -5663,10 +5646,10 @@ "homepage": "https://jkphl.is/projects/micrometa/", "support": { "email": "joschi@tollwerk.de", - "source": "https://github.com/jkphl/micrometa", - "issues": "https://github.com/jkphl/micrometa/issues" + "issues": "https://github.com/jkphl/micrometa/issues", + "source": "https://github.com/jkphl/micrometa" }, - "time": "2026-04-26T17:25:19+00:00" + "time": "2026-04-28T07:20:59+00:00" }, { "name": "jkphl/rdfa-lite-microdata", @@ -8848,16 +8831,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.7", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903" + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { @@ -8865,8 +8848,8 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { @@ -8876,7 +8859,8 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, "type": "library", "extra": { @@ -8906,44 +8890,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, - "time": "2026-03-18T20:47:46+00:00" + "time": "2026-03-18T20:49:53+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.12.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -8964,9 +8948,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, - "time": "2025-11-21T15:09:14+00:00" + "time": "2026-01-06T21:53:42+00:00" }, { "name": "phpoffice/phpspreadsheet", @@ -10089,29 +10073,29 @@ }, { "name": "sabre/uri", - "version": "3.0.3", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sabre-io/uri.git", - "reference": "4fa0b2049e06a4fbe4aea4f0aa69e7b8410a13bc" + "reference": "a926c749dddfb289b8a9b5218d16ac06affdc631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/uri/zipball/4fa0b2049e06a4fbe4aea4f0aa69e7b8410a13bc", - "reference": "4fa0b2049e06a4fbe4aea4f0aa69e7b8410a13bc", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/a926c749dddfb289b8a9b5218d16ac06affdc631", + "reference": "a926c749dddfb289b8a9b5218d16ac06affdc631", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": "^8.2" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.94", + "friendsofphp/php-cs-fixer": "^3.95", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6", - "rector/rector": "^2.3" + "phpunit/phpunit": "^10.5", + "rector/rector": "^2.4" }, "type": "library", "autoload": { @@ -10146,7 +10130,7 @@ "issues": "https://github.com/sabre-io/uri/issues", "source": "https://github.com/fruux/sabre-uri" }, - "time": "2026-04-01T08:19:11+00:00" + "time": "2026-04-26T04:19:03+00:00" }, { "name": "scheb/2fa-backup-code", @@ -11390,16 +11374,16 @@ }, { "name": "symfony/cache", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "467464da294734b0fb17e853e5712abc8470f819" + "reference": "3860fa12a5013b48d445909c6ea07f870e10ba7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/467464da294734b0fb17e853e5712abc8470f819", - "reference": "467464da294734b0fb17e853e5712abc8470f819", + "url": "https://api.github.com/repos/symfony/cache/zipball/3860fa12a5013b48d445909c6ea07f870e10ba7c", + "reference": "3860fa12a5013b48d445909c6ea07f870e10ba7c", "shasum": "" }, "require": { @@ -11470,7 +11454,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.4.8" + "source": "https://github.com/symfony/cache/tree/v7.4.9" }, "funding": [ { @@ -11490,7 +11474,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:15:47+00:00" + "time": "2026-04-29T13:21:53+00:00" }, { "name": "symfony/cache-contracts", @@ -11648,16 +11632,16 @@ }, { "name": "symfony/config", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b" + "reference": "d4a277b7a0f26487db16b264d935c617b7d994ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/2d19dde43fa2ff720b9a40763ace7226594f503b", - "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b", + "url": "https://api.github.com/repos/symfony/config/zipball/d4a277b7a0f26487db16b264d935c617b7d994ea", + "reference": "d4a277b7a0f26487db16b264d935c617b7d994ea", "shasum": "" }, "require": { @@ -11703,7 +11687,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.4.8" + "source": "https://github.com/symfony/config/tree/v7.4.9" }, "funding": [ { @@ -11723,20 +11707,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-29T14:25:20+00:00" }, { "name": "symfony/console", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707" + "reference": "d7d2b64a45a89d607865927b176fa51c33ddbb58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", - "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", + "url": "https://api.github.com/repos/symfony/console/zipball/d7d2b64a45a89d607865927b176fa51c33ddbb58", + "reference": "d7d2b64a45a89d607865927b176fa51c33ddbb58", "shasum": "" }, "require": { @@ -11801,7 +11785,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.8" + "source": "https://github.com/symfony/console/tree/v7.4.9" }, "funding": [ { @@ -11821,20 +11805,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T13:54:39+00:00" + "time": "2026-04-22T15:21:55+00:00" }, { "name": "symfony/css-selector", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "b055f228a4178a1d6774909903905e3475f3eac8" + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b055f228a4178a1d6774909903905e3475f3eac8", - "reference": "b055f228a4178a1d6774909903905e3475f3eac8", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4", + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4", "shasum": "" }, "require": { @@ -11870,7 +11854,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.4.8" + "source": "https://github.com/symfony/css-selector/tree/v7.4.9" }, "funding": [ { @@ -11890,20 +11874,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f7025fd7b687c240426562f86ada06a93b1e771d" + "reference": "27cd9f912438d07ced76008bc66cf8b0cf4de622" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7025fd7b687c240426562f86ada06a93b1e771d", - "reference": "f7025fd7b687c240426562f86ada06a93b1e771d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/27cd9f912438d07ced76008bc66cf8b0cf4de622", + "reference": "27cd9f912438d07ced76008bc66cf8b0cf4de622", "shasum": "" }, "require": { @@ -11954,7 +11938,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.8" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.9" }, "funding": [ { @@ -11974,7 +11958,7 @@ "type": "tidelift" } ], - "time": "2026-03-31T06:50:29+00:00" + "time": "2026-04-30T18:38:49+00:00" }, { "name": "symfony/deprecation-contracts", @@ -12045,16 +12029,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "3f8f805e54ecb5cbd487b1eff8837a8bbd278669" + "reference": "7a87c85853f3069e3657a823c62b02952de46b0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/3f8f805e54ecb5cbd487b1eff8837a8bbd278669", - "reference": "3f8f805e54ecb5cbd487b1eff8837a8bbd278669", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/7a87c85853f3069e3657a823c62b02952de46b0a", + "reference": "7a87c85853f3069e3657a823c62b02952de46b0a", "shasum": "" }, "require": { @@ -12134,7 +12118,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.4.8" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.4.9" }, "funding": [ { @@ -12154,7 +12138,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-29T14:19:39+00:00" }, { "name": "symfony/dom-crawler", @@ -12230,16 +12214,16 @@ }, { "name": "symfony/dotenv", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "5df79f11350166125fe754c85b87f7e13d735314" + "reference": "ba757a8564a0ccac1a26a859b83295645020ea68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/5df79f11350166125fe754c85b87f7e13d735314", - "reference": "5df79f11350166125fe754c85b87f7e13d735314", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/ba757a8564a0ccac1a26a859b83295645020ea68", + "reference": "ba757a8564a0ccac1a26a859b83295645020ea68", "shasum": "" }, "require": { @@ -12284,7 +12268,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v7.4.8" + "source": "https://github.com/symfony/dotenv/tree/v7.4.9" }, "funding": [ { @@ -12304,7 +12288,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T12:55:43+00:00" + "time": "2026-04-29T13:21:53+00:00" }, { "name": "symfony/error-handler", @@ -12390,16 +12374,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f57b899fa736fd71121168ef268f23c206083f0a" + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f57b899fa736fd71121168ef268f23c206083f0a", - "reference": "f57b899fa736fd71121168ef268f23c206083f0a", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101", "shasum": "" }, "require": { @@ -12451,7 +12435,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.8" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.9" }, "funding": [ { @@ -12471,7 +12455,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T13:54:39+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -12619,16 +12603,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5" + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/58b9790d12f9670b7f53a1c1738febd3108970a5", - "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dcd8f96bcdc0f128ec406c765cc066c6035d1be3", + "reference": "dcd8f96bcdc0f128ec406c765cc066c6035d1be3", "shasum": "" }, "require": { @@ -12665,7 +12649,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.8" + "source": "https://github.com/symfony/filesystem/tree/v7.4.9" }, "funding": [ { @@ -12685,7 +12669,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/finder", @@ -12830,16 +12814,16 @@ }, { "name": "symfony/form", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "fbb79fc4de32f091ec697276824331f5de3a87b4" + "reference": "b6c107af659106abec1771d9d7d22da528644d3a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/fbb79fc4de32f091ec697276824331f5de3a87b4", - "reference": "fbb79fc4de32f091ec697276824331f5de3a87b4", + "url": "https://api.github.com/repos/symfony/form/zipball/b6c107af659106abec1771d9d7d22da528644d3a", + "reference": "b6c107af659106abec1771d9d7d22da528644d3a", "shasum": "" }, "require": { @@ -12909,7 +12893,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v7.4.8" + "source": "https://github.com/symfony/form/tree/v7.4.9" }, "funding": [ { @@ -12929,20 +12913,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-29T14:39:19+00:00" }, { "name": "symfony/framework-bundle", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "180533cfbac2144349044267db31d5d3df9957cb" + "reference": "601423cc0af2eb5e8c4acdf21fed553d456ff802" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/180533cfbac2144349044267db31d5d3df9957cb", - "reference": "180533cfbac2144349044267db31d5d3df9957cb", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/601423cc0af2eb5e8c4acdf21fed553d456ff802", + "reference": "601423cc0af2eb5e8c4acdf21fed553d456ff802", "shasum": "" }, "require": { @@ -12978,7 +12962,7 @@ "symfony/lock": "<6.4", "symfony/mailer": "<6.4", "symfony/messenger": "<7.4", - "symfony/mime": "<6.4", + "symfony/mime": "<6.4.37|>=7.0,<7.4.9|>=8.0,<8.0.9", "symfony/property-access": "<6.4", "symfony/property-info": "<6.4", "symfony/runtime": "<6.4.13|>=7.0,<7.1.6", @@ -13016,7 +13000,7 @@ "symfony/lock": "^6.4|^7.0|^8.0", "symfony/mailer": "^6.4|^7.0|^8.0", "symfony/messenger": "^7.4|^8.0", - "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/mime": "^6.4.37|^7.4.9|^8.0.9", "symfony/notifier": "^6.4|^7.0|^8.0", "symfony/object-mapper": "^7.3|^8.0", "symfony/polyfill-intl-icu": "~1.0", @@ -13067,7 +13051,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v7.4.8" + "source": "https://github.com/symfony/framework-bundle/tree/v7.4.9" }, "funding": [ { @@ -13087,20 +13071,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T12:55:43+00:00" + "time": "2026-04-30T08:57:13+00:00" }, { "name": "symfony/http-client", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "01933e626c3de76bea1e22641e205e78f6a34342" + "reference": "7e941c6abf4e3bf7dca160bf0e11ef36a9f832f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/01933e626c3de76bea1e22641e205e78f6a34342", - "reference": "01933e626c3de76bea1e22641e205e78f6a34342", + "url": "https://api.github.com/repos/symfony/http-client/zipball/7e941c6abf4e3bf7dca160bf0e11ef36a9f832f6", + "reference": "7e941c6abf4e3bf7dca160bf0e11ef36a9f832f6", "shasum": "" }, "require": { @@ -13168,7 +13152,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.4.8" + "source": "https://github.com/symfony/http-client/tree/v7.4.9" }, "funding": [ { @@ -13188,7 +13172,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T12:55:43+00:00" + "time": "2026-04-29T13:25:15+00:00" }, { "name": "symfony/http-client-contracts", @@ -13645,16 +13629,16 @@ }, { "name": "symfony/mime", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "6df02f99998081032da3407a8d6c4e1dcb5d4379" + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/6df02f99998081032da3407a8d6c4e1dcb5d4379", - "reference": "6df02f99998081032da3407a8d6c4e1dcb5d4379", + "url": "https://api.github.com/repos/symfony/mime/zipball/2d550c4758ba4c47519a6667c36553d535705b0c", + "reference": "2d550c4758ba4c47519a6667c36553d535705b0c", "shasum": "" }, "require": { @@ -13710,7 +13694,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.4.8" + "source": "https://github.com/symfony/mime/tree/v7.4.9" }, "funding": [ { @@ -13730,20 +13714,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T14:11:46+00:00" + "time": "2026-04-29T13:21:53+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "b52aeb44645a9a84a1795b973cc5c77a76df0720" + "reference": "20366bceee51838144a14805204bb792cb3d09f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/b52aeb44645a9a84a1795b973cc5c77a76df0720", - "reference": "b52aeb44645a9a84a1795b973cc5c77a76df0720", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/20366bceee51838144a14805204bb792cb3d09f2", + "reference": "20366bceee51838144a14805204bb792cb3d09f2", "shasum": "" }, "require": { @@ -13793,7 +13777,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v7.4.8" + "source": "https://github.com/symfony/monolog-bridge/tree/v7.4.9" }, "funding": [ { @@ -13813,7 +13797,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T13:54:39+00:00" + "time": "2026-04-29T13:21:53+00:00" }, { "name": "symfony/monolog-bundle", @@ -15115,16 +15099,16 @@ }, { "name": "symfony/rate-limiter", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "d55de9ec479418f58464e122e68d33886cf6f1fb" + "reference": "0b0078d29f6e64b8833492e9f76a853f23fb1a81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/d55de9ec479418f58464e122e68d33886cf6f1fb", - "reference": "d55de9ec479418f58464e122e68d33886cf6f1fb", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/0b0078d29f6e64b8833492e9f76a853f23fb1a81", + "reference": "0b0078d29f6e64b8833492e9f76a853f23fb1a81", "shasum": "" }, "require": { @@ -15165,7 +15149,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v7.4.8" + "source": "https://github.com/symfony/rate-limiter/tree/v7.4.9" }, "funding": [ { @@ -15185,20 +15169,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-29T13:21:53+00:00" }, { "name": "symfony/routing", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "9608de9873ec86e754fb6c0a0fa7e5f1a960eb6b" + "reference": "287771d8bc86eacb30678dd10eda6c64a859951f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/9608de9873ec86e754fb6c0a0fa7e5f1a960eb6b", - "reference": "9608de9873ec86e754fb6c0a0fa7e5f1a960eb6b", + "url": "https://api.github.com/repos/symfony/routing/zipball/287771d8bc86eacb30678dd10eda6c64a859951f", + "reference": "287771d8bc86eacb30678dd10eda6c64a859951f", "shasum": "" }, "require": { @@ -15250,7 +15234,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.4.8" + "source": "https://github.com/symfony/routing/tree/v7.4.9" }, "funding": [ { @@ -15270,7 +15254,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-22T15:21:55+00:00" }, { "name": "symfony/runtime", @@ -15634,16 +15618,16 @@ }, { "name": "symfony/security-http", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "1b07d7d472ba967fd66697067e6274084d2d1d7c" + "reference": "a34991b13899de1f953df245395aa2196f9bc113" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/1b07d7d472ba967fd66697067e6274084d2d1d7c", - "reference": "1b07d7d472ba967fd66697067e6274084d2d1d7c", + "url": "https://api.github.com/repos/symfony/security-http/zipball/a34991b13899de1f953df245395aa2196f9bc113", + "reference": "a34991b13899de1f953df245395aa2196f9bc113", "shasum": "" }, "require": { @@ -15702,7 +15686,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v7.4.8" + "source": "https://github.com/symfony/security-http/tree/v7.4.9" }, "funding": [ { @@ -15722,7 +15706,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-22T15:21:55+00:00" }, { "name": "symfony/serializer", @@ -16534,16 +16518,16 @@ }, { "name": "symfony/type-info", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "6bf34da885ff5143a3dfd8f1b863bb8ab95f50bd" + "reference": "cafeedbf157b890e94ac5b83eaed85595106d5d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/6bf34da885ff5143a3dfd8f1b863bb8ab95f50bd", - "reference": "6bf34da885ff5143a3dfd8f1b863bb8ab95f50bd", + "url": "https://api.github.com/repos/symfony/type-info/zipball/cafeedbf157b890e94ac5b83eaed85595106d5d6", + "reference": "cafeedbf157b890e94ac5b83eaed85595106d5d6", "shasum": "" }, "require": { @@ -16593,7 +16577,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v7.4.8" + "source": "https://github.com/symfony/type-info/tree/v7.4.9" }, "funding": [ { @@ -16613,20 +16597,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-22T15:21:55+00:00" }, { "name": "symfony/uid", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "6883ebdf7bf6a12b37519dbc0df62b0222401b56" + "reference": "2676b524340abcfe4d6151ec698463cebafee439" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/6883ebdf7bf6a12b37519dbc0df62b0222401b56", - "reference": "6883ebdf7bf6a12b37519dbc0df62b0222401b56", + "url": "https://api.github.com/repos/symfony/uid/zipball/2676b524340abcfe4d6151ec698463cebafee439", + "reference": "2676b524340abcfe4d6151ec698463cebafee439", "shasum": "" }, "require": { @@ -16671,7 +16655,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.4.8" + "source": "https://github.com/symfony/uid/tree/v7.4.9" }, "funding": [ { @@ -16691,7 +16675,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-30T15:19:22+00:00" }, { "name": "symfony/ux-translator", @@ -16879,16 +16863,16 @@ }, { "name": "symfony/validator", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "8f73cbddae916756f319b3e195088da216f0f12f" + "reference": "d3bb3dcfbaa26b5782196819dac2e1097d5fae2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/8f73cbddae916756f319b3e195088da216f0f12f", - "reference": "8f73cbddae916756f319b3e195088da216f0f12f", + "url": "https://api.github.com/repos/symfony/validator/zipball/d3bb3dcfbaa26b5782196819dac2e1097d5fae2c", + "reference": "d3bb3dcfbaa26b5782196819dac2e1097d5fae2c", "shasum": "" }, "require": { @@ -16959,7 +16943,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.4.8" + "source": "https://github.com/symfony/validator/tree/v7.4.9" }, "funding": [ { @@ -16979,7 +16963,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T12:55:43+00:00" + "time": "2026-04-30T15:35:16+00:00" }, { "name": "symfony/var-dumper", @@ -17070,16 +17054,16 @@ }, { "name": "symfony/var-exporter", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "398907e89a2a56fe426f7955c6fa943ec0c77225" + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/398907e89a2a56fe426f7955c6fa943ec0c77225", - "reference": "398907e89a2a56fe426f7955c6fa943ec0c77225", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/22e03a49c95ef054a43601cd159b222bfab1c701", + "reference": "22e03a49c95ef054a43601cd159b222bfab1c701", "shasum": "" }, "require": { @@ -17127,7 +17111,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.4.8" + "source": "https://github.com/symfony/var-exporter/tree/v7.4.9" }, "funding": [ { @@ -17147,7 +17131,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/web-link", @@ -17451,16 +17435,16 @@ }, { "name": "tecnickcom/tc-lib-barcode", - "version": "2.4.34", + "version": "2.4.37", "source": { "type": "git", "url": "https://github.com/tecnickcom/tc-lib-barcode.git", - "reference": "4057b35150e383f0425221efaea312e5cb968902" + "reference": "86b89b0399797706a07c1fd4eec3158460b13f7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/tc-lib-barcode/zipball/4057b35150e383f0425221efaea312e5cb968902", - "reference": "4057b35150e383f0425221efaea312e5cb968902", + "url": "https://api.github.com/repos/tecnickcom/tc-lib-barcode/zipball/86b89b0399797706a07c1fd4eec3158460b13f7f", + "reference": "86b89b0399797706a07c1fd4eec3158460b13f7f", "shasum": "" }, "require": { @@ -17469,7 +17453,7 @@ "ext-gd": "*", "ext-pcre": "*", "php": ">=8.1", - "tecnickcom/tc-lib-color": "^2.3" + "tecnickcom/tc-lib-color": "^2.5" }, "require-dev": { "pdepend/pdepend": "^2.16", @@ -17548,20 +17532,20 @@ "type": "custom" } ], - "time": "2026-04-20T07:15:41+00:00" + "time": "2026-04-30T19:47:34+00:00" }, { "name": "tecnickcom/tc-lib-color", - "version": "2.3.14", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/tecnickcom/tc-lib-color.git", - "reference": "6fbb7daabf4f15b38d264ad9091f0745502459b9" + "reference": "ebb76dfb334b7a0b470e765a7b46c5635dce2fe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/tc-lib-color/zipball/6fbb7daabf4f15b38d264ad9091f0745502459b9", - "reference": "6fbb7daabf4f15b38d264ad9091f0745502459b9", + "url": "https://api.github.com/repos/tecnickcom/tc-lib-color/zipball/ebb76dfb334b7a0b470e765a7b46c5635dce2fe0", + "reference": "ebb76dfb334b7a0b470e765a7b46c5635dce2fe0", "shasum": "" }, "require": { @@ -17618,7 +17602,7 @@ "type": "custom" } ], - "time": "2026-04-20T07:09:08+00:00" + "time": "2026-04-30T19:21:47+00:00" }, { "name": "thecodingmachine/safe", @@ -18566,16 +18550,16 @@ }, { "name": "web-auth/webauthn-lib", - "version": "5.2.5", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-lib.git", - "reference": "c28f27cb8f968d2b84db48587563f03bb451b60a" + "reference": "a272f254c056fb3d6c80a4801d3c7c5fedc6a08d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/c28f27cb8f968d2b84db48587563f03bb451b60a", - "reference": "c28f27cb8f968d2b84db48587563f03bb451b60a", + "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/a272f254c056fb3d6c80a4801d3c7c5fedc6a08d", + "reference": "a272f254c056fb3d6c80a4801d3c7c5fedc6a08d", "shasum": "" }, "require": { @@ -18583,18 +18567,18 @@ "ext-openssl": "*", "paragonie/constant_time_encoding": "^2.6|^3.0", "php": ">=8.2", - "phpdocumentor/reflection-docblock": "^5.3", + "phpdocumentor/reflection-docblock": "^5.3|^6.0", "psr/clock": "^1.0", "psr/event-dispatcher": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "spomky-labs/cbor-php": "^3.0", "spomky-labs/pki-framework": "^1.0", - "symfony/clock": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0|^8.0", "symfony/deprecation-contracts": "^3.2", - "symfony/property-access": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0", "web-auth/cose-lib": "^4.2.3" }, "suggest": { @@ -18636,7 +18620,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-lib/tree/5.2.5" + "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.0" }, "funding": [ { @@ -18648,34 +18632,35 @@ "type": "patreon" } ], - "time": "2026-03-23T21:43:02+00:00" + "time": "2026-05-01T12:14:37+00:00" }, { "name": "web-auth/webauthn-symfony-bundle", - "version": "5.2.5", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-symfony-bundle.git", - "reference": "91f0aff70703e20d84251c83e238da1f8fc53b24" + "reference": "40f5ae033d4bea090aaa395b906ebfa7d7fe6055" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-auth/webauthn-symfony-bundle/zipball/91f0aff70703e20d84251c83e238da1f8fc53b24", - "reference": "91f0aff70703e20d84251c83e238da1f8fc53b24", + "url": "https://api.github.com/repos/web-auth/webauthn-symfony-bundle/zipball/40f5ae033d4bea090aaa395b906ebfa7d7fe6055", + "reference": "40f5ae033d4bea090aaa395b906ebfa7d7fe6055", "shasum": "" }, "require": { "php": ">=8.2", "psr/event-dispatcher": "^1.0", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/framework-bundle": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/security-bundle": "^6.4|^7.0", - "symfony/security-core": "^6.4|^7.0", - "symfony/security-http": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/validator": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/security-bundle": "^6.4|^7.0|^8.0", + "symfony/security-core": "^6.4|^7.0|^8.0", + "symfony/security-http": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^3.0", + "symfony/validator": "^6.4|^7.0|^8.0", "web-auth/webauthn-lib": "self.version" }, "suggest": { @@ -18718,7 +18703,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-symfony-bundle/tree/5.2.5" + "source": "https://github.com/web-auth/webauthn-symfony-bundle/tree/5.3.0" }, "funding": [ { @@ -18730,7 +18715,7 @@ "type": "patreon" } ], - "time": "2025-12-20T10:20:41+00:00" + "time": "2026-05-01T12:14:37+00:00" }, { "name": "webmozart/assert", @@ -19429,11 +19414,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.51", + "version": "2.1.54", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc3b523c45e714c70de2ac5113b958223b55dc59", - "reference": "dc3b523c45e714c70de2ac5113b958223b55dc59", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "reference": "8be50c3992107dc837b17da4d140fbbdf9a5c5bd", "shasum": "" }, "require": { @@ -19478,7 +19463,7 @@ "type": "github" } ], - "time": "2026-04-21T18:22:01+00:00" + "time": "2026-04-29T13:31:09+00:00" }, { "name": "phpstan/phpstan-doctrine", @@ -20204,18 +20189,18 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "08cd07f04fb07fb4d316e956801d57b700cf7096" + "reference": "2221f6ef09e87784e78e188aadd8f7e3a50e679a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/08cd07f04fb07fb4d316e956801d57b700cf7096", - "reference": "08cd07f04fb07fb4d316e956801d57b700cf7096", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/2221f6ef09e87784e78e188aadd8f7e3a50e679a", + "reference": "2221f6ef09e87784e78e188aadd8f7e3a50e679a", "shasum": "" }, "conflict": { "3f/pygmentize": "<1.2", "adaptcms/adaptcms": "<=1.3", - "admidio/admidio": "<5.0.8", + "admidio/admidio": "<=5.0.8", "adodb/adodb-php": "<=5.22.9", "aheinze/cockpit": "<2.2", "aimeos/ai-admin-graphql": ">=2022.04.1,<2022.10.10|>=2023.04.1,<2023.10.6|>=2024.04.1,<2024.07.2", @@ -20324,7 +20309,7 @@ "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "chriskacerguis/codeigniter-restserver": "<=2.7.1", "chrome-php/chrome": "<1.14", - "ci4-cms-erp/ci4ms": "<0.31.5", + "ci4-cms-erp/ci4ms": "<=0.31.6", "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", "ckeditor/ckeditor": "<4.25", "clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3", @@ -20529,7 +20514,7 @@ "geshi/geshi": "<=1.0.9.1", "getformwork/formwork": "<=2.3.3", "getgrav/grav": "<1.11.0.0-beta1", - "getkirby/cms": "<5.4", + "getkirby/cms": "<4.9|>=5,<5.4", "getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", @@ -20589,7 +20574,7 @@ "intelliants/subrion": "<4.2.2", "inter-mediator/inter-mediator": "==5.5", "invoiceninja/invoiceninja": "<5.13.4", - "ipl/web": "<0.10.1", + "ipl/web": "<=0.13", "islandora/crayfish": "<4.1", "islandora/islandora": ">=2,<2.4.1", "ivankristianto/phpwhois": "<=4.3", @@ -20825,7 +20810,7 @@ "phpoffice/common": "<0.2.9", "phpoffice/math": "<=0.2", "phpoffice/phpexcel": "<=1.8.2", - "phpoffice/phpspreadsheet": "<1.30|>=2,<2.1.12|>=2.2,<2.4|>=3,<3.10|>=4,<5", + "phpoffice/phpspreadsheet": "<=1.30.3|>=2,<=2.1.15|>=2.2,<=2.4.4|>=3,<=3.10.4|>=4,<=5.6", "phppgadmin/phppgadmin": "<=7.13", "phpseclib/phpseclib": "<2.0.53|>=3,<3.0.51", "phpservermon/phpservermon": "<3.6", @@ -20859,7 +20844,7 @@ "prestashop/gamification": "<2.3.2", "prestashop/prestashop": "<8.2.5|>=9.0.0.0-alpha1,<9.1", "prestashop/productcomments": "<5.0.2", - "prestashop/ps_checkout": "<4.4.1|>=5,<5.0.5", + "prestashop/ps_checkout": "<5.3", "prestashop/ps_contactinfo": "<=3.3.2", "prestashop/ps_emailsubscription": "<2.6.1", "prestashop/ps_facetedsearch": "<3.4.1", @@ -20896,6 +20881,7 @@ "rhukster/dom-sanitizer": "<1.0.10", "rmccue/requests": ">=1.6,<1.8", "roadiz/documents": "<2.3.42|>=2.4,<2.5.44|>=2.6,<2.6.28|>=2.7,<2.7.9", + "roadiz/openid": "<2.3.43|>=2.5,<2.5.45|>=2.6,<2.6.31|>=2.7,<2.7.18", "robrichards/xmlseclibs": "<3.1.5", "roots/soil": "<4.1", "roundcube/roundcubemail": "<1.5.10|>=1.6,<1.6.11|>=1.7.0.0-beta,<1.7.0.0-RC5-dev", @@ -21253,7 +21239,7 @@ "type": "tidelift" } ], - "time": "2026-04-24T17:22:29+00:00" + "time": "2026-04-30T21:24:12+00:00" }, { "name": "sebastian/cli-parser", @@ -22627,16 +22613,16 @@ }, { "name": "symfony/web-profiler-bundle", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "79f039096c67cc1cc3f607d2ba72af86cd27e6a4" + "reference": "36dd8b8c05da059925c5804641aad9159e5b73e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/79f039096c67cc1cc3f607d2ba72af86cd27e6a4", - "reference": "79f039096c67cc1cc3f607d2ba72af86cd27e6a4", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/36dd8b8c05da059925c5804641aad9159e5b73e8", + "reference": "36dd8b8c05da059925c5804641aad9159e5b73e8", "shasum": "" }, "require": { @@ -22693,7 +22679,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.4.8" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.4.9" }, "funding": [ { @@ -22713,7 +22699,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-22T15:21:55+00:00" }, { "name": "theseer/tokenizer", @@ -22769,7 +22755,6 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "jkphl/micrometa": 20, "roave/security-advisories": 20 }, "prefer-stable": false, diff --git a/config/reference.php b/config/reference.php index 71850e24..e1304d43 100644 --- a/config/reference.php +++ b/config/reference.php @@ -128,7 +128,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * @psalm-type FrameworkConfig = array{ * secret?: scalar|Param|null, * http_method_override?: bool|Param, // Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests. // Default: false - * allowed_http_method_override?: list|null, + * allowed_http_method_override?: null|list, * trust_x_sendfile_type_header?: scalar|Param|null, // Set true to enable support for xsendfile in binary file responses. // Default: "%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%" * ide?: scalar|Param|null, // Default: "%env(default::SYMFONY_IDE)%" * test?: bool|Param, @@ -136,9 +136,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * set_locale_from_accept_language?: bool|Param, // Whether to use the Accept-Language HTTP header to set the Request locale (only when the "_locale" request attribute is not passed). // Default: false * set_content_language_from_locale?: bool|Param, // Whether to set the Content-Language HTTP header on the Response using the Request locale. // Default: false * enabled_locales?: list, - * trusted_hosts?: list, + * trusted_hosts?: string|list, * trusted_proxies?: mixed, // Default: ["%env(default::SYMFONY_TRUSTED_PROXIES)%"] - * trusted_headers?: list, + * trusted_headers?: string|list, * error_controller?: scalar|Param|null, // Default: "error_controller" * handle_all_throwables?: bool|Param, // HttpKernel will handle all kinds of \Throwable. // Default: true * csrf_protection?: bool|array{ @@ -193,40 +193,40 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * workflows?: bool|array{ * enabled?: bool|Param, // Default: false * workflows?: array, - * definition_validators?: list, - * support_strategy?: scalar|Param|null, - * initial_marking?: list, - * events_to_dispatch?: list|null, - * places?: list, + * definition_validators?: list, + * support_strategy?: scalar|Param|null, + * initial_marking?: backed-enum|string|list, + * events_to_dispatch?: null|list, + * places?: string|list, + * }>, + * transitions?: list, + * to?: backed-enum|string|list, + * weight?: int|Param, // Default: 1 + * metadata?: array, + * }>, * metadata?: array, * }>, - * transitions?: list, - * to?: list, - * weight?: int|Param, // Default: 1 - * metadata?: array, - * }>, - * metadata?: array, - * }>, * }, * router?: bool|array{ // Router configuration * enabled?: bool|Param, // Default: false @@ -271,20 +271,20 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * version_format?: scalar|Param|null, // Default: "%%s?%%s" * json_manifest_path?: scalar|Param|null, // Default: null * base_path?: scalar|Param|null, // Default: "" - * base_urls?: list, + * base_urls?: string|list, * packages?: array, - * }>, + * strict_mode?: bool|Param, // Throw an exception if an entry is missing from the manifest.json. // Default: false + * version_strategy?: scalar|Param|null, // Default: null + * version?: scalar|Param|null, + * version_format?: scalar|Param|null, // Default: null + * json_manifest_path?: scalar|Param|null, // Default: null + * base_path?: scalar|Param|null, // Default: "" + * base_urls?: string|list, + * }>, * }, * asset_mapper?: bool|array{ // Asset Mapper configuration * enabled?: bool|Param, // Default: false - * paths?: array, + * paths?: string|array, * excluded_patterns?: list, * exclude_dotfiles?: bool|Param, // If true, any files starting with "." will be excluded from the asset mapper. // Default: true * server?: bool|Param, // If true, a "dev server" will return the assets from the public directory (true in "debug" mode only by default). // Default: true @@ -303,7 +303,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * translator?: bool|array{ // Translator configuration * enabled?: bool|Param, // Default: true - * fallbacks?: list, + * fallbacks?: string|list, * logging?: bool|Param, // Default: false * formatter?: scalar|Param|null, // Default: "translator.formatter.default" * cache_dir?: scalar|Param|null, // Default: "%kernel.cache_dir%/translations" @@ -318,22 +318,22 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * localizable_html_attributes?: list, * }, * providers?: array, - * locales?: list, - * }>, + * dsn?: scalar|Param|null, + * domains?: list, + * locales?: list, + * }>, * globals?: array, - * domain?: string|Param, - * }>, + * value?: mixed, + * message?: string|Param, + * parameters?: array, + * domain?: string|Param, + * }>, * }, * validation?: bool|array{ // Validation configuration * enabled?: bool|Param, // Default: true * cache?: scalar|Param|null, // Deprecated: Setting the "framework.validation.cache.cache" configuration option is deprecated. It will be removed in version 8.0. * enable_attributes?: bool|Param, // Default: true - * static_method?: list, + * static_method?: string|list, * translation_domain?: scalar|Param|null, // Default: "validators" * email_validation_mode?: "html5"|"html5-allow-no-tld"|"strict"|"loose"|Param, // Default: "html5" * mapping?: array{ @@ -345,8 +345,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * disable_translation?: bool|Param, // Default: false * auto_mapping?: array, - * }>, + * services?: list, + * }>, * }, * annotations?: bool|array{ * enabled?: bool|Param, // Default: false @@ -362,11 +362,11 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * default_context?: array, * named_serializers?: array, - * include_built_in_normalizers?: bool|Param, // Whether to include the built-in normalizers // Default: true - * include_built_in_encoders?: bool|Param, // Whether to include the built-in encoders // Default: true - * }>, + * name_converter?: scalar|Param|null, + * default_context?: array, + * include_built_in_normalizers?: bool|Param, // Whether to include the built-in normalizers // Default: true + * include_built_in_encoders?: bool|Param, // Whether to include the built-in encoders // Default: true + * }>, * }, * property_access?: bool|array{ // Property access configuration * enabled?: bool|Param, // Default: true @@ -396,40 +396,40 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * default_doctrine_dbal_provider?: scalar|Param|null, // Default: "database_connection" * default_pdo_provider?: scalar|Param|null, // Default: null * pools?: array, - * tags?: scalar|Param|null, // Default: null - * public?: bool|Param, // Default: false - * default_lifetime?: scalar|Param|null, // Default lifetime of the pool. - * provider?: scalar|Param|null, // Overwrite the setting from the default provider for this adapter. - * early_expiration_message_bus?: scalar|Param|null, - * clearer?: scalar|Param|null, - * }>, + * adapters?: string|list, + * tags?: scalar|Param|null, // Default: null + * public?: bool|Param, // Default: false + * default_lifetime?: scalar|Param|null, // Default lifetime of the pool. + * provider?: scalar|Param|null, // Overwrite the setting from the default provider for this adapter. + * early_expiration_message_bus?: scalar|Param|null, + * clearer?: scalar|Param|null, + * }>, * }, * php_errors?: array{ // PHP errors handling configuration * log?: mixed, // Use the application logger instead of the PHP logger for logging PHP errors. // Default: true * throw?: bool|Param, // Throw PHP errors as \ErrorException instances. // Default: true * }, * exceptions?: array, + * log_level?: scalar|Param|null, // The level of log message. Null to let Symfony decide. // Default: null + * status_code?: scalar|Param|null, // The status code of the response. Null or 0 to let Symfony decide. // Default: null + * log_channel?: scalar|Param|null, // The channel of log message. Null to let Symfony decide. // Default: null + * }>, * web_link?: bool|array{ // Web links configuration * enabled?: bool|Param, // Default: true * }, * lock?: bool|string|array{ // Lock configuration * enabled?: bool|Param, // Default: false - * resources?: array>, + * resources?: string|array>, * }, * semaphore?: bool|string|array{ // Semaphore configuration * enabled?: bool|Param, // Default: false - * resources?: array, + * resources?: string|array, * }, * messenger?: bool|array{ // Messenger configuration * enabled?: bool|Param, // Default: false * routing?: array, - * }>, + * senders?: list, + * }>, * serializer?: array{ * default_serializer?: scalar|Param|null, // Service id to use as the default serializer for the transports. // Default: "messenger.transport.native_php_serializer" * symfony_serializer?: array{ @@ -438,34 +438,34 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * }, * transports?: array, - * failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null - * retry_strategy?: string|array{ - * service?: scalar|Param|null, // Service id to override the retry strategy entirely. // Default: null - * max_retries?: int|Param, // Default: 3 - * delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000 - * multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: this delay = (delay * (multiple ^ retries)). // Default: 2 - * max_delay?: int|Param, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0 - * jitter?: float|Param, // Randomness to apply to the delay (between 0 and 1). // Default: 0.1 - * }, - * rate_limiter?: scalar|Param|null, // Rate limiter name to use when processing messages. // Default: null - * }>, + * dsn?: scalar|Param|null, + * serializer?: scalar|Param|null, // Service id of a custom serializer to use. // Default: null + * options?: array, + * failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null + * retry_strategy?: string|array{ + * service?: scalar|Param|null, // Service id to override the retry strategy entirely. // Default: null + * max_retries?: int|Param, // Default: 3 + * delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000 + * multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: this delay = (delay * (multiple ^ retries)). // Default: 2 + * max_delay?: int|Param, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0 + * jitter?: float|Param, // Randomness to apply to the delay (between 0 and 1). // Default: 0.1 + * }, + * rate_limiter?: scalar|Param|null, // Rate limiter name to use when processing messages. // Default: null + * }>, * failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null - * stop_worker_on_signals?: list, + * stop_worker_on_signals?: int|string|list, * default_bus?: scalar|Param|null, // Default: null * buses?: array, + * default_middleware?: bool|string|array{ + * enabled?: bool|Param, // Default: true + * allow_no_handlers?: bool|Param, // Default: false + * allow_no_senders?: bool|Param, // Default: true + * }, + * middleware?: string|list, + * }>, * }>, - * }>, * }, * scheduler?: bool|array{ // Scheduler configuration * enabled?: bool|Param, // Default: false @@ -510,10 +510,10 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * retry_failed?: bool|array{ * enabled?: bool|Param, // Default: false * retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null - * http_codes?: array, - * }>, + * http_codes?: int|string|array, + * }>, * max_retries?: int|Param, // Default: 3 * delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000 * multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: delay * (multiple ^ retries). // Default: 2 @@ -523,57 +523,57 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * mock_response_factory?: scalar|Param|null, // The id of the service that should generate mock responses. It should be either an invokable or an iterable. * scoped_clients?: array, - * headers?: array, - * max_redirects?: int|Param, // The maximum number of redirects to follow. - * http_version?: scalar|Param|null, // The default HTTP version, typically 1.1 or 2.0, leave to null for the best version. - * resolve?: array, - * proxy?: scalar|Param|null, // The URL of the proxy to pass requests through or null for automatic detection. - * no_proxy?: scalar|Param|null, // A comma separated list of hosts that do not require a proxy to be reached. - * timeout?: float|Param, // The idle timeout, defaults to the "default_socket_timeout" ini parameter. - * max_duration?: float|Param, // The maximum execution time for the request+response as a whole. - * bindto?: scalar|Param|null, // A network interface name, IP address, a host name or a UNIX socket to bind to. - * verify_peer?: bool|Param, // Indicates if the peer should be verified in a TLS context. - * verify_host?: bool|Param, // Indicates if the host should exist as a certificate common name. - * cafile?: scalar|Param|null, // A certificate authority file. - * capath?: scalar|Param|null, // A directory that contains multiple certificate authority files. - * local_cert?: scalar|Param|null, // A PEM formatted certificate file. - * local_pk?: scalar|Param|null, // A private key file. - * passphrase?: scalar|Param|null, // The passphrase used to encrypt the "local_pk" file. - * ciphers?: scalar|Param|null, // A list of TLS ciphers separated by colons, commas or spaces (e.g. "RC3-SHA:TLS13-AES-128-GCM-SHA256"...). - * peer_fingerprint?: array{ // Associative array: hashing algorithm => hash(es). - * sha1?: mixed, - * pin-sha256?: mixed, - * md5?: mixed, - * }, - * crypto_method?: scalar|Param|null, // The minimum version of TLS to accept; must be one of STREAM_CRYPTO_METHOD_TLSv*_CLIENT constants. - * extra?: array, - * rate_limiter?: scalar|Param|null, // Rate limiter name to use for throttling requests. // Default: null - * caching?: bool|array{ // Caching configuration. - * enabled?: bool|Param, // Default: false - * cache_pool?: string|Param, // The taggable cache pool to use for storing the responses. // Default: "cache.http_client" - * shared?: bool|Param, // Indicates whether the cache is shared (public) or private. // Default: true - * max_ttl?: int|Param, // The maximum TTL (in seconds) allowed for cached responses. Null means no cap. // Default: null - * }, - * retry_failed?: bool|array{ - * enabled?: bool|Param, // Default: false - * retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null - * http_codes?: array, - * }>, - * max_retries?: int|Param, // Default: 3 - * delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000 - * multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: delay * (multiple ^ retries). // Default: 2 - * max_delay?: int|Param, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0 - * jitter?: float|Param, // Randomness in percent (between 0 and 1) to apply to the delay. // Default: 0.1 - * }, - * }>, + * scope?: scalar|Param|null, // The regular expression that the request URL must match before adding the other options. When none is provided, the base URI is used instead. + * base_uri?: scalar|Param|null, // The URI to resolve relative URLs, following rules in RFC 3985, section 2. + * auth_basic?: scalar|Param|null, // An HTTP Basic authentication "username:password". + * auth_bearer?: scalar|Param|null, // A token enabling HTTP Bearer authorization. + * auth_ntlm?: scalar|Param|null, // A "username:password" pair to use Microsoft NTLM authentication (requires the cURL extension). + * query?: array, + * headers?: array, + * max_redirects?: int|Param, // The maximum number of redirects to follow. + * http_version?: scalar|Param|null, // The default HTTP version, typically 1.1 or 2.0, leave to null for the best version. + * resolve?: array, + * proxy?: scalar|Param|null, // The URL of the proxy to pass requests through or null for automatic detection. + * no_proxy?: scalar|Param|null, // A comma separated list of hosts that do not require a proxy to be reached. + * timeout?: float|Param, // The idle timeout, defaults to the "default_socket_timeout" ini parameter. + * max_duration?: float|Param, // The maximum execution time for the request+response as a whole. + * bindto?: scalar|Param|null, // A network interface name, IP address, a host name or a UNIX socket to bind to. + * verify_peer?: bool|Param, // Indicates if the peer should be verified in a TLS context. + * verify_host?: bool|Param, // Indicates if the host should exist as a certificate common name. + * cafile?: scalar|Param|null, // A certificate authority file. + * capath?: scalar|Param|null, // A directory that contains multiple certificate authority files. + * local_cert?: scalar|Param|null, // A PEM formatted certificate file. + * local_pk?: scalar|Param|null, // A private key file. + * passphrase?: scalar|Param|null, // The passphrase used to encrypt the "local_pk" file. + * ciphers?: scalar|Param|null, // A list of TLS ciphers separated by colons, commas or spaces (e.g. "RC3-SHA:TLS13-AES-128-GCM-SHA256"...). + * peer_fingerprint?: array{ // Associative array: hashing algorithm => hash(es). + * sha1?: mixed, + * pin-sha256?: mixed, + * md5?: mixed, + * }, + * crypto_method?: scalar|Param|null, // The minimum version of TLS to accept; must be one of STREAM_CRYPTO_METHOD_TLSv*_CLIENT constants. + * extra?: array, + * rate_limiter?: scalar|Param|null, // Rate limiter name to use for throttling requests. // Default: null + * caching?: bool|array{ // Caching configuration. + * enabled?: bool|Param, // Default: false + * cache_pool?: string|Param, // The taggable cache pool to use for storing the responses. // Default: "cache.http_client" + * shared?: bool|Param, // Indicates whether the cache is shared (public) or private. // Default: true + * max_ttl?: int|Param, // The maximum TTL (in seconds) allowed for cached responses. Null means no cap. // Default: null + * }, + * retry_failed?: bool|array{ + * enabled?: bool|Param, // Default: false + * retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null + * http_codes?: int|string|array, + * }>, + * max_retries?: int|Param, // Default: 3 + * delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000 + * multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: delay * (multiple ^ retries). // Default: 2 + * max_delay?: int|Param, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0 + * jitter?: float|Param, // Randomness in percent (between 0 and 1) to apply to the delay. // Default: 0.1 + * }, + * }>, * }, * mailer?: bool|array{ // Mailer configuration * enabled?: bool|Param, // Default: true @@ -582,12 +582,12 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * transports?: array, * envelope?: array{ // Mailer Envelope configuration * sender?: scalar|Param|null, - * recipients?: list, - * allowed_recipients?: list, + * recipients?: string|list, + * allowed_recipients?: string|list, * }, * headers?: array, + * value?: mixed, + * }>, * dkim_signer?: bool|array{ // DKIM signer configuration * enabled?: bool|Param, // Default: false * key?: scalar|Param|null, // Key content, or path to key (in PEM format with the `file://` prefix) // Default: "" @@ -624,25 +624,25 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * notification_on_failed_messages?: bool|Param, // Default: false * channel_policy?: array>, * admin_recipients?: list, + * email?: scalar|Param|null, + * phone?: scalar|Param|null, // Default: "" + * }>, * }, * rate_limiter?: bool|array{ // Rate limiter configuration * enabled?: bool|Param, // Default: true * limiters?: array, - * limit?: int|Param, // The maximum allowed hits in a fixed interval or burst. - * interval?: scalar|Param|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent). - * rate?: array{ // Configures the fill rate if "policy" is set to "token_bucket". - * interval?: scalar|Param|null, // Configures the rate interval. The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent). - * amount?: int|Param, // Amount of tokens to add each interval. // Default: 1 - * }, - * }>, + * lock_factory?: scalar|Param|null, // The service ID of the lock factory used by this limiter (or null to disable locking). // Default: "auto" + * cache_pool?: scalar|Param|null, // The cache pool to use for storing the current limiter state. // Default: "cache.rate_limiter" + * storage_service?: scalar|Param|null, // The service ID of a custom storage implementation, this precedes any configured "cache_pool". // Default: null + * policy?: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter. + * limiters?: string|list, + * limit?: int|Param, // The maximum allowed hits in a fixed interval or burst. + * interval?: scalar|Param|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent). + * rate?: array{ // Configures the fill rate if "policy" is set to "token_bucket". + * interval?: scalar|Param|null, // Configures the rate interval. The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent). + * amount?: int|Param, // Amount of tokens to add each interval. // Default: 1 + * }, + * }>, * }, * uid?: bool|array{ // Uid configuration * enabled?: bool|Param, // Default: true @@ -655,33 +655,33 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * html_sanitizer?: bool|array{ // HtmlSanitizer configuration * enabled?: bool|Param, // Default: false * sanitizers?: array, - * block_elements?: list, - * drop_elements?: list, - * allow_attributes?: array, - * drop_attributes?: array, - * force_attributes?: array>, - * force_https_urls?: bool|Param, // Transforms URLs using the HTTP scheme to use the HTTPS scheme instead. // Default: false - * allowed_link_schemes?: list, - * allowed_link_hosts?: list|null, - * allow_relative_links?: bool|Param, // Allows relative URLs to be used in links href attributes. // Default: false - * allowed_media_schemes?: list, - * allowed_media_hosts?: list|null, - * allow_relative_medias?: bool|Param, // Allows relative URLs to be used in media source attributes (img, audio, video, ...). // Default: false - * with_attribute_sanitizers?: list, - * without_attribute_sanitizers?: list, - * max_input_length?: int|Param, // The maximum length allowed for the sanitized input. // Default: 0 - * }>, + * allow_safe_elements?: bool|Param, // Allows "safe" elements and attributes. // Default: false + * allow_static_elements?: bool|Param, // Allows all static elements and attributes from the W3C Sanitizer API standard. // Default: false + * allow_elements?: array, + * block_elements?: string|list, + * drop_elements?: string|list, + * allow_attributes?: array, + * drop_attributes?: array, + * force_attributes?: array>, + * force_https_urls?: bool|Param, // Transforms URLs using the HTTP scheme to use the HTTPS scheme instead. // Default: false + * allowed_link_schemes?: string|list, + * allowed_link_hosts?: null|string|list, + * allow_relative_links?: bool|Param, // Allows relative URLs to be used in links href attributes. // Default: false + * allowed_media_schemes?: string|list, + * allowed_media_hosts?: null|string|list, + * allow_relative_medias?: bool|Param, // Allows relative URLs to be used in media source attributes (img, audio, video, ...). // Default: false + * with_attribute_sanitizers?: string|list, + * without_attribute_sanitizers?: string|list, + * max_input_length?: int|Param, // The maximum length allowed for the sanitized input. // Default: 0 + * }>, * }, * webhook?: bool|array{ // Webhook configuration * enabled?: bool|Param, // Default: false * message_bus?: scalar|Param|null, // The message bus to use. // Default: "messenger.default_bus" * routing?: array, + * service?: scalar|Param|null, + * secret?: scalar|Param|null, // Default: "" + * }>, * }, * remote-event?: bool|array{ // RemoteEvent configuration * enabled?: bool|Param, // Default: false @@ -694,62 +694,11 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * dbal?: array{ * default_connection?: scalar|Param|null, * types?: array, + * class?: scalar|Param|null, + * commented?: bool|Param, // Deprecated: The doctrine-bundle type commenting features were removed; the corresponding config parameter was deprecated in 2.0 and will be dropped in 3.0. + * }>, * driver_schemes?: array, * connections?: array, - * mapping_types?: array, - * default_table_options?: array, - * schema_manager_factory?: scalar|Param|null, // Default: "doctrine.dbal.default_schema_manager_factory" - * result_cache?: scalar|Param|null, - * slaves?: array, + * mapping_types?: array, + * default_table_options?: array, + * schema_manager_factory?: scalar|Param|null, // Default: "doctrine.dbal.default_schema_manager_factory" + * result_cache?: scalar|Param|null, + * slaves?: array, + * replicas?: array, * }>, - * replicas?: array, - * }>, * }, * orm?: array{ * default_entity_manager?: scalar|Param|null, @@ -828,94 +828,94 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * evict_cache?: bool|Param, // Set to true to fetch the entity from the database instead of using the cache, if any // Default: false * }, * entity_managers?: array, - * }>, - * }>, - * }, - * connection?: scalar|Param|null, - * class_metadata_factory_name?: scalar|Param|null, // Default: "Doctrine\\ORM\\Mapping\\ClassMetadataFactory" - * default_repository_class?: scalar|Param|null, // Default: "Doctrine\\ORM\\EntityRepository" - * auto_mapping?: scalar|Param|null, // Default: false - * naming_strategy?: scalar|Param|null, // Default: "doctrine.orm.naming_strategy.default" - * quote_strategy?: scalar|Param|null, // Default: "doctrine.orm.quote_strategy.default" - * typed_field_mapper?: scalar|Param|null, // Default: "doctrine.orm.typed_field_mapper.default" - * entity_listener_resolver?: scalar|Param|null, // Default: null - * fetch_mode_subselect_batch_size?: scalar|Param|null, - * repository_factory?: scalar|Param|null, // Default: "doctrine.orm.container_repository_factory" - * schema_ignore_classes?: list, - * report_fields_where_declared?: bool|Param, // Set to "true" to opt-in to the new mapping driver mode that was added in Doctrine ORM 2.16 and will be mandatory in ORM 3.0. See https://github.com/doctrine/orm/pull/10455. // Default: true - * validate_xml_mapping?: bool|Param, // Set to "true" to opt-in to the new mapping driver mode that was added in Doctrine ORM 2.14. See https://github.com/doctrine/orm/pull/6728. // Default: false - * second_level_cache?: array{ - * region_cache_driver?: string|array{ + * query_cache_driver?: string|array{ * type?: scalar|Param|null, // Default: null * id?: scalar|Param|null, * pool?: scalar|Param|null, * }, - * region_lock_lifetime?: scalar|Param|null, // Default: 60 - * log_enabled?: bool|Param, // Default: true - * region_lifetime?: scalar|Param|null, // Default: 3600 - * enabled?: bool|Param, // Default: true - * factory?: scalar|Param|null, - * regions?: array, + * }>, + * }>, + * }, + * connection?: scalar|Param|null, + * class_metadata_factory_name?: scalar|Param|null, // Default: "Doctrine\\ORM\\Mapping\\ClassMetadataFactory" + * default_repository_class?: scalar|Param|null, // Default: "Doctrine\\ORM\\EntityRepository" + * auto_mapping?: scalar|Param|null, // Default: false + * naming_strategy?: scalar|Param|null, // Default: "doctrine.orm.naming_strategy.default" + * quote_strategy?: scalar|Param|null, // Default: "doctrine.orm.quote_strategy.default" + * typed_field_mapper?: scalar|Param|null, // Default: "doctrine.orm.typed_field_mapper.default" + * entity_listener_resolver?: scalar|Param|null, // Default: null + * fetch_mode_subselect_batch_size?: scalar|Param|null, + * repository_factory?: scalar|Param|null, // Default: "doctrine.orm.container_repository_factory" + * schema_ignore_classes?: list, + * report_fields_where_declared?: bool|Param, // Set to "true" to opt-in to the new mapping driver mode that was added in Doctrine ORM 2.16 and will be mandatory in ORM 3.0. See https://github.com/doctrine/orm/pull/10455. // Default: true + * validate_xml_mapping?: bool|Param, // Set to "true" to opt-in to the new mapping driver mode that was added in Doctrine ORM 2.14. See https://github.com/doctrine/orm/pull/6728. // Default: false + * second_level_cache?: array{ + * region_cache_driver?: string|array{ * type?: scalar|Param|null, // Default: null * id?: scalar|Param|null, * pool?: scalar|Param|null, * }, - * lock_path?: scalar|Param|null, // Default: "%kernel.cache_dir%/doctrine/orm/slc/filelock" - * lock_lifetime?: scalar|Param|null, // Default: 60 - * type?: scalar|Param|null, // Default: "default" - * lifetime?: scalar|Param|null, // Default: 0 - * service?: scalar|Param|null, - * name?: scalar|Param|null, - * }>, - * loggers?: array, - * }, - * hydrators?: array, - * mappings?: array, + * loggers?: array, + * }, + * hydrators?: array, + * mappings?: array, + * dql?: array{ + * string_functions?: array, + * numeric_functions?: array, + * datetime_functions?: array, + * }, + * filters?: array, + * }>, + * identity_generation_preferences?: array, * }>, - * dql?: array{ - * string_functions?: array, - * numeric_functions?: array, - * datetime_functions?: array, - * }, - * filters?: array, - * }>, - * identity_generation_preferences?: array, - * }>, * resolve_target_entities?: array, * }, * } @@ -957,390 +957,391 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * allow_if_equal_granted_denied?: bool|Param, // Default: true * }, * password_hashers?: array, - * hash_algorithm?: scalar|Param|null, // Name of hashing algorithm for PBKDF2 (i.e. sha256, sha512, etc..) See hash_algos() for a list of supported algorithms. // Default: "sha512" - * key_length?: scalar|Param|null, // Default: 40 - * ignore_case?: bool|Param, // Default: false - * encode_as_base64?: bool|Param, // Default: true - * iterations?: scalar|Param|null, // Default: 5000 - * cost?: int|Param, // Default: null - * memory_cost?: scalar|Param|null, // Default: null - * time_cost?: scalar|Param|null, // Default: null - * id?: scalar|Param|null, - * }>, + * algorithm?: scalar|Param|null, + * migrate_from?: string|list, + * hash_algorithm?: scalar|Param|null, // Name of hashing algorithm for PBKDF2 (i.e. sha256, sha512, etc..) See hash_algos() for a list of supported algorithms. // Default: "sha512" + * key_length?: scalar|Param|null, // Default: 40 + * ignore_case?: bool|Param, // Default: false + * encode_as_base64?: bool|Param, // Default: true + * iterations?: scalar|Param|null, // Default: 5000 + * cost?: int|Param, // Default: null + * memory_cost?: scalar|Param|null, // Default: null + * time_cost?: scalar|Param|null, // Default: null + * id?: scalar|Param|null, + * }>, * providers?: array, - * }, - * entity?: array{ - * class?: scalar|Param|null, // The full entity class name of your user class. - * property?: scalar|Param|null, // Default: null - * manager_name?: scalar|Param|null, // Default: null - * }, - * memory?: array{ - * users?: array, - * }>, - * }, - * ldap?: array{ - * service?: scalar|Param|null, - * base_dn?: scalar|Param|null, - * search_dn?: scalar|Param|null, // Default: null - * search_password?: scalar|Param|null, // Default: null - * extra_fields?: list, - * default_roles?: list, - * role_fetcher?: scalar|Param|null, // Default: null - * uid_key?: scalar|Param|null, // Default: "sAMAccountName" - * filter?: scalar|Param|null, // Default: "({uid_key}={user_identifier})" - * password_attribute?: scalar|Param|null, // Default: null - * }, - * saml?: array{ - * user_class?: scalar|Param|null, - * default_roles?: list, - * }, - * }>, + * id?: scalar|Param|null, + * chain?: array{ + * providers?: string|list, + * }, + * entity?: array{ + * class?: scalar|Param|null, // The full entity class name of your user class. + * property?: scalar|Param|null, // Default: null + * manager_name?: scalar|Param|null, // Default: null + * }, + * memory?: array{ + * users?: array, + * }>, + * }, + * ldap?: array{ + * service?: scalar|Param|null, + * base_dn?: scalar|Param|null, + * search_dn?: scalar|Param|null, // Default: null + * search_password?: scalar|Param|null, // Default: null + * extra_fields?: list, + * default_roles?: string|list, + * role_fetcher?: scalar|Param|null, // Default: null + * uid_key?: scalar|Param|null, // Default: "sAMAccountName" + * filter?: scalar|Param|null, // Default: "({uid_key}={user_identifier})" + * password_attribute?: scalar|Param|null, // Default: null + * }, + * saml?: array{ + * user_class?: scalar|Param|null, + * default_roles?: list, + * }, + * }>, * firewalls?: array, - * security?: bool|Param, // Default: true - * user_checker?: scalar|Param|null, // The UserChecker to use when authenticating users in this firewall. // Default: "security.user_checker" - * request_matcher?: scalar|Param|null, - * access_denied_url?: scalar|Param|null, - * access_denied_handler?: scalar|Param|null, - * entry_point?: scalar|Param|null, // An enabled authenticator name or a service id that implements "Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface". - * provider?: scalar|Param|null, - * stateless?: bool|Param, // Default: false - * lazy?: bool|Param, // Default: false - * context?: scalar|Param|null, - * logout?: array{ - * enable_csrf?: bool|Param|null, // Default: null - * csrf_token_id?: scalar|Param|null, // Default: "logout" - * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" - * csrf_token_manager?: scalar|Param|null, - * path?: scalar|Param|null, // Default: "/logout" - * target?: scalar|Param|null, // Default: "/" - * invalidate_session?: bool|Param, // Default: true - * clear_site_data?: list<"*"|"cache"|"cookies"|"storage"|"executionContexts"|Param>, - * delete_cookies?: array, - * }, - * switch_user?: array{ + * pattern?: scalar|Param|null, + * host?: scalar|Param|null, + * methods?: string|list, + * security?: bool|Param, // Default: true + * user_checker?: scalar|Param|null, // The UserChecker to use when authenticating users in this firewall. // Default: "security.user_checker" + * request_matcher?: scalar|Param|null, + * access_denied_url?: scalar|Param|null, + * access_denied_handler?: scalar|Param|null, + * entry_point?: scalar|Param|null, // An enabled authenticator name or a service id that implements "Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface". * provider?: scalar|Param|null, - * parameter?: scalar|Param|null, // Default: "_switch_user" - * role?: scalar|Param|null, // Default: "ROLE_ALLOWED_TO_SWITCH" - * target_route?: scalar|Param|null, // Default: null - * }, - * required_badges?: list, - * custom_authenticators?: list, - * login_throttling?: array{ - * limiter?: scalar|Param|null, // A service id implementing "Symfony\Component\HttpFoundation\RateLimiter\RequestRateLimiterInterface". - * max_attempts?: int|Param, // Default: 5 - * interval?: scalar|Param|null, // Default: "1 minute" - * lock_factory?: scalar|Param|null, // The service ID of the lock factory used by the login rate limiter (or null to disable locking). // Default: null - * cache_pool?: string|Param, // The cache pool to use for storing the limiter state // Default: "cache.rate_limiter" - * storage_service?: string|Param, // The service ID of a custom storage implementation, this precedes any configured "cache_pool" // Default: null - * }, - * two_factor?: array{ - * check_path?: scalar|Param|null, // Default: "/2fa_check" - * post_only?: bool|Param, // Default: true - * auth_form_path?: scalar|Param|null, // Default: "/2fa" - * always_use_default_target_path?: bool|Param, // Default: false - * default_target_path?: scalar|Param|null, // Default: "/" - * success_handler?: scalar|Param|null, // Default: null - * failure_handler?: scalar|Param|null, // Default: null - * authentication_required_handler?: scalar|Param|null, // Default: null - * auth_code_parameter_name?: scalar|Param|null, // Default: "_auth_code" - * trusted_parameter_name?: scalar|Param|null, // Default: "_trusted" - * remember_me_sets_trusted?: scalar|Param|null, // Default: false - * multi_factor?: bool|Param, // Default: false - * prepare_on_login?: bool|Param, // Default: false - * prepare_on_access_denied?: bool|Param, // Default: false - * enable_csrf?: scalar|Param|null, // Default: false - * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" - * csrf_token_id?: scalar|Param|null, // Default: "two_factor" - * csrf_header?: scalar|Param|null, // Default: null - * csrf_token_manager?: scalar|Param|null, // Default: "scheb_two_factor.csrf_token_manager" - * provider?: scalar|Param|null, // Default: null - * }, - * webauthn?: array{ - * user_provider?: scalar|Param|null, // Default: null - * options_storage?: scalar|Param|null, // Deprecated: The child node "options_storage" at path "security.firewalls..webauthn.options_storage" is deprecated. Please use the root option "options_storage" instead. // Default: null - * success_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultSuccessHandler" - * failure_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultFailureHandler" - * secured_rp_ids?: array, - * authentication?: bool|array{ - * enabled?: bool|Param, // Default: true - * profile?: scalar|Param|null, // Default: "default" - * options_builder?: scalar|Param|null, // Default: null - * routes?: array{ - * host?: scalar|Param|null, // Default: null - * options_method?: scalar|Param|null, // Default: "POST" - * options_path?: scalar|Param|null, // Default: "/login/options" - * result_method?: scalar|Param|null, // Default: "POST" - * result_path?: scalar|Param|null, // Default: "/login" - * }, - * options_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultRequestOptionsHandler" + * stateless?: bool|Param, // Default: false + * lazy?: bool|Param, // Default: false + * context?: scalar|Param|null, + * logout?: array{ + * enable_csrf?: bool|Param|null, // Default: null + * csrf_token_id?: scalar|Param|null, // Default: "logout" + * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" + * csrf_token_manager?: scalar|Param|null, + * path?: scalar|Param|null, // Default: "/logout" + * target?: scalar|Param|null, // Default: "/" + * invalidate_session?: bool|Param, // Default: true + * clear_site_data?: string|list<"*"|"cache"|"cookies"|"storage"|"executionContexts"|Param>, + * delete_cookies?: string|array, * }, - * registration?: bool|array{ - * enabled?: bool|Param, // Default: false - * profile?: scalar|Param|null, // Default: "default" - * options_builder?: scalar|Param|null, // Default: null - * routes?: array{ - * host?: scalar|Param|null, // Default: null - * options_method?: scalar|Param|null, // Default: "POST" - * options_path?: scalar|Param|null, // Default: "/register/options" - * result_method?: scalar|Param|null, // Default: "POST" - * result_path?: scalar|Param|null, // Default: "/register" - * }, - * options_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultCreationOptionsHandler" + * switch_user?: array{ + * provider?: scalar|Param|null, + * parameter?: scalar|Param|null, // Default: "_switch_user" + * role?: scalar|Param|null, // Default: "ROLE_ALLOWED_TO_SWITCH" + * target_route?: scalar|Param|null, // Default: null * }, - * }, - * x509?: array{ - * provider?: scalar|Param|null, - * user?: scalar|Param|null, // Default: "SSL_CLIENT_S_DN_Email" - * credentials?: scalar|Param|null, // Default: "SSL_CLIENT_S_DN" - * user_identifier?: scalar|Param|null, // Default: "emailAddress" - * }, - * remote_user?: array{ - * provider?: scalar|Param|null, - * user?: scalar|Param|null, // Default: "REMOTE_USER" - * }, - * saml?: array{ - * provider?: scalar|Param|null, - * remember_me?: bool|Param, // Default: true - * success_handler?: scalar|Param|null, // Default: "Nbgrp\\OneloginSamlBundle\\Security\\Http\\Authentication\\SamlAuthenticationSuccessHandler" - * failure_handler?: scalar|Param|null, - * check_path?: scalar|Param|null, // Default: "/login_check" - * use_forward?: bool|Param, // Default: false - * login_path?: scalar|Param|null, // Default: "/login" - * identifier_attribute?: scalar|Param|null, // Default: null - * use_attribute_friendly_name?: bool|Param, // Default: false - * user_factory?: scalar|Param|null, // Default: null - * token_factory?: scalar|Param|null, // Default: null - * persist_user?: bool|Param, // Default: false - * always_use_default_target_path?: bool|Param, // Default: false - * default_target_path?: scalar|Param|null, // Default: "/" - * target_path_parameter?: scalar|Param|null, // Default: "_target_path" - * use_referer?: bool|Param, // Default: false - * failure_path?: scalar|Param|null, // Default: null - * failure_forward?: bool|Param, // Default: false - * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" - * }, - * login_link?: array{ - * check_route?: scalar|Param|null, // Route that will validate the login link - e.g. "app_login_link_verify". - * check_post_only?: scalar|Param|null, // If true, only HTTP POST requests to "check_route" will be handled by the authenticator. // Default: false - * signature_properties?: list, - * lifetime?: int|Param, // The lifetime of the login link in seconds. // Default: 600 - * max_uses?: int|Param, // Max number of times a login link can be used - null means unlimited within lifetime. // Default: null - * used_link_cache?: scalar|Param|null, // Cache service id used to expired links of max_uses is set. - * success_handler?: scalar|Param|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface. - * failure_handler?: scalar|Param|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface. - * provider?: scalar|Param|null, // The user provider to load users from. - * secret?: scalar|Param|null, // Default: "%kernel.secret%" - * always_use_default_target_path?: bool|Param, // Default: false - * default_target_path?: scalar|Param|null, // Default: "/" - * login_path?: scalar|Param|null, // Default: "/login" - * target_path_parameter?: scalar|Param|null, // Default: "_target_path" - * use_referer?: bool|Param, // Default: false - * failure_path?: scalar|Param|null, // Default: null - * failure_forward?: bool|Param, // Default: false - * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" - * }, - * form_login?: array{ - * provider?: scalar|Param|null, - * remember_me?: bool|Param, // Default: true - * success_handler?: scalar|Param|null, - * failure_handler?: scalar|Param|null, - * check_path?: scalar|Param|null, // Default: "/login_check" - * use_forward?: bool|Param, // Default: false - * login_path?: scalar|Param|null, // Default: "/login" - * username_parameter?: scalar|Param|null, // Default: "_username" - * password_parameter?: scalar|Param|null, // Default: "_password" - * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" - * csrf_token_id?: scalar|Param|null, // Default: "authenticate" - * enable_csrf?: bool|Param, // Default: false - * post_only?: bool|Param, // Default: true - * form_only?: bool|Param, // Default: false - * always_use_default_target_path?: bool|Param, // Default: false - * default_target_path?: scalar|Param|null, // Default: "/" - * target_path_parameter?: scalar|Param|null, // Default: "_target_path" - * use_referer?: bool|Param, // Default: false - * failure_path?: scalar|Param|null, // Default: null - * failure_forward?: bool|Param, // Default: false - * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" - * }, - * form_login_ldap?: array{ - * provider?: scalar|Param|null, - * remember_me?: bool|Param, // Default: true - * success_handler?: scalar|Param|null, - * failure_handler?: scalar|Param|null, - * check_path?: scalar|Param|null, // Default: "/login_check" - * use_forward?: bool|Param, // Default: false - * login_path?: scalar|Param|null, // Default: "/login" - * username_parameter?: scalar|Param|null, // Default: "_username" - * password_parameter?: scalar|Param|null, // Default: "_password" - * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" - * csrf_token_id?: scalar|Param|null, // Default: "authenticate" - * enable_csrf?: bool|Param, // Default: false - * post_only?: bool|Param, // Default: true - * form_only?: bool|Param, // Default: false - * always_use_default_target_path?: bool|Param, // Default: false - * default_target_path?: scalar|Param|null, // Default: "/" - * target_path_parameter?: scalar|Param|null, // Default: "_target_path" - * use_referer?: bool|Param, // Default: false - * failure_path?: scalar|Param|null, // Default: null - * failure_forward?: bool|Param, // Default: false - * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" - * service?: scalar|Param|null, // Default: "ldap" - * dn_string?: scalar|Param|null, // Default: "{user_identifier}" - * query_string?: scalar|Param|null, - * search_dn?: scalar|Param|null, // Default: "" - * search_password?: scalar|Param|null, // Default: "" - * }, - * json_login?: array{ - * provider?: scalar|Param|null, - * remember_me?: bool|Param, // Default: true - * success_handler?: scalar|Param|null, - * failure_handler?: scalar|Param|null, - * check_path?: scalar|Param|null, // Default: "/login_check" - * use_forward?: bool|Param, // Default: false - * login_path?: scalar|Param|null, // Default: "/login" - * username_path?: scalar|Param|null, // Default: "username" - * password_path?: scalar|Param|null, // Default: "password" - * }, - * json_login_ldap?: array{ - * provider?: scalar|Param|null, - * remember_me?: bool|Param, // Default: true - * success_handler?: scalar|Param|null, - * failure_handler?: scalar|Param|null, - * check_path?: scalar|Param|null, // Default: "/login_check" - * use_forward?: bool|Param, // Default: false - * login_path?: scalar|Param|null, // Default: "/login" - * username_path?: scalar|Param|null, // Default: "username" - * password_path?: scalar|Param|null, // Default: "password" - * service?: scalar|Param|null, // Default: "ldap" - * dn_string?: scalar|Param|null, // Default: "{user_identifier}" - * query_string?: scalar|Param|null, - * search_dn?: scalar|Param|null, // Default: "" - * search_password?: scalar|Param|null, // Default: "" - * }, - * access_token?: array{ - * provider?: scalar|Param|null, - * remember_me?: bool|Param, // Default: true - * success_handler?: scalar|Param|null, - * failure_handler?: scalar|Param|null, - * realm?: scalar|Param|null, // Default: null - * token_extractors?: list, - * token_handler?: string|array{ - * id?: scalar|Param|null, - * oidc_user_info?: string|array{ - * base_uri?: scalar|Param|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured). - * discovery?: array{ // Enable the OIDC discovery. - * cache?: array{ - * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. - * }, - * }, - * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g. sub, email, etc.). // Default: "sub" - * client?: scalar|Param|null, // HttpClient service id to use to call the OIDC server. - * }, - * oidc?: array{ - * discovery?: array{ // Enable the OIDC discovery. - * base_uri?: list, - * cache?: array{ - * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. - * }, - * }, - * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g.: sub, email..). // Default: "sub" - * audience?: scalar|Param|null, // Audience set in the token, for validation purpose. - * issuers?: list, - * algorithm?: array, - * algorithms?: list, - * key?: scalar|Param|null, // Deprecated: The "key" option is deprecated and will be removed in 8.0. Use the "keyset" option instead. // JSON-encoded JWK used to sign the token (must contain a "kty" key). - * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to sign the token (must contain a list of valid public keys). - * encryption?: bool|array{ - * enabled?: bool|Param, // Default: false - * enforce?: bool|Param, // When enabled, the token shall be encrypted. // Default: false - * algorithms?: list, - * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys). - * }, - * }, - * cas?: array{ - * validation_url?: scalar|Param|null, // CAS server validation URL - * prefix?: scalar|Param|null, // CAS prefix // Default: "cas" - * http_client?: scalar|Param|null, // HTTP Client service // Default: null - * }, - * oauth2?: scalar|Param|null, + * required_badges?: list, + * custom_authenticators?: list, + * login_throttling?: array{ + * limiter?: scalar|Param|null, // A service id implementing "Symfony\Component\HttpFoundation\RateLimiter\RequestRateLimiterInterface". + * max_attempts?: int|Param, // Default: 5 + * interval?: scalar|Param|null, // Default: "1 minute" + * lock_factory?: scalar|Param|null, // The service ID of the lock factory used by the login rate limiter (or null to disable locking). // Default: null + * cache_pool?: string|Param, // The cache pool to use for storing the limiter state // Default: "cache.rate_limiter" + * storage_service?: string|Param, // The service ID of a custom storage implementation, this precedes any configured "cache_pool" // Default: null * }, - * }, - * http_basic?: array{ - * provider?: scalar|Param|null, - * realm?: scalar|Param|null, // Default: "Secured Area" - * }, - * http_basic_ldap?: array{ - * provider?: scalar|Param|null, - * realm?: scalar|Param|null, // Default: "Secured Area" - * service?: scalar|Param|null, // Default: "ldap" - * dn_string?: scalar|Param|null, // Default: "{user_identifier}" - * query_string?: scalar|Param|null, - * search_dn?: scalar|Param|null, // Default: "" - * search_password?: scalar|Param|null, // Default: "" - * }, - * remember_me?: array{ - * secret?: scalar|Param|null, // Default: "%kernel.secret%" - * service?: scalar|Param|null, - * user_providers?: list, - * catch_exceptions?: bool|Param, // Default: true - * signature_properties?: list, - * token_provider?: string|array{ - * service?: scalar|Param|null, // The service ID of a custom remember-me token provider. - * doctrine?: bool|array{ + * two_factor?: array{ + * check_path?: scalar|Param|null, // Default: "/2fa_check" + * post_only?: bool|Param, // Default: true + * auth_form_path?: scalar|Param|null, // Default: "/2fa" + * always_use_default_target_path?: bool|Param, // Default: false + * default_target_path?: scalar|Param|null, // Default: "/" + * success_handler?: scalar|Param|null, // Default: null + * failure_handler?: scalar|Param|null, // Default: null + * authentication_required_handler?: scalar|Param|null, // Default: null + * auth_code_parameter_name?: scalar|Param|null, // Default: "_auth_code" + * trusted_parameter_name?: scalar|Param|null, // Default: "_trusted" + * remember_me_sets_trusted?: scalar|Param|null, // Default: false + * multi_factor?: bool|Param, // Default: false + * prepare_on_login?: bool|Param, // Default: false + * prepare_on_access_denied?: bool|Param, // Default: false + * enable_csrf?: scalar|Param|null, // Default: false + * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" + * csrf_token_id?: scalar|Param|null, // Default: "two_factor" + * csrf_header?: scalar|Param|null, // Default: null + * csrf_token_manager?: scalar|Param|null, // Default: "scheb_two_factor.csrf_token_manager" + * provider?: scalar|Param|null, // Default: null + * }, + * webauthn?: array{ + * user_provider?: scalar|Param|null, // Default: null + * options_storage?: scalar|Param|null, // Deprecated: The child node "options_storage" at path "security.firewalls..webauthn.options_storage" is deprecated. Please use the root option "options_storage" instead. // Default: null + * success_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultSuccessHandler" + * failure_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultFailureHandler" + * secured_rp_ids?: array, + * authentication?: bool|array{ + * enabled?: bool|Param, // Default: true + * profile?: scalar|Param|null, // Default: "default" + * options_builder?: scalar|Param|null, // Default: null + * routes?: array{ + * host?: scalar|Param|null, // Default: null + * options_method?: scalar|Param|null, // Default: "POST" + * options_path?: scalar|Param|null, // Default: "/login/options" + * result_method?: scalar|Param|null, // Default: "POST" + * result_path?: scalar|Param|null, // Default: "/login" + * }, + * options_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultRequestOptionsHandler" + * }, + * registration?: bool|array{ * enabled?: bool|Param, // Default: false - * connection?: scalar|Param|null, // Default: null + * hide_existing_credentials?: bool|Param, // Default: true + * profile?: scalar|Param|null, // Default: "default" + * options_builder?: scalar|Param|null, // Default: null + * routes?: array{ + * host?: scalar|Param|null, // Default: null + * options_method?: scalar|Param|null, // Default: "POST" + * options_path?: scalar|Param|null, // Default: "/register/options" + * result_method?: scalar|Param|null, // Default: "POST" + * result_path?: scalar|Param|null, // Default: "/register" + * }, + * options_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultCreationOptionsHandler" * }, * }, - * token_verifier?: scalar|Param|null, // The service ID of a custom rememberme token verifier. - * name?: scalar|Param|null, // Default: "REMEMBERME" - * lifetime?: int|Param, // Default: 31536000 - * path?: scalar|Param|null, // Default: "/" - * domain?: scalar|Param|null, // Default: null - * secure?: true|false|"auto"|Param, // Default: null - * httponly?: bool|Param, // Default: true - * samesite?: null|"lax"|"strict"|"none"|Param, // Default: "lax" - * always_remember_me?: bool|Param, // Default: false - * remember_me_parameter?: scalar|Param|null, // Default: "_remember_me" - * }, - * }>, + * x509?: array{ + * provider?: scalar|Param|null, + * user?: scalar|Param|null, // Default: "SSL_CLIENT_S_DN_Email" + * credentials?: scalar|Param|null, // Default: "SSL_CLIENT_S_DN" + * user_identifier?: scalar|Param|null, // Default: "emailAddress" + * }, + * remote_user?: array{ + * provider?: scalar|Param|null, + * user?: scalar|Param|null, // Default: "REMOTE_USER" + * }, + * saml?: array{ + * provider?: scalar|Param|null, + * remember_me?: bool|Param, // Default: true + * success_handler?: scalar|Param|null, // Default: "Nbgrp\\OneloginSamlBundle\\Security\\Http\\Authentication\\SamlAuthenticationSuccessHandler" + * failure_handler?: scalar|Param|null, + * check_path?: scalar|Param|null, // Default: "/login_check" + * use_forward?: bool|Param, // Default: false + * login_path?: scalar|Param|null, // Default: "/login" + * identifier_attribute?: scalar|Param|null, // Default: null + * use_attribute_friendly_name?: bool|Param, // Default: false + * user_factory?: scalar|Param|null, // Default: null + * token_factory?: scalar|Param|null, // Default: null + * persist_user?: bool|Param, // Default: false + * always_use_default_target_path?: bool|Param, // Default: false + * default_target_path?: scalar|Param|null, // Default: "/" + * target_path_parameter?: scalar|Param|null, // Default: "_target_path" + * use_referer?: bool|Param, // Default: false + * failure_path?: scalar|Param|null, // Default: null + * failure_forward?: bool|Param, // Default: false + * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" + * }, + * login_link?: array{ + * check_route?: scalar|Param|null, // Route that will validate the login link - e.g. "app_login_link_verify". + * check_post_only?: scalar|Param|null, // If true, only HTTP POST requests to "check_route" will be handled by the authenticator. // Default: false + * signature_properties?: list, + * lifetime?: int|Param, // The lifetime of the login link in seconds. // Default: 600 + * max_uses?: int|Param, // Max number of times a login link can be used - null means unlimited within lifetime. // Default: null + * used_link_cache?: scalar|Param|null, // Cache service id used to expired links of max_uses is set. + * success_handler?: scalar|Param|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface. + * failure_handler?: scalar|Param|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface. + * provider?: scalar|Param|null, // The user provider to load users from. + * secret?: scalar|Param|null, // Default: "%kernel.secret%" + * always_use_default_target_path?: bool|Param, // Default: false + * default_target_path?: scalar|Param|null, // Default: "/" + * login_path?: scalar|Param|null, // Default: "/login" + * target_path_parameter?: scalar|Param|null, // Default: "_target_path" + * use_referer?: bool|Param, // Default: false + * failure_path?: scalar|Param|null, // Default: null + * failure_forward?: bool|Param, // Default: false + * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" + * }, + * form_login?: array{ + * provider?: scalar|Param|null, + * remember_me?: bool|Param, // Default: true + * success_handler?: scalar|Param|null, + * failure_handler?: scalar|Param|null, + * check_path?: scalar|Param|null, // Default: "/login_check" + * use_forward?: bool|Param, // Default: false + * login_path?: scalar|Param|null, // Default: "/login" + * username_parameter?: scalar|Param|null, // Default: "_username" + * password_parameter?: scalar|Param|null, // Default: "_password" + * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" + * csrf_token_id?: scalar|Param|null, // Default: "authenticate" + * enable_csrf?: bool|Param, // Default: false + * post_only?: bool|Param, // Default: true + * form_only?: bool|Param, // Default: false + * always_use_default_target_path?: bool|Param, // Default: false + * default_target_path?: scalar|Param|null, // Default: "/" + * target_path_parameter?: scalar|Param|null, // Default: "_target_path" + * use_referer?: bool|Param, // Default: false + * failure_path?: scalar|Param|null, // Default: null + * failure_forward?: bool|Param, // Default: false + * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" + * }, + * form_login_ldap?: array{ + * provider?: scalar|Param|null, + * remember_me?: bool|Param, // Default: true + * success_handler?: scalar|Param|null, + * failure_handler?: scalar|Param|null, + * check_path?: scalar|Param|null, // Default: "/login_check" + * use_forward?: bool|Param, // Default: false + * login_path?: scalar|Param|null, // Default: "/login" + * username_parameter?: scalar|Param|null, // Default: "_username" + * password_parameter?: scalar|Param|null, // Default: "_password" + * csrf_parameter?: scalar|Param|null, // Default: "_csrf_token" + * csrf_token_id?: scalar|Param|null, // Default: "authenticate" + * enable_csrf?: bool|Param, // Default: false + * post_only?: bool|Param, // Default: true + * form_only?: bool|Param, // Default: false + * always_use_default_target_path?: bool|Param, // Default: false + * default_target_path?: scalar|Param|null, // Default: "/" + * target_path_parameter?: scalar|Param|null, // Default: "_target_path" + * use_referer?: bool|Param, // Default: false + * failure_path?: scalar|Param|null, // Default: null + * failure_forward?: bool|Param, // Default: false + * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" + * service?: scalar|Param|null, // Default: "ldap" + * dn_string?: scalar|Param|null, // Default: "{user_identifier}" + * query_string?: scalar|Param|null, + * search_dn?: scalar|Param|null, // Default: "" + * search_password?: scalar|Param|null, // Default: "" + * }, + * json_login?: array{ + * provider?: scalar|Param|null, + * remember_me?: bool|Param, // Default: true + * success_handler?: scalar|Param|null, + * failure_handler?: scalar|Param|null, + * check_path?: scalar|Param|null, // Default: "/login_check" + * use_forward?: bool|Param, // Default: false + * login_path?: scalar|Param|null, // Default: "/login" + * username_path?: scalar|Param|null, // Default: "username" + * password_path?: scalar|Param|null, // Default: "password" + * }, + * json_login_ldap?: array{ + * provider?: scalar|Param|null, + * remember_me?: bool|Param, // Default: true + * success_handler?: scalar|Param|null, + * failure_handler?: scalar|Param|null, + * check_path?: scalar|Param|null, // Default: "/login_check" + * use_forward?: bool|Param, // Default: false + * login_path?: scalar|Param|null, // Default: "/login" + * username_path?: scalar|Param|null, // Default: "username" + * password_path?: scalar|Param|null, // Default: "password" + * service?: scalar|Param|null, // Default: "ldap" + * dn_string?: scalar|Param|null, // Default: "{user_identifier}" + * query_string?: scalar|Param|null, + * search_dn?: scalar|Param|null, // Default: "" + * search_password?: scalar|Param|null, // Default: "" + * }, + * access_token?: array{ + * provider?: scalar|Param|null, + * remember_me?: bool|Param, // Default: true + * success_handler?: scalar|Param|null, + * failure_handler?: scalar|Param|null, + * realm?: scalar|Param|null, // Default: null + * token_extractors?: string|list, + * token_handler?: string|array{ + * id?: scalar|Param|null, + * oidc_user_info?: string|array{ + * base_uri?: scalar|Param|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured). + * discovery?: array{ // Enable the OIDC discovery. + * cache?: array{ + * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. + * }, + * }, + * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g. sub, email, etc.). // Default: "sub" + * client?: scalar|Param|null, // HttpClient service id to use to call the OIDC server. + * }, + * oidc?: array{ + * discovery?: array{ // Enable the OIDC discovery. + * base_uri?: string|list, + * cache?: array{ + * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. + * }, + * }, + * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g.: sub, email..). // Default: "sub" + * audience?: scalar|Param|null, // Audience set in the token, for validation purpose. + * issuers?: list, + * algorithm?: array, + * algorithms?: list, + * key?: scalar|Param|null, // Deprecated: The "key" option is deprecated and will be removed in 8.0. Use the "keyset" option instead. // JSON-encoded JWK used to sign the token (must contain a "kty" key). + * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to sign the token (must contain a list of valid public keys). + * encryption?: bool|array{ + * enabled?: bool|Param, // Default: false + * enforce?: bool|Param, // When enabled, the token shall be encrypted. // Default: false + * algorithms?: list, + * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys). + * }, + * }, + * cas?: array{ + * validation_url?: scalar|Param|null, // CAS server validation URL + * prefix?: scalar|Param|null, // CAS prefix // Default: "cas" + * http_client?: scalar|Param|null, // HTTP Client service // Default: null + * }, + * oauth2?: scalar|Param|null, + * }, + * }, + * http_basic?: array{ + * provider?: scalar|Param|null, + * realm?: scalar|Param|null, // Default: "Secured Area" + * }, + * http_basic_ldap?: array{ + * provider?: scalar|Param|null, + * realm?: scalar|Param|null, // Default: "Secured Area" + * service?: scalar|Param|null, // Default: "ldap" + * dn_string?: scalar|Param|null, // Default: "{user_identifier}" + * query_string?: scalar|Param|null, + * search_dn?: scalar|Param|null, // Default: "" + * search_password?: scalar|Param|null, // Default: "" + * }, + * remember_me?: array{ + * secret?: scalar|Param|null, // Default: "%kernel.secret%" + * service?: scalar|Param|null, + * user_providers?: string|list, + * catch_exceptions?: bool|Param, // Default: true + * signature_properties?: list, + * token_provider?: string|array{ + * service?: scalar|Param|null, // The service ID of a custom remember-me token provider. + * doctrine?: bool|array{ + * enabled?: bool|Param, // Default: false + * connection?: scalar|Param|null, // Default: null + * }, + * }, + * token_verifier?: scalar|Param|null, // The service ID of a custom rememberme token verifier. + * name?: scalar|Param|null, // Default: "REMEMBERME" + * lifetime?: int|Param, // Default: 31536000 + * path?: scalar|Param|null, // Default: "/" + * domain?: scalar|Param|null, // Default: null + * secure?: true|false|"auto"|Param, // Default: null + * httponly?: bool|Param, // Default: true + * samesite?: null|"lax"|"strict"|"none"|Param, // Default: "lax" + * always_remember_me?: bool|Param, // Default: false + * remember_me_parameter?: scalar|Param|null, // Default: "_remember_me" + * }, + * }>, * access_control?: list, - * attributes?: array, - * route?: scalar|Param|null, // Default: null - * methods?: list, - * allow_if?: scalar|Param|null, // Default: null - * roles?: list, - * }>, + * request_matcher?: scalar|Param|null, // Default: null + * requires_channel?: scalar|Param|null, // Default: null + * path?: scalar|Param|null, // Use the urldecoded format. // Default: null + * host?: scalar|Param|null, // Default: null + * port?: int|Param, // Default: null + * ips?: string|list, + * attributes?: array, + * route?: scalar|Param|null, // Default: null + * methods?: string|list, + * allow_if?: scalar|Param|null, // Default: null + * roles?: string|list, + * }>, * role_hierarchy?: array>, * } * @psalm-type TwigConfig = array{ * form_themes?: list, * globals?: array, + * id?: scalar|Param|null, + * type?: scalar|Param|null, + * value?: mixed, + * }>, * autoescape_service?: scalar|Param|null, // Default: null * autoescape_service_method?: scalar|Param|null, // Default: null * base_template_class?: scalar|Param|null, // Deprecated: The child node "base_template_class" at path "twig.base_template_class" is deprecated. @@ -1351,7 +1352,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * auto_reload?: scalar|Param|null, * optimizations?: int|Param, * default_path?: scalar|Param|null, // The default path used to load templates. // Default: "%kernel.project_dir%/templates" - * file_name_pattern?: list, + * file_name_pattern?: string|list, * paths?: array, * date?: array{ // The default format options used by the date filter. * format?: scalar|Param|null, // Default: "F j, Y H:i" @@ -1379,144 +1380,144 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * use_microseconds?: scalar|Param|null, // Default: true * channels?: list, * handlers?: array, - * }>, - * accepted_levels?: list, - * min_level?: scalar|Param|null, // Default: "DEBUG" - * max_level?: scalar|Param|null, // Default: "EMERGENCY" - * buffer_size?: scalar|Param|null, // Default: 0 - * flush_on_overflow?: bool|Param, // Default: false - * handler?: scalar|Param|null, - * url?: scalar|Param|null, - * exchange?: scalar|Param|null, - * exchange_name?: scalar|Param|null, // Default: "log" - * channel?: scalar|Param|null, // Default: null - * bot_name?: scalar|Param|null, // Default: "Monolog" - * use_attachment?: scalar|Param|null, // Default: true - * use_short_attachment?: scalar|Param|null, // Default: false - * include_extra?: scalar|Param|null, // Default: false - * icon_emoji?: scalar|Param|null, // Default: null - * webhook_url?: scalar|Param|null, - * exclude_fields?: list, - * token?: scalar|Param|null, - * region?: scalar|Param|null, - * source?: scalar|Param|null, - * use_ssl?: bool|Param, // Default: true - * user?: mixed, - * title?: scalar|Param|null, // Default: null - * host?: scalar|Param|null, // Default: null - * port?: scalar|Param|null, // Default: 514 - * config?: list, - * members?: list, - * connection_string?: scalar|Param|null, - * timeout?: scalar|Param|null, - * time?: scalar|Param|null, // Default: 60 - * deduplication_level?: scalar|Param|null, // Default: 400 - * store?: scalar|Param|null, // Default: null - * connection_timeout?: scalar|Param|null, - * persistent?: bool|Param, - * message_type?: scalar|Param|null, // Default: 0 - * parse_mode?: scalar|Param|null, // Default: null - * disable_webpage_preview?: bool|Param|null, // Default: null - * disable_notification?: bool|Param|null, // Default: null - * split_long_messages?: bool|Param, // Default: false - * delay_between_messages?: bool|Param, // Default: false - * topic?: int|Param, // Default: null - * factor?: int|Param, // Default: 1 - * tags?: list, - * console_formatter_options?: mixed, // Default: [] - * formatter?: scalar|Param|null, - * nested?: bool|Param, // Default: false - * publisher?: string|array{ - * id?: scalar|Param|null, - * hostname?: scalar|Param|null, - * port?: scalar|Param|null, // Default: 12201 - * chunk_size?: scalar|Param|null, // Default: 1420 - * encoder?: "json"|"compressed_json"|Param, - * }, - * mongodb?: string|array{ - * id?: scalar|Param|null, // ID of a MongoDB\Client service - * uri?: scalar|Param|null, - * username?: scalar|Param|null, - * password?: scalar|Param|null, - * database?: scalar|Param|null, // Default: "monolog" - * collection?: scalar|Param|null, // Default: "logs" - * }, - * elasticsearch?: string|array{ - * id?: scalar|Param|null, - * hosts?: list, - * host?: scalar|Param|null, - * port?: scalar|Param|null, // Default: 9200 - * transport?: scalar|Param|null, // Default: "Http" - * user?: scalar|Param|null, // Default: null - * password?: scalar|Param|null, // Default: null - * }, - * index?: scalar|Param|null, // Default: "monolog" - * document_type?: scalar|Param|null, // Default: "logs" - * ignore_error?: scalar|Param|null, // Default: false - * redis?: string|array{ - * id?: scalar|Param|null, - * host?: scalar|Param|null, - * password?: scalar|Param|null, // Default: null - * port?: scalar|Param|null, // Default: 6379 - * database?: scalar|Param|null, // Default: 0 - * key_name?: scalar|Param|null, // Default: "monolog_redis" - * }, - * predis?: string|array{ - * id?: scalar|Param|null, - * host?: scalar|Param|null, - * }, - * from_email?: scalar|Param|null, - * to_email?: list, - * subject?: scalar|Param|null, - * content_type?: scalar|Param|null, // Default: null - * headers?: list, - * mailer?: scalar|Param|null, // Default: null - * email_prototype?: string|array{ - * id?: scalar|Param|null, - * method?: scalar|Param|null, // Default: null - * }, - * verbosity_levels?: array{ - * VERBOSITY_QUIET?: scalar|Param|null, // Default: "ERROR" - * VERBOSITY_NORMAL?: scalar|Param|null, // Default: "WARNING" - * VERBOSITY_VERBOSE?: scalar|Param|null, // Default: "NOTICE" - * VERBOSITY_VERY_VERBOSE?: scalar|Param|null, // Default: "INFO" - * VERBOSITY_DEBUG?: scalar|Param|null, // Default: "DEBUG" - * }, - * channels?: string|array{ * type?: scalar|Param|null, - * elements?: list, - * }, - * }>, + * id?: scalar|Param|null, + * enabled?: bool|Param, // Default: true + * priority?: scalar|Param|null, // Default: 0 + * level?: scalar|Param|null, // Default: "DEBUG" + * bubble?: bool|Param, // Default: true + * interactive_only?: bool|Param, // Default: false + * app_name?: scalar|Param|null, // Default: null + * include_stacktraces?: bool|Param, // Default: false + * process_psr_3_messages?: array{ + * enabled?: bool|Param|null, // Default: null + * date_format?: scalar|Param|null, + * remove_used_context_fields?: bool|Param, + * }, + * path?: scalar|Param|null, // Default: "%kernel.logs_dir%/%kernel.environment%.log" + * file_permission?: scalar|Param|null, // Default: null + * use_locking?: bool|Param, // Default: false + * filename_format?: scalar|Param|null, // Default: "{filename}-{date}" + * date_format?: scalar|Param|null, // Default: "Y-m-d" + * ident?: scalar|Param|null, // Default: false + * logopts?: scalar|Param|null, // Default: 1 + * facility?: scalar|Param|null, // Default: "user" + * max_files?: scalar|Param|null, // Default: 0 + * action_level?: scalar|Param|null, // Default: "WARNING" + * activation_strategy?: scalar|Param|null, // Default: null + * stop_buffering?: bool|Param, // Default: true + * passthru_level?: scalar|Param|null, // Default: null + * excluded_http_codes?: list, + * }>, + * accepted_levels?: list, + * min_level?: scalar|Param|null, // Default: "DEBUG" + * max_level?: scalar|Param|null, // Default: "EMERGENCY" + * buffer_size?: scalar|Param|null, // Default: 0 + * flush_on_overflow?: bool|Param, // Default: false + * handler?: scalar|Param|null, + * url?: scalar|Param|null, + * exchange?: scalar|Param|null, + * exchange_name?: scalar|Param|null, // Default: "log" + * channel?: scalar|Param|null, // Default: null + * bot_name?: scalar|Param|null, // Default: "Monolog" + * use_attachment?: scalar|Param|null, // Default: true + * use_short_attachment?: scalar|Param|null, // Default: false + * include_extra?: scalar|Param|null, // Default: false + * icon_emoji?: scalar|Param|null, // Default: null + * webhook_url?: scalar|Param|null, + * exclude_fields?: list, + * token?: scalar|Param|null, + * region?: scalar|Param|null, + * source?: scalar|Param|null, + * use_ssl?: bool|Param, // Default: true + * user?: mixed, + * title?: scalar|Param|null, // Default: null + * host?: scalar|Param|null, // Default: null + * port?: scalar|Param|null, // Default: 514 + * config?: list, + * members?: list, + * connection_string?: scalar|Param|null, + * timeout?: scalar|Param|null, + * time?: scalar|Param|null, // Default: 60 + * deduplication_level?: scalar|Param|null, // Default: 400 + * store?: scalar|Param|null, // Default: null + * connection_timeout?: scalar|Param|null, + * persistent?: bool|Param, + * message_type?: scalar|Param|null, // Default: 0 + * parse_mode?: scalar|Param|null, // Default: null + * disable_webpage_preview?: bool|Param|null, // Default: null + * disable_notification?: bool|Param|null, // Default: null + * split_long_messages?: bool|Param, // Default: false + * delay_between_messages?: bool|Param, // Default: false + * topic?: int|Param, // Default: null + * factor?: int|Param, // Default: 1 + * tags?: string|list, + * console_formatter_options?: mixed, // Default: [] + * formatter?: scalar|Param|null, + * nested?: bool|Param, // Default: false + * publisher?: string|array{ + * id?: scalar|Param|null, + * hostname?: scalar|Param|null, + * port?: scalar|Param|null, // Default: 12201 + * chunk_size?: scalar|Param|null, // Default: 1420 + * encoder?: "json"|"compressed_json"|Param, + * }, + * mongodb?: string|array{ + * id?: scalar|Param|null, // ID of a MongoDB\Client service + * uri?: scalar|Param|null, + * username?: scalar|Param|null, + * password?: scalar|Param|null, + * database?: scalar|Param|null, // Default: "monolog" + * collection?: scalar|Param|null, // Default: "logs" + * }, + * elasticsearch?: string|array{ + * id?: scalar|Param|null, + * hosts?: list, + * host?: scalar|Param|null, + * port?: scalar|Param|null, // Default: 9200 + * transport?: scalar|Param|null, // Default: "Http" + * user?: scalar|Param|null, // Default: null + * password?: scalar|Param|null, // Default: null + * }, + * index?: scalar|Param|null, // Default: "monolog" + * document_type?: scalar|Param|null, // Default: "logs" + * ignore_error?: scalar|Param|null, // Default: false + * redis?: string|array{ + * id?: scalar|Param|null, + * host?: scalar|Param|null, + * password?: scalar|Param|null, // Default: null + * port?: scalar|Param|null, // Default: 6379 + * database?: scalar|Param|null, // Default: 0 + * key_name?: scalar|Param|null, // Default: "monolog_redis" + * }, + * predis?: string|array{ + * id?: scalar|Param|null, + * host?: scalar|Param|null, + * }, + * from_email?: scalar|Param|null, + * to_email?: string|list, + * subject?: scalar|Param|null, + * content_type?: scalar|Param|null, // Default: null + * headers?: list, + * mailer?: scalar|Param|null, // Default: null + * email_prototype?: string|array{ + * id?: scalar|Param|null, + * method?: scalar|Param|null, // Default: null + * }, + * verbosity_levels?: array{ + * VERBOSITY_QUIET?: scalar|Param|null, // Default: "ERROR" + * VERBOSITY_NORMAL?: scalar|Param|null, // Default: "WARNING" + * VERBOSITY_VERBOSE?: scalar|Param|null, // Default: "NOTICE" + * VERBOSITY_VERY_VERBOSE?: scalar|Param|null, // Default: "INFO" + * VERBOSITY_DEBUG?: scalar|Param|null, // Default: "DEBUG" + * }, + * channels?: string|array{ + * type?: scalar|Param|null, + * elements?: list, + * }, + * }>, * } * @psalm-type DebugConfig = array{ * max_items?: int|Param, // Max number of displayed items past the first level, -1 means no limit. // Default: 2500 @@ -1556,52 +1557,52 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * } * @psalm-type LiipImagineConfig = array{ * resolvers?: array, - * get_options?: array, - * put_options?: array, - * proxies?: array, - * }, - * flysystem?: array{ - * filesystem_service?: scalar|Param|null, - * cache_prefix?: scalar|Param|null, // Default: "" - * root_url?: scalar|Param|null, - * visibility?: "public"|"private"|"noPredefinedVisibility"|Param, // Default: "public" - * }, - * }>, - * loaders?: array, - * allow_unresolvable_data_roots?: bool|Param, // Default: false - * bundle_resources?: array{ - * enabled?: bool|Param, // Default: false - * access_control_type?: "blacklist"|"whitelist"|Param, // Sets the access control method applied to bundle names in "access_control_list" into a blacklist or whitelist. // Default: "blacklist" - * access_control_list?: list, + * web_path?: array{ + * web_root?: scalar|Param|null, // Default: "%kernel.project_dir%/public" + * cache_prefix?: scalar|Param|null, // Default: "media/cache" * }, - * }, - * flysystem?: array{ - * filesystem_service?: scalar|Param|null, - * }, - * asset_mapper?: array, - * chain?: array{ - * loaders?: list, - * }, - * }>, + * aws_s3?: array{ + * bucket?: scalar|Param|null, + * cache?: scalar|Param|null, // Default: false + * use_psr_cache?: bool|Param, // Default: false + * acl?: scalar|Param|null, // Default: "public-read" + * cache_prefix?: scalar|Param|null, // Default: "" + * client_id?: scalar|Param|null, // Default: null + * client_config?: list, + * get_options?: array, + * put_options?: array, + * proxies?: array, + * }, + * flysystem?: array{ + * filesystem_service?: scalar|Param|null, + * cache_prefix?: scalar|Param|null, // Default: "" + * root_url?: scalar|Param|null, + * visibility?: "public"|"private"|"noPredefinedVisibility"|Param, // Default: "public" + * }, + * }>, + * loaders?: array, + * allow_unresolvable_data_roots?: bool|Param, // Default: false + * bundle_resources?: array{ + * enabled?: bool|Param, // Default: false + * access_control_type?: "blacklist"|"whitelist"|Param, // Sets the access control method applied to bundle names in "access_control_list" into a blacklist or whitelist. // Default: "blacklist" + * access_control_list?: list, + * }, + * }, + * flysystem?: array{ + * filesystem_service?: scalar|Param|null, + * }, + * asset_mapper?: array, + * chain?: array{ + * loaders?: list, + * }, + * }>, * driver?: scalar|Param|null, // Default: "gd" * cache?: scalar|Param|null, // Default: "default" * cache_base_path?: scalar|Param|null, // Default: "" @@ -1626,18 +1627,18 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * redirect_response_code?: int|Param, // Default: 302 * }, * filter_sets?: array>, - * post_processors?: array>, - * }>, + * quality?: scalar|Param|null, + * jpeg_quality?: scalar|Param|null, + * png_compression_level?: scalar|Param|null, + * png_compression_filter?: scalar|Param|null, + * format?: scalar|Param|null, + * animated?: bool|Param, + * cache?: scalar|Param|null, + * data_loader?: scalar|Param|null, + * default_image?: scalar|Param|null, + * filters?: array>, + * post_processors?: array>, + * }>, * twig?: array{ * mode?: "none"|"lazy"|"legacy"|Param, // Twig mode: none/lazy/legacy (default) // Default: "legacy" * assets_version?: scalar|Param|null, // Default: null @@ -1852,8 +1853,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * clickjacking?: array{ * hosts?: list, * paths?: array, + * header?: scalar|Param|null, // Default: "DENY" + * }>, * content_types?: list, * }, * external_redirects?: array{ @@ -1930,7 +1931,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * script-src?: list, * style-src?: list, * upgrade-insecure-requests?: bool|Param, // Default: false - * report-uri?: list, + * report-uri?: string|list, * worker-src?: list, * prefetch-src?: list, * report-to?: scalar|Param|null, @@ -1958,7 +1959,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * script-src?: list, * style-src?: list, * upgrade-insecure-requests?: bool|Param, // Default: false - * report-uri?: list, + * report-uri?: string|list, * worker-src?: list, * prefetch-src?: list, * report-to?: scalar|Param|null, @@ -1966,7 +1967,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * referrer_policy?: bool|array{ * enabled?: bool|Param, // Default: false - * policies?: list, + * policies?: string|list, * }, * permissions_policy?: bool|array{ * enabled?: bool|Param, // Default: false @@ -2018,12 +2019,12 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * cross_origin_isolation?: bool|array{ * enabled?: bool|Param, // Default: false * paths?: array, + * coep?: "unsafe-none"|"require-corp"|"credentialless"|Param, // Cross-Origin-Embedder-Policy (COEP) header value + * coop?: "unsafe-none"|"same-origin-allow-popups"|"same-origin"|"noopener-allow-popups"|Param, // Cross-Origin-Opener-Policy (COOP) header value + * corp?: "same-site"|"same-origin"|"cross-origin"|Param, // Cross-Origin-Resource-Policy (CORP) header value + * report_only?: bool|Param, // Use Report-Only headers instead of enforcing (applies to COEP and COOP only) // Default: false + * report_to?: scalar|Param|null, // Reporting endpoint name for violations (requires Reporting API configuration, applies to COEP and COOP only) // Default: null + * }>, * }, * } * @psalm-type TurboConfig = array{ @@ -2097,31 +2098,57 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * secured_rp_ids?: array, * counter_checker?: scalar|Param|null, // This service will check if the counter is valid. By default it throws an exception (recommended). // Default: "Webauthn\\Counter\\ThrowExceptionIfInvalid" * top_origin_validator?: scalar|Param|null, // For cross origin (e.g. iframe), this service will be in charge of verifying the top origin. // Default: null - * creation_profiles?: array, + * public_key_credential_parameters?: list, + * attestation_conveyance?: scalar|Param|null, // Default: "none" + * conditional_create?: bool|Param, // Enable Conditional Create (auto-register) for this profile. When true, user presence can be false after password authentication. See https://github.com/w3c/webauthn/wiki/Explainer:-Conditional-Create // Default: false + * }>, + * request_profiles?: bool|array, + * }>, + * client_override_policy?: array{ // Configuration for allowing client request values to override profile configuration + * user_verification?: array{ + * enabled?: bool|Param, // Whether to allow client requests to override the user verification requirement // Default: false + * allowed_values?: list, * }, - * extensions?: array, - * public_key_credential_parameters?: list, - * attestation_conveyance?: scalar|Param|null, // Default: "none" - * }>, - * request_profiles?: array, - * }>, + * authenticator_attachment?: array{ + * enabled?: bool|Param, // Whether to allow client requests to override the authenticator attachment // Default: true + * allowed_values?: list, + * }, + * resident_key?: array{ + * enabled?: bool|Param, // Whether to allow client requests to override the resident key requirement // Default: true + * allowed_values?: list, + * }, + * attestation_conveyance?: array{ + * enabled?: bool|Param, // Whether to allow client requests to override the attestation conveyance preference // Default: true + * allowed_values?: list, + * }, + * extensions?: array{ + * enabled?: bool|Param, // Whether to allow client requests to override extensions // Default: true + * }, + * mediation?: array{ + * enabled?: bool|Param, // Whether to allow client requests to request the conditional mediation flow (auto-register). // Default: false + * allowed_values?: list, + * }, + * }, * metadata?: bool|array{ // Enable the support of the Metadata Statements. Please read the documentation for this feature. * enabled?: bool|Param, // Default: false * mds_repository?: scalar|Param|null, // The Metadata Statement repository. @@ -2131,146 +2158,161 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * controllers?: bool|array{ * enabled?: bool|Param, // Default: false * creation?: array, - * allow_subdomains?: bool|Param, // Default: false - * secured_rp_ids?: array, - * }>, + * options_method?: scalar|Param|null, // Default: "POST" + * options_path?: scalar|Param|null, + * result_method?: scalar|Param|null, // Default: "POST" + * result_path?: scalar|Param|null, // Default: null + * host?: scalar|Param|null, // Default: null + * profile?: scalar|Param|null, // Default: "default" + * options_builder?: scalar|Param|null, // When set, corresponds to the ID of the Public Key Credential Creation Builder. The profile-based ebuilder is ignored. // Default: null + * user_entity_guesser?: scalar|Param|null, + * hide_existing_credentials?: scalar|Param|null, // In order to prevent username enumeration, the existing credentials can be hidden. This is highly recommended when the attestation ceremony is performed by anonymous users. // Default: false + * options_storage?: scalar|Param|null, // Deprecated: The child node "options_storage" at path "webauthn.controllers.creation..options_storage" is deprecated. Please use the root option "options_storage" instead. // Service responsible of the options/user entity storage during the ceremony // Default: null + * success_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Service\\DefaultSuccessHandler" + * failure_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Service\\DefaultFailureHandler" + * options_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultCreationOptionsHandler" + * allowed_origins?: array, + * allow_subdomains?: bool|Param, // Default: false + * secured_rp_ids?: array, + * }>, * request?: array, - * allow_subdomains?: bool|Param, // Default: false - * secured_rp_ids?: array, - * }>, + * options_method?: scalar|Param|null, // Default: "POST" + * options_path?: scalar|Param|null, + * result_method?: scalar|Param|null, // Default: "POST" + * result_path?: scalar|Param|null, // Default: null + * host?: scalar|Param|null, // Default: null + * profile?: scalar|Param|null, // Default: "default" + * options_builder?: scalar|Param|null, // When set, corresponds to the ID of the Public Key Credential Creation Builder. The profile-based ebuilder is ignored. // Default: null + * options_storage?: scalar|Param|null, // Deprecated: The child node "options_storage" at path "webauthn.controllers.request..options_storage" is deprecated. Please use the root option "options_storage" instead. // Service responsible of the options/user entity storage during the ceremony // Default: null + * success_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Service\\DefaultSuccessHandler" + * failure_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Service\\DefaultFailureHandler" + * options_handler?: scalar|Param|null, // Default: "Webauthn\\Bundle\\Security\\Handler\\DefaultRequestOptionsHandler" + * allowed_origins?: array, + * allow_subdomains?: bool|Param, // Default: false + * secured_rp_ids?: array, + * }>, + * }, + * passkey_endpoints?: bool|array{ // Enable the .well-known/passkey-endpoints discovery endpoint as defined in the W3C Passkey Endpoints specification. + * enabled?: bool|Param, // Default: false + * enroll?: string|array{ // URL to the passkey enrollment/creation interface. + * path?: scalar|Param|null, // The absolute HTTPS URL or Symfony route name. + * params?: list, + * }, + * manage?: string|array{ // URL to the passkey management interface. + * path?: scalar|Param|null, // The absolute HTTPS URL or Symfony route name. + * params?: list, + * }, + * prf_usage_details?: string|array{ // URL to informational page about PRF (Pseudo-Random Function) extension usage. + * path?: scalar|Param|null, // The absolute HTTPS URL or Symfony route name. + * params?: list, + * }, * }, * } * @psalm-type NbgrpOneloginSamlConfig = array{ // nb:group OneLogin PHP Symfony Bundle configuration * onelogin_settings?: array/saml/" - * strict?: bool|Param, - * debug?: bool|Param, - * idp?: array{ - * entityId?: scalar|Param|null, - * singleSignOnService?: array{ - * url?: scalar|Param|null, - * binding?: scalar|Param|null, + * baseurl?: scalar|Param|null, // Default: "/saml/" + * strict?: bool|Param, + * debug?: bool|Param, + * idp?: array{ + * entityId?: scalar|Param|null, + * singleSignOnService?: array{ + * url?: scalar|Param|null, + * binding?: scalar|Param|null, + * }, + * singleLogoutService?: array{ + * url?: scalar|Param|null, + * responseUrl?: scalar|Param|null, + * binding?: scalar|Param|null, + * }, + * x509cert?: scalar|Param|null, + * certFingerprint?: scalar|Param|null, + * certFingerprintAlgorithm?: "sha1"|"sha256"|"sha384"|"sha512"|Param, + * x509certMulti?: array{ + * signing?: list, + * encryption?: list, + * }, * }, - * singleLogoutService?: array{ - * url?: scalar|Param|null, - * responseUrl?: scalar|Param|null, - * binding?: scalar|Param|null, + * sp?: array{ + * entityId?: scalar|Param|null, // Default: "/saml/metadata" + * assertionConsumerService?: array{ + * url?: scalar|Param|null, // Default: "/saml/acs" + * binding?: scalar|Param|null, + * }, + * attributeConsumingService?: array{ + * serviceName?: scalar|Param|null, + * serviceDescription?: scalar|Param|null, + * requestedAttributes?: list, + * }>, + * }, + * singleLogoutService?: array{ + * url?: scalar|Param|null, // Default: "/saml/logout" + * binding?: scalar|Param|null, + * }, + * NameIDFormat?: scalar|Param|null, + * x509cert?: scalar|Param|null, + * privateKey?: scalar|Param|null, + * x509certNew?: scalar|Param|null, * }, - * x509cert?: scalar|Param|null, - * certFingerprint?: scalar|Param|null, - * certFingerprintAlgorithm?: "sha1"|"sha256"|"sha384"|"sha512"|Param, - * x509certMulti?: array{ - * signing?: list, - * encryption?: list, + * compress?: array{ + * requests?: bool|Param, + * responses?: bool|Param, * }, - * }, - * sp?: array{ - * entityId?: scalar|Param|null, // Default: "/saml/metadata" - * assertionConsumerService?: array{ - * url?: scalar|Param|null, // Default: "/saml/acs" - * binding?: scalar|Param|null, + * security?: array{ + * nameIdEncrypted?: bool|Param, + * authnRequestsSigned?: bool|Param, + * logoutRequestSigned?: bool|Param, + * logoutResponseSigned?: bool|Param, + * signMetadata?: bool|Param, + * wantMessagesSigned?: bool|Param, + * wantAssertionsEncrypted?: bool|Param, + * wantAssertionsSigned?: bool|Param, + * wantNameId?: bool|Param, + * wantNameIdEncrypted?: bool|Param, + * requestedAuthnContext?: mixed, + * requestedAuthnContextComparison?: "exact"|"minimum"|"maximum"|"better"|Param, + * wantXMLValidation?: bool|Param, + * relaxDestinationValidation?: bool|Param, + * destinationStrictlyMatches?: bool|Param, + * allowRepeatAttributeName?: bool|Param, + * rejectUnsolicitedResponsesWithInResponseTo?: bool|Param, + * signatureAlgorithm?: "http://www.w3.org/2000/09/xmldsig#rsa-sha1"|"http://www.w3.org/2000/09/xmldsig#dsa-sha1"|"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"|"http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"|"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"|Param, + * digestAlgorithm?: "http://www.w3.org/2000/09/xmldsig#sha1"|"http://www.w3.org/2001/04/xmlenc#sha256"|"http://www.w3.org/2001/04/xmldsig-more#sha384"|"http://www.w3.org/2001/04/xmlenc#sha512"|Param, + * encryption_algorithm?: "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"|"http://www.w3.org/2001/04/xmlenc#aes128-cbc"|"http://www.w3.org/2001/04/xmlenc#aes192-cbc"|"http://www.w3.org/2001/04/xmlenc#aes256-cbc"|"http://www.w3.org/2009/xmlenc11#aes128-gcm"|"http://www.w3.org/2009/xmlenc11#aes192-gcm"|"http://www.w3.org/2009/xmlenc11#aes256-gcm"|Param, + * lowercaseUrlencoding?: bool|Param, * }, - * attributeConsumingService?: array{ - * serviceName?: scalar|Param|null, - * serviceDescription?: scalar|Param|null, - * requestedAttributes?: list, + * displayname?: scalar|Param|null, + * url?: scalar|Param|null, * }>, - * }, - * singleLogoutService?: array{ - * url?: scalar|Param|null, // Default: "/saml/logout" - * binding?: scalar|Param|null, - * }, - * NameIDFormat?: scalar|Param|null, - * x509cert?: scalar|Param|null, - * privateKey?: scalar|Param|null, - * x509certNew?: scalar|Param|null, - * }, - * compress?: array{ - * requests?: bool|Param, - * responses?: bool|Param, - * }, - * security?: array{ - * nameIdEncrypted?: bool|Param, - * authnRequestsSigned?: bool|Param, - * logoutRequestSigned?: bool|Param, - * logoutResponseSigned?: bool|Param, - * signMetadata?: bool|Param, - * wantMessagesSigned?: bool|Param, - * wantAssertionsEncrypted?: bool|Param, - * wantAssertionsSigned?: bool|Param, - * wantNameId?: bool|Param, - * wantNameIdEncrypted?: bool|Param, - * requestedAuthnContext?: mixed, - * requestedAuthnContextComparison?: "exact"|"minimum"|"maximum"|"better"|Param, - * wantXMLValidation?: bool|Param, - * relaxDestinationValidation?: bool|Param, - * destinationStrictlyMatches?: bool|Param, - * allowRepeatAttributeName?: bool|Param, - * rejectUnsolicitedResponsesWithInResponseTo?: bool|Param, - * signatureAlgorithm?: "http://www.w3.org/2000/09/xmldsig#rsa-sha1"|"http://www.w3.org/2000/09/xmldsig#dsa-sha1"|"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"|"http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"|"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"|Param, - * digestAlgorithm?: "http://www.w3.org/2000/09/xmldsig#sha1"|"http://www.w3.org/2001/04/xmlenc#sha256"|"http://www.w3.org/2001/04/xmldsig-more#sha384"|"http://www.w3.org/2001/04/xmlenc#sha512"|Param, - * encryption_algorithm?: "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"|"http://www.w3.org/2001/04/xmlenc#aes128-cbc"|"http://www.w3.org/2001/04/xmlenc#aes192-cbc"|"http://www.w3.org/2001/04/xmlenc#aes256-cbc"|"http://www.w3.org/2009/xmlenc11#aes128-gcm"|"http://www.w3.org/2009/xmlenc11#aes192-gcm"|"http://www.w3.org/2009/xmlenc11#aes256-gcm"|Param, - * lowercaseUrlencoding?: bool|Param, - * }, - * contactPerson?: array{ - * technical?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, - * }, - * support?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, - * }, - * administrative?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, - * }, - * billing?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, - * }, - * other?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, - * }, - * }, - * organization?: list, - * }>, * use_proxy_vars?: bool|Param, // Default: false * idp_parameter_name?: scalar|Param|null, // Default: "idp" * entity_manager_name?: scalar|Param|null, @@ -2293,7 +2335,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * type?: scalar|Param|null, * elements?: list, * }, - * keys_patterns?: list, + * keys_patterns?: string|list, * } * @psalm-type DompdfFontLoaderConfig = array{ * autodiscovery?: bool|array{ @@ -2304,11 +2346,11 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * auto_install?: bool|Param, // Default: false * fonts?: list, + * normal?: scalar|Param|null, + * bold?: scalar|Param|null, + * italic?: scalar|Param|null, + * bold_italic?: scalar|Param|null, + * }>, * } * @psalm-type KnpuOauth2ClientConfig = array{ * http_client?: scalar|Param|null, // Service id of HTTP client to use (must implement GuzzleHttp\ClientInterface) // Default: null @@ -2334,18 +2376,18 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * skip_same_as_origin?: bool|Param, // Default: true * }, * paths?: array, - * allow_headers?: list, - * allow_methods?: list, - * allow_private_network?: bool|Param, - * expose_headers?: list, - * max_age?: scalar|Param|null, // Default: 0 - * hosts?: list, - * origin_regex?: bool|Param, - * forced_allow_origin_value?: scalar|Param|null, // Default: null - * skip_same_as_origin?: bool|Param, - * }>, + * allow_credentials?: bool|Param, + * allow_origin?: list, + * allow_headers?: list, + * allow_methods?: list, + * allow_private_network?: bool|Param, + * expose_headers?: list, + * max_age?: scalar|Param|null, // Default: 0 + * hosts?: list, + * origin_regex?: bool|Param, + * forced_allow_origin_value?: scalar|Param|null, // Default: null + * skip_same_as_origin?: bool|Param, + * }>, * } * @psalm-type JbtronicsSettingsConfig = array{ * search_paths?: list, @@ -2476,13 +2518,13 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * persist_authorization?: bool|Param, // Persist the SwaggerUI Authorization in the localStorage. // Default: false * versions?: list, * api_keys?: array, + * name?: scalar|Param|null, // The name of the header or query parameter containing the api key. + * type?: "query"|"header"|Param, // Whether the api key should be a query parameter or a header. + * }>, * http_auth?: array, + * scheme?: scalar|Param|null, // The OpenAPI HTTP auth scheme, for example "bearer" + * bearerFormat?: scalar|Param|null, // The OpenAPI HTTP bearer format + * }>, * swagger_ui_extra_configuration?: mixed, // To pass extra configuration to Swagger UI, like docExpansion or filter. // Default: [] * }, * http_cache?: array{ @@ -2523,9 +2565,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * termsOfService?: scalar|Param|null, // A URL to the Terms of Service for the API. MUST be in the format of a URL. // Default: null * tags?: list, + * name?: scalar|Param|null, + * description?: scalar|Param|null, // Default: null + * }>, * license?: array{ * name?: scalar|Param|null, // The license name used for the API. // Default: null * url?: scalar|Param|null, // URL to the license used for the API. MUST be in the format of a URL. // Default: null @@ -2547,17 +2589,17 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * exception_to_status?: array, * formats?: array, - * }>, + * mime_types?: list, + * }>, * patch_formats?: array, - * }>, + * mime_types?: list, + * }>, * docs_formats?: array, - * }>, + * mime_types?: list, + * }>, * error_formats?: array, - * }>, + * mime_types?: list, + * }>, * jsonschema_formats?: list, * defaults?: array{ * uri_template?: mixed, @@ -2629,30 +2671,30 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * policy?: mixed, * middleware?: mixed, * parameters?: array - * }>, + * key?: mixed, + * schema?: mixed, + * open_api?: mixed, + * provider?: mixed, + * filter?: mixed, + * property?: mixed, + * description?: mixed, + * properties?: mixed, + * required?: mixed, + * priority?: mixed, + * hydra?: mixed, + * constraints?: mixed, + * security?: mixed, + * security_message?: mixed, + * extra_properties?: mixed, + * filter_context?: mixed, + * native_type?: mixed, + * cast_to_array?: mixed, + * cast_to_native_type?: mixed, + * cast_fn?: mixed, + * default?: mixed, + * filter_class?: mixed, + * ... + * }>, * strict_query_parameter_validation?: mixed, * hide_hydra_operation?: mixed, * json_stream?: mixed, @@ -2693,22 +2735,22 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * cache_retention?: "none"|"short"|"long"|Param, // Prompt cache retention policy for Anthropic models // Default: "short" * }, * azure?: array, + * api_key?: string|Param, + * base_url?: string|Param, + * deployment?: string|Param, + * api_version?: string|Param, // The used API version + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }>, * bedrock?: array, + * bedrock_runtime_client?: string|Param, // Service ID of the Bedrock runtime client to use // Default: null + * model_catalog?: string|Param, // Default: null + * }>, * cache?: array, + * platform?: string|Param, + * service?: string|Param, // The cache service id as defined under the "cache" configuration key // Default: "cache.app" + * cache_key?: string|Param, // Key used to store platform results, if not set, the current platform name will be used, the "prompt_cache_key" can be set during platform call to override this value + * ttl?: int|Param, + * }>, * cartesia?: array{ * api_key?: string|Param, * version?: string|Param, @@ -2741,23 +2783,23 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" * }, * failover?: array, - * rate_limiter?: string|Param, - * }>, + * platforms?: list, + * rate_limiter?: string|Param, + * }>, * gemini?: array{ * api_key?: string|Param, * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" * }, * generic?: array, + * base_url?: string|Param, + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * model_catalog?: string|Param, // Service ID of the model catalog to use + * supports_completions?: bool|Param, // Default: true + * supports_embeddings?: bool|Param, // Default: true + * completions_path?: string|Param, // Default: "/v1/chat/completions" + * embeddings_path?: string|Param, // Default: "/v1/embeddings" + * }>, * huggingface?: array{ * api_key?: string|Param, * provider?: string|Param, // Default: "hf-inference" @@ -2810,328 +2852,328 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * }, * model?: array|\Symfony\AI\Platform\Capability|Param>, - * }>>, + * class?: string|Param, // The fully qualified class name of the model (must extend Symfony\AI\Platform\Model) // Default: "Symfony\\AI\\Platform\\Model" + * capabilities?: list|\Symfony\AI\Platform\Capability|Param>, + * }>>, * agent?: array, - * }, - * keep_tool_messages?: bool|Param, // Keep tool messages in the conversation history // Default: false - * include_sources?: bool|Param, // Include sources exposed by tools as part of the tool result metadata // Default: false - * fault_tolerant_toolbox?: bool|Param, // Continue the agent run even if a tool call fails // Default: true - * speech?: bool|array{ // Speech (TTS/STT) decorator configuration - * enabled?: bool|Param, // Default: true - * text_to_speech_platform?: string|Param, // Service name of the TTS platform (e.g. ai.platform.elevenlabs). // Default: null - * speech_to_text_platform?: string|Param, // Service name of the STT platform (e.g. ai.platform.openai). // Default: null - * tts_model?: string|Param, // Text-to-speech model name // Default: null - * tts_options?: mixed, // Provider-specific TTS options // Default: [] - * stt_model?: string|Param, // Speech-to-text model name // Default: null - * stt_options?: mixed, // Provider-specific STT options // Default: [] - * }, - * }>, + * platform?: string|Param, // Service name of platform // Default: "Symfony\\AI\\Platform\\PlatformInterface" + * model?: mixed, + * memory?: mixed, // Memory configuration: string for static memory, or array with "service" key for service reference // Default: null + * prompt?: string|array{ // The system prompt configuration + * text?: string|Param, // The system prompt text + * file?: string|Param, // Path to file containing the system prompt + * include_tools?: bool|Param, // Include tool definitions at the end of the system prompt // Default: false + * enable_translation?: bool|Param, // Enable translation for the system prompt // Default: false + * translation_domain?: string|Param, // The translation domain for the system prompt // Default: null + * }, + * tools?: bool|array{ + * enabled?: bool|Param, // Default: true + * services?: list, + * }, + * keep_tool_messages?: bool|Param, // Keep tool messages in the conversation history // Default: false + * include_sources?: bool|Param, // Include sources exposed by tools as part of the tool result metadata // Default: false + * fault_tolerant_toolbox?: bool|Param, // Continue the agent run even if a tool call fails // Default: true + * speech?: bool|array{ // Speech (TTS/STT) decorator configuration + * enabled?: bool|Param, // Default: true + * text_to_speech_platform?: string|Param, // Service name of the TTS platform (e.g. ai.platform.elevenlabs). // Default: null + * speech_to_text_platform?: string|Param, // Service name of the STT platform (e.g. ai.platform.openai). // Default: null + * tts_model?: string|Param, // Text-to-speech model name // Default: null + * tts_options?: mixed, // Provider-specific TTS options // Default: [] + * stt_model?: string|Param, // Speech-to-text model name // Default: null + * stt_options?: mixed, // Provider-specific STT options // Default: [] + * }, + * }>, * multi_agent?: array>, - * fallback?: string|Param, // Service ID of the fallback agent for unmatched requests - * }>, + * orchestrator?: string|Param, // Service ID of the orchestrator agent + * handoffs?: array>, + * fallback?: string|Param, // Service ID of the fallback agent for unmatched requests + * }>, * store?: array{ * azuresearch?: array, + * endpoint?: string|Param, + * api_key?: string|Param, + * api_version?: string|Param, + * index_name?: string|Param, // The name of the store will be used if the "index_name" option is not set + * http_client?: string|Param, // Default: "http_client" + * vector_field?: string|Param, // Default: "vector" + * }>, * cache?: array, + * service?: string|Param, // Default: "cache.app" + * cache_key?: string|Param, // The name of the store will be used if the key is not set. + * strategy?: string|Param, // Default: "cosine" + * }>, * chromadb?: array, + * client?: string|Param, // Default: "Codewithkyrian\\ChromaDB\\Client" + * collection?: string|Param, + * }>, * clickhouse?: array, + * dsn?: string|Param, + * http_client?: string|Param, + * database?: string|Param, + * table?: string|Param, + * }>, * cloudflare?: array, + * account_id?: string|Param, + * api_key?: string|Param, + * index_name?: string|Param, + * dimensions?: int|Param, // Default: 1536 + * metric?: string|Param, // Default: "cosine" + * endpoint?: string|Param, + * }>, * elasticsearch?: array, + * endpoint?: string|Param, + * index_name?: string|Param, + * vectors_field?: string|Param, // Default: "_vectors" + * dimensions?: int|Param, // Default: 1536 + * similarity?: string|Param, // Default: "cosine" + * http_client?: string|Param, // Default: "http_client" + * }>, * manticoresearch?: array, + * endpoint?: string|Param, + * table?: string|Param, + * field?: string|Param, // Default: "_vectors" + * type?: string|Param, // Default: "hnsw" + * similarity?: string|Param, // Default: "cosine" + * dimensions?: int|Param, // Default: 1536 + * quantization?: string|Param, + * }>, * mariadb?: array, + * connection?: string|Param, + * table_name?: string|Param, + * index_name?: string|Param, + * vector_field_name?: string|Param, + * setup_options?: array{ + * dimensions?: int|Param, + * }, + * distance?: "cosine"|"euclidean"|"distance"|Param, // Distance metric to use for vector similarity search // Default: "euclidean" + * }>, * meilisearch?: array, + * endpoint?: string|Param, + * api_key?: string|Param, + * index_name?: string|Param, + * embedder?: string|Param, // Default: "default" + * vector_field?: string|Param, // Default: "_vectors" + * dimensions?: int|Param, // Default: 1536 + * semantic_ratio?: float|Param, // The ratio between semantic (vector) and full-text search (0.0 to 1.0). Default: 1.0 (100% semantic) // Default: 1.0 + * }>, * memory?: array, + * strategy?: string|Param, + * }>, * milvus?: array, + * endpoint?: string|Param, + * api_key?: string|Param, + * database?: string|Param, + * collection?: string|Param, + * vector_field?: string|Param, // Default: "_vectors" + * dimensions?: int|Param, // Default: 1536 + * metric_type?: string|Param, // Default: "COSINE" + * }>, * mongodb?: array, + * client?: string|Param, // Default: "MongoDB\\Client" + * database?: string|Param, + * collection?: string|Param, + * index_name?: string|Param, + * vector_field?: string|Param, // Default: "vector" + * bulk_write?: bool|Param, // Default: false + * setup_options?: array{ + * fields?: mixed, // Default: [] + * }, + * }>, * neo4j?: array, + * endpoint?: string|Param, + * username?: string|Param, + * password?: string|Param, + * database?: string|Param, + * vector_index_name?: string|Param, + * node_name?: string|Param, + * vector_field?: string|Param, // Default: "embeddings" + * dimensions?: int|Param, // Default: 1536 + * distance?: string|Param, // Default: "cosine" + * quantization?: bool|Param, + * }>, * opensearch?: array, + * endpoint?: string|Param, + * index_name?: string|Param, + * vectors_field?: string|Param, // Default: "_vectors" + * dimensions?: int|Param, // Default: 1536 + * space_type?: string|Param, // Default: "l2" + * http_client?: string|Param, // Default: "http_client" + * }>, * pinecone?: array, - * top_k?: int|Param, - * }>, + * client?: string|Param, // Default: "Probots\\Pinecone\\Client" + * index_name?: string|Param, + * namespace?: string|Param, + * filter?: list, + * top_k?: int|Param, + * }>, * postgres?: array, + * dsn?: string|Param, + * username?: string|Param, + * password?: string|Param, + * table_name?: string|Param, + * vector_field?: string|Param, // Default: "embedding" + * distance?: "cosine"|"inner_product"|"l1"|"l2"|Param, // Distance metric to use for vector similarity search // Default: "l2" + * dbal_connection?: string|Param, + * setup_options?: array{ + * vector_type?: string|Param, // Default: "vector" + * vector_size?: int|Param, // Default: 1536 + * index_method?: string|Param, // Default: "ivfflat" + * index_opclass?: string|Param, // Default: "vector_cosine_ops" + * }, + * }>, * qdrant?: array, + * endpoint?: string|Param, + * api_key?: string|Param, + * collection_name?: string|Param, // The name of the store will be used if the "collection_name" is not set + * http_client?: string|Param, // Default: "http_client" + * dimensions?: int|Param, // Default: 1536 + * distance?: string|Param, // Default: "Cosine" + * async?: bool|Param, // Default: false + * }>, * redis?: array, + * connection_parameters?: mixed, // see https://github.com/phpredis/phpredis?tab=readme-ov-file#example-1 + * client?: string|Param, // a service id of a Redis client + * index_name?: string|Param, + * key_prefix?: string|Param, // Default: "vector:" + * distance?: "COSINE"|"L2"|"IP"|Param, // Distance metric to use for vector similarity search // Default: "COSINE" + * }>, * s3vectors?: array, - * vector_bucket_name?: string|Param, - * index_name?: string|Param, - * filter?: array, - * top_k?: int|Param, // Default number of results to return // Default: 3 - * }>, + * client?: string|Param, // Service reference to an existing S3VectorsClient + * configuration?: array, + * vector_bucket_name?: string|Param, + * index_name?: string|Param, + * filter?: array, + * top_k?: int|Param, // Default number of results to return // Default: 3 + * }>, * sqlite?: array, + * dsn?: string|Param, + * connection?: string|Param, + * table_name?: string|Param, + * strategy?: string|Param, + * vec?: bool|Param, // Default: false + * distance?: "cosine"|"L2"|Param, // Default: "cosine" + * vector_dimension?: int|Param, // Default: 1536 + * }>, * supabase?: array, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * url?: string|Param, + * api_key?: string|Param, + * table?: string|Param, + * vector_field?: string|Param, // Default: "embedding" + * vector_dimension?: int|Param, // Default: 1536 + * function_name?: string|Param, // Default: "match_documents" + * }>, * surrealdb?: array, + * endpoint?: string|Param, + * username?: string|Param, + * password?: string|Param, + * namespace?: string|Param, + * database?: string|Param, + * table?: string|Param, + * vector_field?: string|Param, // Default: "_vectors" + * strategy?: string|Param, // Default: "cosine" + * dimensions?: int|Param, // Default: 1536 + * namespaced_user?: bool|Param, + * }>, * typesense?: array, + * endpoint?: string|Param, + * api_key?: string|Param, + * collection?: string|Param, + * vector_field?: string|Param, // Default: "_vectors" + * dimensions?: int|Param, // Default: 1536 + * }>, * weaviate?: array, + * endpoint?: string|Param, + * api_key?: string|Param, + * http_client?: string|Param, // Default: "http_client" + * collection?: string|Param, // The name of the store will be used if the "collection" is not set + * }>, * vektor?: array, + * storage_path?: string|Param, // Default: "%kernel.project_dir%/var/share" + * dimensions?: int|Param, // Default: 1536 + * }>, * }, * message_store?: array{ * cache?: array, + * service?: string|Param, // Default: "cache.app" + * key?: string|Param, // The name of the message store will be used if the key is not set + * ttl?: int|Param, + * }>, * cloudflare?: array, + * account_id?: string|Param, + * api_key?: string|Param, + * namespace?: string|Param, + * endpoint_url?: string|Param, // If the version of the Cloudflare API is updated, use this key to support it. + * }>, * doctrine?: array{ * dbal?: array, + * connection?: string|Param, + * table_name?: string|Param, // The name of the message store will be used if the table_name is not set + * }>, * }, * meilisearch?: array, + * endpoint?: string|Param, + * api_key?: string|Param, + * index_name?: string|Param, + * }>, * memory?: array, + * identifier?: string|Param, + * }>, * mongodb?: array, + * client?: string|Param, // Default: "MongoDB\\Client" + * database?: string|Param, + * collection?: string|Param, + * }>, * pogocache?: array, + * endpoint?: string|Param, + * password?: string|Param, + * key?: string|Param, + * }>, * redis?: array, + * connection_parameters?: mixed, // see https://github.com/phpredis/phpredis?tab=readme-ov-file#example-1 + * client?: string|Param, // a service id of a Redis client + * endpoint?: string|Param, + * index_name?: string|Param, + * }>, * session?: array, + * identifier?: string|Param, + * }>, * surrealdb?: array, + * endpoint?: string|Param, + * username?: string|Param, + * password?: string|Param, + * namespace?: string|Param, + * database?: string|Param, + * table?: string|Param, + * namespaced_user?: bool|Param, // Using a namespaced user is a good practice to prevent any undesired access to a specific table, see https://surrealdb.com/docs/surrealdb/reference-guide/security-best-practices + * }>, * }, * chat?: array, + * agent?: string|Param, + * message_store?: string|Param, + * }>, * vectorizer?: array, + * platform?: string|Param, // Service name of platform // Default: "Symfony\\AI\\Platform\\PlatformInterface" + * model?: mixed, + * }>, * indexer?: array, - * filters?: list, - * vectorizer?: scalar|Param|null, // Service name of vectorizer // Default: "Symfony\\AI\\Store\\Document\\VectorizerInterface" - * store?: string|Param, // Service name of store // Default: "Symfony\\AI\\Store\\StoreInterface" - * }>, + * loader?: string|Param, // Service name of loader // Default: null + * source?: mixed, // Source identifier (file path, URL, etc.) or array of sources // Default: null + * transformers?: list, + * filters?: list, + * vectorizer?: scalar|Param|null, // Service name of vectorizer // Default: "Symfony\\AI\\Store\\Document\\VectorizerInterface" + * store?: string|Param, // Service name of store // Default: "Symfony\\AI\\Store\\StoreInterface" + * }>, * retriever?: array, + * vectorizer?: scalar|Param|null, // Service name of vectorizer // Default: "Symfony\\AI\\Store\\Document\\VectorizerInterface" + * store?: string|Param, // Service name of store // Default: "Symfony\\AI\\Store\\StoreInterface" + * }>, * } * @psalm-type ConfigType = array{ * imports?: ImportsConfig, From f13413a104992f5026a25c7f3f85574fc2e6b243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Fri, 1 May 2026 20:21:58 +0200 Subject: [PATCH 22/36] Fixed exception when github is not reachable --- src/Services/System/UpdateAvailableFacade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/System/UpdateAvailableFacade.php b/src/Services/System/UpdateAvailableFacade.php index ac3a46c0..60f66036 100644 --- a/src/Services/System/UpdateAvailableFacade.php +++ b/src/Services/System/UpdateAvailableFacade.php @@ -105,6 +105,6 @@ class UpdateAvailableFacade return $this->updateCache->get(self::CACHE_KEY, function (ItemInterface $item) { $item->expiresAfter(self::CACHE_TTL); return $this->updateChecker->getLatestVersion(); - }); + }) ?? ['version' => '0.0.1', 'url' => 'update-checking-failed']; } } From 4137bde1948c6a5287f049a1d7491acf12a8a7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Fri, 1 May 2026 20:57:41 +0200 Subject: [PATCH 23/36] Allow to pass options to circumvent caching of info provider results / force fresh --- src/Controller/PartController.php | 6 ++- .../InfoProviderSystem/PartInfoRetriever.php | 45 ++++++++++++++++--- .../Providers/BuerklinProvider.php | 12 +++-- .../Providers/CanopyProvider.php | 4 +- .../Providers/InfoProviderInterface.php | 1 + .../Providers/OEMSecretsProvider.php | 5 +++ .../Providers/OctopartProvider.php | 4 +- 7 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/Controller/PartController.php b/src/Controller/PartController.php index eb80d9bc..4c7ec37f 100644 --- a/src/Controller/PartController.php +++ b/src/Controller/PartController.php @@ -40,6 +40,7 @@ use App\Services\Attachments\AttachmentSubmitHandler; use App\Services\Attachments\PartPreviewGenerator; use App\Services\EntityMergers\Mergers\PartMerger; use App\Services\InfoProviderSystem\PartInfoRetriever; +use App\Services\InfoProviderSystem\Providers\InfoProviderInterface; use App\Services\LogSystem\EventCommentHelper; use App\Services\LogSystem\HistoryHelper; use App\Services\LogSystem\TimeTravel; @@ -283,7 +284,10 @@ final class PartController extends AbstractController { $this->denyAccessUnlessGranted('@info_providers.create_parts'); - $dto = $infoRetriever->getDetails($providerKey, $providerId); + //Force info providers to not use cache, when retrieving part details for creating a new part, because otherwise we might end up with outdated information + $no_cache = $request->query->getBoolean('no_cache', false); + + $dto = $infoRetriever->getDetails($providerKey, $providerId, [InfoProviderInterface::OPTION_NO_CACHE => $no_cache]); $new_part = $infoRetriever->dtoToPart($dto); if ($new_part->getCategory() === null || $new_part->getCategory()->getID() === null) { diff --git a/src/Services/InfoProviderSystem/PartInfoRetriever.php b/src/Services/InfoProviderSystem/PartInfoRetriever.php index db1895e7..53206a75 100644 --- a/src/Services/InfoProviderSystem/PartInfoRetriever.php +++ b/src/Services/InfoProviderSystem/PartInfoRetriever.php @@ -53,6 +53,7 @@ final class PartInfoRetriever * Search for a keyword in the given providers. The results can be cached * @param string[]|InfoProviderInterface[] $providers A list of providers to search in, either as provider keys or as provider instances * @param string $keyword The keyword to search for + * @param array $options An associative array of options which can be used to modify the search behavior. The supported options depend on the provider and should be documented in the provider's documentation. * @return SearchResultDTO[] The search results * @throws InfoProviderNotActiveException if any of the given providers is not active * @throws ClientException if any of the providers throws an exception during the search @@ -60,7 +61,7 @@ final class PartInfoRetriever * @throws TransportException if any of the providers throws an exception during the search * @throws OAuthReconnectRequiredException if any of the providers throws an exception during the search that indicates that the OAuth token needs to be refreshed */ - public function searchByKeyword(string $keyword, array $providers): array + public function searchByKeyword(string $keyword, array $providers, array $options = []): array { $results = []; @@ -89,15 +90,31 @@ final class PartInfoRetriever * Search for a keyword in the given provider. The result is cached for 7 days. * @return SearchResultDTO[] */ - protected function searchInProvider(InfoProviderInterface $provider, string $keyword): array + protected function searchInProvider(InfoProviderInterface $provider, string $keyword, array $options = []): array { //Generate key and escape reserved characters from the provider id $escaped_keyword = hash('xxh3', $keyword); - return $this->partInfoCache->get("search_{$provider->getProviderKey()}_{$escaped_keyword}", function (ItemInterface $item) use ($provider, $keyword) { + + $no_cache = $options[InfoProviderInterface::OPTION_NO_CACHE] ?? false; + + //Exclude the no_cache option from the options hash, since it should not affect the cache key, as it only determines whether to bypass the cache or not, but does not change the actual search results + $options_without_cache = $options; + unset($options_without_cache[InfoProviderInterface::OPTION_NO_CACHE]); + //Generate a hash for the options, to ensure that different options result in different cache entries + $options_hash = hash('xxh3', json_encode($options_without_cache, JSON_THROW_ON_ERROR)); + + $cache_key = "search_{$provider->getProviderKey()}_{$escaped_keyword}_{$options_hash}"; + + //If no_cache is set, bypass the cache and get fresh results from the provider + if ($no_cache) { + $this->partInfoCache->delete($cache_key); + } + + return $this->partInfoCache->get($cache_key, function (ItemInterface $item) use ($provider, $keyword, $options) { //Set the expiration time $item->expiresAfter(!$this->debugMode ? self::CACHE_RESULT_EXPIRATION : 10); - return $provider->searchByKeyword($keyword); + return $provider->searchByKeyword($keyword, $options); }); } @@ -106,10 +123,11 @@ final class PartInfoRetriever * The result is cached for 4 days. * @param string $provider_key * @param string $part_id + * @param array $options An associative array of options which can be used to modify the search behavior. The supported options depend on the provider and should be documented in the provider's documentation. * @return PartDetailDTO * @throws InfoProviderNotActiveException if the the given providers is not active */ - public function getDetails(string $provider_key, string $part_id): PartDetailDTO + public function getDetails(string $provider_key, string $part_id, array $options = []): PartDetailDTO { $provider = $this->provider_registry->getProviderByKey($provider_key); @@ -118,13 +136,26 @@ final class PartInfoRetriever throw InfoProviderNotActiveException::fromProvider($provider); } + //Exclude the no_cache option from the options hash, since it should not affect the cache key, as it only determines whether to bypass the cache or not, but does not change the actual search results + $options_without_cache = $options; + unset($options_without_cache[InfoProviderInterface::OPTION_NO_CACHE]); + //Generate a hash for the options, to ensure that different options result in different cache entries + $options_hash = hash('xxh3', json_encode($options_without_cache, JSON_THROW_ON_ERROR)); + //Generate key and escape reserved characters from the provider id $escaped_part_id = hash('xxh3', $part_id); - return $this->partInfoCache->get("details_{$provider_key}_{$escaped_part_id}", function (ItemInterface $item) use ($provider, $part_id) { + $cache_key = "details_{$provider_key}_{$escaped_part_id}_{$options_hash}"; + + //Delete the cache entry if no_cache is set, to ensure that the next get call will fetch fresh data from the provider, instead of returning stale data from the cache. + if ($options[InfoProviderInterface::OPTION_NO_CACHE] ?? false) { + $this->partInfoCache->delete($cache_key); + } + + return $this->partInfoCache->get($cache_key, function (ItemInterface $item) use ($provider, $part_id, $options) { //Set the expiration time $item->expiresAfter(!$this->debugMode ? self::CACHE_DETAIL_EXPIRATION : 10); - return $provider->getDetails($part_id); + return $provider->getDetails($part_id, $options); }); } diff --git a/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php b/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php index e5017eb2..ca6e26e1 100644 --- a/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php +++ b/src/Services/InfoProviderSystem/Providers/BuerklinProvider.php @@ -120,7 +120,7 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv ]; } - private function getProduct(string $code): array + private function getProduct(string $code, bool $use_cache = true): array { $code = strtoupper(trim($code)); if ($code === '') { @@ -132,6 +132,11 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv md5($code . '|' . $this->settings->language . '|' . $this->settings->currency) ); + if (!$use_cache) { + $this->partInfoCache->deleteItem($cacheKey); + unset($this->productCache[$cacheKey]); + } + if (isset($this->productCache[$cacheKey])) { return $this->productCache[$cacheKey]; } @@ -488,7 +493,7 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv // Fallback: try direct lookup by code try { - $product = $this->getProduct($keyword); + $product = $this->getProduct($keyword, use_cache: !($options[self::OPTION_NO_CACHE] ?? false)); return [$this->getPartDetail($product)]; } catch (\Throwable $e) { return []; @@ -498,7 +503,8 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv public function getDetails(string $id, array $options = []): PartDetailDTO { // Detail endpoint is /products/{code}/ - $response = $this->getProduct($id); + //By default use cache for details, but allow bypassing cache with option (e.g. for refresh) + $response = $this->getProduct($id, use_cache: !($options[self::OPTION_NO_CACHE] ?? false)); return $this->getPartDetail($response); } diff --git a/src/Services/InfoProviderSystem/Providers/CanopyProvider.php b/src/Services/InfoProviderSystem/Providers/CanopyProvider.php index d826c765..aee30d6b 100644 --- a/src/Services/InfoProviderSystem/Providers/CanopyProvider.php +++ b/src/Services/InfoProviderSystem/Providers/CanopyProvider.php @@ -184,8 +184,10 @@ class CanopyProvider implements InfoProviderInterface throw new \InvalidArgumentException("The id must be a valid ASIN (10 characters, letters and numbers)"); } + $do_not_cache = ($options[self::OPTION_NO_CACHE] ?? false) || $this->settings->alwaysGetDetails; + //Use cached details if available and the settings allow it, to avoid unnecessary API requests, since the search results already contain most of the details - if(!$this->settings->alwaysGetDetails && ($cached = $this->getFromCache($id)) !== null) { + if(!$do_not_cache && ($cached = $this->getFromCache($id)) !== null) { return $cached; } diff --git a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php index feb3466f..8896d94b 100644 --- a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php +++ b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php @@ -28,6 +28,7 @@ use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; interface InfoProviderInterface { + public const OPTION_NO_CACHE = 'no_cache'; // if set to true, the provider should not use any cache and retrieve fresh data from the source /** * Get information about this provider diff --git a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php index 2c98e6e5..9764517b 100644 --- a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php +++ b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php @@ -424,6 +424,11 @@ class OEMSecretsProvider implements InfoProviderInterface public function getDetails(string $id, array $options = []): PartDetailDTO { $cacheKey = $this->getCacheKey($id); + + if ($options[self::OPTION_NO_CACHE] ?? false) { + $this->partInfoCache->deleteItem($cacheKey); + } + $cacheItem = $this->partInfoCache->getItem($cacheKey); if ($cacheItem->isHit()) { diff --git a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php index 684e4ff0..de404e18 100644 --- a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php +++ b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php @@ -369,9 +369,11 @@ class OctopartProvider implements InfoProviderInterface public function getDetails(string $id, array $options = []): PartDetailDTO { + $no_cache = $options[self::OPTION_NO_CACHE] ?? false; + //Check if we have the part cached $cached = $this->getFromCache($id); - if ($cached !== null) { + if (!$no_cache && $cached !== null) { return $cached; } From fe4dc1f1e44aaef590d73d4558fb8e16aba4d3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 2 May 2026 01:40:08 +0200 Subject: [PATCH 24/36] Allow to set no_cache options via info provider UI --- src/Controller/InfoProviderController.php | 11 ++++++++-- src/Controller/PartController.php | 5 ++++- .../InfoProviderSystem/PartSearchType.php | 12 ++++++++++- .../InfoProviderSystem/PartInfoRetriever.php | 2 +- .../search/part_search.html.twig | 21 +++++++++++++++---- translations/messages.en.xlf | 18 ++++++++++++++++ 6 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/Controller/InfoProviderController.php b/src/Controller/InfoProviderController.php index deec8a57..cd076d67 100644 --- a/src/Controller/InfoProviderController.php +++ b/src/Controller/InfoProviderController.php @@ -31,6 +31,7 @@ use App\Services\InfoProviderSystem\ExistingPartFinder; use App\Services\InfoProviderSystem\PartInfoRetriever; use App\Services\InfoProviderSystem\ProviderRegistry; use App\Services\InfoProviderSystem\Providers\GenericWebProvider; +use App\Services\InfoProviderSystem\Providers\InfoProviderInterface; use App\Settings\AppSettings; use App\Settings\InfoProviderSystem\InfoProviderGeneralSettings; use Doctrine\ORM\EntityManagerInterface; @@ -172,10 +173,15 @@ class InfoProviderController extends AbstractController $keyword = $form->get('keyword')->getData(); $providers = $form->get('providers')->getData(); + $no_cache_search = $form->get('no_cache_search')->getData(); + $no_cache_details = $form->get('no_cache_details')->getData(); + $dtos = []; try { - $dtos = $this->infoRetriever->searchByKeyword(keyword: $keyword, providers: $providers); + $dtos = $this->infoRetriever->searchByKeyword(keyword: $keyword, providers: $providers, options: [ + InfoProviderInterface::OPTION_NO_CACHE => $no_cache_search + ]); } catch (ClientException $e) { $this->addFlash('error', t('info_providers.search.error.client_exception')); $this->addFlash('error',$e->getMessage()); @@ -207,7 +213,8 @@ class InfoProviderController extends AbstractController return $this->render('info_providers/search/part_search.html.twig', [ 'form' => $form, 'results' => $results, - 'update_target' => $update_target + 'update_target' => $update_target, + 'no_cache_details' => $no_cache_details ?? false, ]); } diff --git a/src/Controller/PartController.php b/src/Controller/PartController.php index 4c7ec37f..c80afdb7 100644 --- a/src/Controller/PartController.php +++ b/src/Controller/PartController.php @@ -346,10 +346,13 @@ final class PartController extends AbstractController $this->denyAccessUnlessGranted('edit', $part); $this->denyAccessUnlessGranted('@info_providers.create_parts'); + //Force info providers to not use cache, when retrieving part details for creating a new part, because otherwise we might end up with outdated information + $no_cache = $request->query->getBoolean('no_cache', false); + //Save the old name of the target part for the template $old_name = $part->getName(); - $dto = $infoRetriever->getDetails($providerKey, $providerId); + $dto = $infoRetriever->getDetails($providerKey, $providerId, [InfoProviderInterface::OPTION_NO_CACHE => $no_cache]); $provider_part = $infoRetriever->dtoToPart($dto); $part = $partMerger->merge($part, $provider_part); diff --git a/src/Form/InfoProviderSystem/PartSearchType.php b/src/Form/InfoProviderSystem/PartSearchType.php index 9d582ca4..154c1aa3 100644 --- a/src/Form/InfoProviderSystem/PartSearchType.php +++ b/src/Form/InfoProviderSystem/PartSearchType.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace App\Form\InfoProviderSystem; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\SearchType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormBuilderInterface; @@ -40,8 +41,17 @@ class PartSearchType extends AbstractType 'help' => 'info_providers.search.providers.help', ]); + $builder->add('no_cache_search', CheckboxType::class, [ + 'label' => 'info_providers.no_cache_search', + 'required' => false, + ]); + $builder->add('no_cache_details', CheckboxType::class, [ + 'label' => 'info_providers.no_cache_details', + 'required' => false, + ]); + $builder->add('submit', SubmitType::class, [ 'label' => 'info_providers.search.submit' ]); } -} \ No newline at end of file +} diff --git a/src/Services/InfoProviderSystem/PartInfoRetriever.php b/src/Services/InfoProviderSystem/PartInfoRetriever.php index 53206a75..6c10f10e 100644 --- a/src/Services/InfoProviderSystem/PartInfoRetriever.php +++ b/src/Services/InfoProviderSystem/PartInfoRetriever.php @@ -80,7 +80,7 @@ final class PartInfoRetriever } /** @noinspection SlowArrayOperationsInLoopInspection */ - $results = array_merge($results, $this->searchInProvider($provider, $keyword)); + $results = array_merge($results, $this->searchInProvider($provider, $keyword, $options)); } return $results; diff --git a/templates/info_providers/search/part_search.html.twig b/templates/info_providers/search/part_search.html.twig index eac3507d..9e1f0834 100644 --- a/templates/info_providers/search/part_search.html.twig +++ b/templates/info_providers/search/part_search.html.twig @@ -33,6 +33,19 @@
+ + +
+
+ {{ form_row(form.no_cache_search) }} + {{ form_row(form.no_cache_details) }} +
+
+ {{ form_row(form.submit) }} {{ form_end(form) }} @@ -116,16 +129,16 @@ {% if update_target %} {# We update an existing part #} {% set href = path('info_providers_update_part', - {'providerKey': dto.provider_key, 'providerId': dto.provider_id, 'id': update_target.iD}) %} + {'providerKey': dto.provider_key, 'providerId': dto.provider_id, 'id': update_target.iD, 'no_cache': no_cache_details ? 1 : null}) %} {% else %} {# Create a fresh part #} {% set href = path('info_providers_create_part', - {'providerKey': dto.provider_key, 'providerId': dto.provider_id}) %} + {'providerKey': dto.provider_key, 'providerId': dto.provider_id, 'no_cache': no_cache_details ? 1 : null}) %} {% endif %} {# If we have no local part, then we can just show the create button #} {% if localPart is null %} + target="_blank" title="{% trans %}part.create.btn{% endtrans %}"> {% else %} {# Otherwise add a button group with all three buttons #} @@ -139,7 +152,7 @@ target="_blank" title="{% trans %}info_providers.search.show_existing_part{% endtrans %}"> - diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index d2c4bc47..f30ffb9f 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13139,5 +13139,23 @@ Buerklin-API Authentication server: The additional instructions will be appended to the system prompt.
+ + + info_providers.search.advanced_options + Advanced options + + + + + info_providers.no_cache_search + Do not cache search results / Force fresh search + + + + + info_providers.no_cache_details + Do not cache result details / Force fresh part detail retrieval + + From e77b67445c0a27a16d8dd33a340ca426126cc506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 2 May 2026 22:08:25 +0200 Subject: [PATCH 25/36] Added cache to AIWebProvider --- ...{AIInfoExtractor.php => AIWebProvider.php} | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) rename src/Services/InfoProviderSystem/Providers/{AIInfoExtractor.php => AIWebProvider.php} (87%) diff --git a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php b/src/Services/InfoProviderSystem/Providers/AIWebProvider.php similarity index 87% rename from src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php rename to src/Services/InfoProviderSystem/Providers/AIWebProvider.php index bf1ce37c..d53201cc 100644 --- a/src/Services/InfoProviderSystem/Providers/AIInfoExtractor.php +++ b/src/Services/InfoProviderSystem/Providers/AIWebProvider.php @@ -33,6 +33,7 @@ use App\Settings\InfoProviderSystem\AIExtractorSettings; use Brick\Schema\SchemaReader; use Jkphl\Micrometa; use League\HTMLToMarkdown\HtmlConverter; +use Psr\Cache\CacheItemPoolInterface; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; use Symfony\Component\DomCrawler\Crawler; @@ -43,11 +44,11 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; use function Symfony\Component\String\u; -final class AIInfoExtractor implements InfoProviderInterface +final class AIWebProvider implements InfoProviderInterface { use FixAndValidateUrlTrait; - private const DISTRIBUTOR_NAME = 'AI Extracted'; + private const DISTRIBUTOR_NAME = 'Website'; private readonly HttpClientInterface $httpClient; @@ -56,6 +57,7 @@ final class AIInfoExtractor implements InfoProviderInterface private readonly AIExtractorSettings $settings, private readonly AIPlatformRegistry $AIPlatformRegistry, private readonly DTOJsonSchemaConverter $jsonSchemaConverter, + private readonly CacheItemPoolInterface $partInfoCache ) { //Use NoPrivateNetworkHttpClient to prevent SSRF vulnerabilities, and RandomizeUseragentHttpClient to make it harder for servers to block us $this->httpClient = (new RandomizeUseragentHttpClient(new NoPrivateNetworkHttpClient($httpClient)))->withOptions( @@ -68,17 +70,17 @@ final class AIInfoExtractor implements InfoProviderInterface public function getProviderInfo(): array { return [ - 'name' => 'AI Information Extractor', - 'description' => 'Extract part info from any URL using OpenRouter LLM', + 'name' => 'AI Web Extractor', + 'description' => 'Extract part info from any URL using LLM', //'url' => 'https://openrouter.ai', - 'disabled_help' => 'Configure OpenRouter API key in settings', + 'disabled_help' => 'Configure AI settings', 'settings_class' => AIExtractorSettings::class, ]; } public function getProviderKey(): string { - return 'ai_extractor'; + return 'ai_web'; } public function isActive(): bool @@ -90,7 +92,7 @@ final class AIInfoExtractor implements InfoProviderInterface { try { return [ - $this->getDetails($keyword) + $this->getDetails($keyword, $options) ]; } catch (ProviderIDNotSupportedException $e) { return []; } @@ -100,16 +102,24 @@ final class AIInfoExtractor implements InfoProviderInterface { $url = $this->fixAndValidateURL($id); + //Check if we have a cached result for this URL, to avoid unnecessary LLM calls, which can be slow and costly. + $cacheKey = 'ai_web_'.hash('xxh3', $url); + + //If ignore cache option is set, skip cache and fetch fresh data + if ($options[self::OPTION_NO_CACHE] ?? false) { + $this->partInfoCache->deleteItem($cacheKey); + } + + //Return cached result if available + $cacheItem = $this->partInfoCache->getItem($cacheKey); + if ($cacheItem->isHit()) { + return $cacheItem->get(); + } + // Fetch HTML content $response = $this->httpClient->request('GET', $url); $html = $response->getContent(); - // Clean HTML - /*$cleanedHtml = $this->cleanHTML($html); - - // Truncate to max content length - $truncatedHtml = $this->truncateHTML($cleanedHtml, $this->settings->maxContentLength);*/ - //Convert html to markdown, to provide a cleaner input to the LLM. $markdown = $this->htmlToMarkdown($html); //Truncate markdown to max content length, if needed @@ -124,6 +134,11 @@ final class AIInfoExtractor implements InfoProviderInterface // Build and return PartDetailDTO $result = $this->jsonSchemaConverter->jsonToDTO($llmResponse, $this->getProviderKey(), $url, $url, self::DISTRIBUTOR_NAME); + // Cache the result for future use, to improve performance and reduce costs. + $cacheItem->set($result); + $cacheItem->expiresAfter(3600 * 2); //Cache for 2 hours, as web content can change frequently, but we still want to benefit from caching for repeated accesses. + $this->partInfoCache->save($cacheItem); + return $result; } From a2b9ee764d2890c975d58a59973b7b96cc654bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 2 May 2026 22:12:36 +0200 Subject: [PATCH 26/36] Added tests for AIPlatformRegistry --- src/Services/AI/AIPlatformRegistry.php | 1 - tests/Services/AI/AIPlatformRegistryTest.php | 99 ++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 tests/Services/AI/AIPlatformRegistryTest.php diff --git a/src/Services/AI/AIPlatformRegistry.php b/src/Services/AI/AIPlatformRegistry.php index bf1d355c..408bb181 100644 --- a/src/Services/AI/AIPlatformRegistry.php +++ b/src/Services/AI/AIPlatformRegistry.php @@ -43,7 +43,6 @@ final readonly class AIPlatformRegistry public function __construct( SettingsManagerInterface $settingsManager, - #[AutowireIterator(tag: 'ai.platform', indexAttribute: 'name')] iterable $platforms, ) { diff --git a/tests/Services/AI/AIPlatformRegistryTest.php b/tests/Services/AI/AIPlatformRegistryTest.php new file mode 100644 index 00000000..1577f9b5 --- /dev/null +++ b/tests/Services/AI/AIPlatformRegistryTest.php @@ -0,0 +1,99 @@ +. + */ + +/** + * Tests for App\Services\AI\AIPlatformRegistry + */ +declare(strict_types=1); + +namespace App\Tests\Services\AI; + +use App\Services\AI\AIPlatformRegistry; +use App\Services\AI\AIPlatforms; +use App\Services\AI\AIPlatformSettingsInterface; +use Jbtronics\SettingsBundle\Manager\SettingsManagerInterface; +use PHPUnit\Framework\TestCase; +use Symfony\AI\Platform\PlatformInterface; + +class AIPlatformRegistryTest extends TestCase +{ + public function testRegistersEnabledPlatformsAndReturnsPlatform(): void + { + // Create a platform mock and expose it under the service tag name (openrouter) + $platformMock = $this->createMock(PlatformInterface::class); + + // Settings for OpenRouter -> enabled + $openRouterSettings = $this->createMock(AIPlatformSettingsInterface::class); + $openRouterSettings->method('isAIPlatformEnabled')->willReturn(true); + + // Settings for LMStudio -> disabled + $lmSettings = $this->createMock(AIPlatformSettingsInterface::class); + $lmSettings->method('isAIPlatformEnabled')->willReturn(false); + + // Settings manager should return the corresponding settings object depending on the requested class name + $settingsManager = $this->createMock(SettingsManagerInterface::class); + $settingsManager->method('get')->willReturnMap([ + [AIPlatforms::OPENROUTER->toSettingsClass(), $openRouterSettings], + [AIPlatforms::LMSTUDIO->toSettingsClass(), $lmSettings], + ]); + + $platforms = new \ArrayIterator([ + AIPlatforms::OPENROUTER->toServiceTagName() => $platformMock, + ]); + + $registry = new AIPlatformRegistry($settingsManager, $platforms); + + // OPENROUTER should be enabled and retrievable + $this->assertTrue($registry->isEnabled(AIPlatforms::OPENROUTER)); + $this->assertSame($platformMock, $registry->getPlatform(AIPlatforms::OPENROUTER)); + + // LMSTUDIO is either not registered or disabled -> should not be enabled + $this->assertFalse($registry->isEnabled(AIPlatforms::LMSTUDIO)); + $this->expectException(\InvalidArgumentException::class); + $registry->getPlatform(AIPlatforms::LMSTUDIO); + } + + public function testGetEnabledPlatformsReturnsIndexedArray(): void + { + $platformMock = $this->createMock(PlatformInterface::class); + + $openRouterSettings = $this->createMock(AIPlatformSettingsInterface::class); + $openRouterSettings->method('isAIPlatformEnabled')->willReturn(true); + + $settingsManager = $this->createMock(SettingsManagerInterface::class); + $settingsManager->method('get')->willReturnMap([ + [AIPlatforms::OPENROUTER->toSettingsClass(), $openRouterSettings], + [AIPlatforms::LMSTUDIO->toSettingsClass(), $this->createMock(AIPlatformSettingsInterface::class)], + ]); + + $platforms = new \ArrayIterator([ + AIPlatforms::OPENROUTER->toServiceTagName() => $platformMock, + // lmstudio not registered + ]); + + $registry = new AIPlatformRegistry($settingsManager, $platforms); + + $enabled = $registry->getEnabledPlatforms(); + + $this->assertArrayHasKey(AIPlatforms::OPENROUTER->value, $enabled); + $this->assertSame($platformMock, $enabled[AIPlatforms::OPENROUTER->value]); + } +} + From aac5b8e0becf1d87b764e5a76082a9f561d53221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 2 May 2026 23:23:20 +0200 Subject: [PATCH 27/36] Allow to select which method should be used to in "Create from URL feature" --- src/Controller/InfoProviderController.php | 25 +++--- .../InfoProviderSystem/FromURLFormType.php | 82 +++++++++++++++++++ .../CreateFromUrlHelper.php | 52 ++++++++++++ src/Twig/MiscExtension.php | 13 ++- templates/_navbar.html.twig | 2 +- .../from_url/from_url.html.twig | 15 ++++ translations/messages.en.xlf | 24 ++++++ 7 files changed, 198 insertions(+), 15 deletions(-) create mode 100644 src/Form/InfoProviderSystem/FromURLFormType.php create mode 100644 src/Services/InfoProviderSystem/CreateFromUrlHelper.php diff --git a/src/Controller/InfoProviderController.php b/src/Controller/InfoProviderController.php index cd076d67..074d3894 100644 --- a/src/Controller/InfoProviderController.php +++ b/src/Controller/InfoProviderController.php @@ -26,8 +26,10 @@ namespace App\Controller; use App\Entity\Parts\Manufacturer; use App\Entity\Parts\Part; use App\Exceptions\OAuthReconnectRequiredException; +use App\Form\InfoProviderSystem\FromURLFormType; use App\Form\InfoProviderSystem\PartSearchType; use App\Services\InfoProviderSystem\ExistingPartFinder; +use App\Services\InfoProviderSystem\CreateFromUrlHelper; use App\Services\InfoProviderSystem\PartInfoRetriever; use App\Services\InfoProviderSystem\ProviderRegistry; use App\Services\InfoProviderSystem\Providers\GenericWebProvider; @@ -219,35 +221,31 @@ class InfoProviderController extends AbstractController } #[Route('/from_url', name: 'info_providers_from_url')] - public function fromURL(Request $request, GenericWebProvider $provider): Response + public function fromURL(Request $request, GenericWebProvider $provider, CreateFromUrlHelper $fromUrlHelper): Response { $this->denyAccessUnlessGranted('@info_providers.create_parts'); - if (!$provider->isActive()) { + if (!$fromUrlHelper->canCreateFromUrl()) { $this->addFlash('error', "Generic Web Provider is not active. Please enable it in the provider settings."); return $this->redirectToRoute('info_providers_list'); } - $formBuilder = $this->createFormBuilder(); - $formBuilder->add('url', UrlType::class, [ - 'label' => 'info_providers.from_url.url.label', - 'required' => true, - ]); - $formBuilder->add('submit', SubmitType::class, [ - 'label' => 'info_providers.search.submit', - ]); - - $form = $formBuilder->getForm(); + $form = $this->createForm(FromURLFormType::class); $form->handleRequest($request); $partDetail = null; if ($form->isSubmitted() && $form->isValid()) { //Try to retrieve the part detail from the given URL $url = $form->get('url')->getData(); + + $method = $form->get('method')->getData(); + $no_cache = $form->get('no_cache')->getData(); + try { + //It's okay if we use the cached results here, as its just for convenience $searchResult = $this->infoRetriever->searchByKeyword( keyword: $url, - providers: [$provider] + providers: [$method], ); if (count($searchResult) === 0) { @@ -258,6 +256,7 @@ class InfoProviderController extends AbstractController return $this->redirectToRoute('info_providers_create_part', [ 'providerKey' => $searchResult->provider_key, 'providerId' => $searchResult->provider_id, + 'no_cache' => $no_cache ? 1 : null, ]); } } catch (ExceptionInterface $e) { diff --git a/src/Form/InfoProviderSystem/FromURLFormType.php b/src/Form/InfoProviderSystem/FromURLFormType.php new file mode 100644 index 00000000..cad7a0f5 --- /dev/null +++ b/src/Form/InfoProviderSystem/FromURLFormType.php @@ -0,0 +1,82 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Form\InfoProviderSystem; + +use App\Services\InfoProviderSystem\ProviderRegistry; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Symfony\Component\Form\Extension\Core\Type\UrlType; +use Symfony\Component\Form\FormBuilderInterface; + +class FromURLFormType extends AbstractType +{ + public function __construct(private readonly ProviderRegistry $providerRegistry) + { + + } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder->add('url', UrlType::class, [ + 'label' => 'info_providers.from_url.url.label', + 'required' => true, + ]); + + + $builder->add('method', ChoiceType::class, [ + 'expanded' => true, + 'data' => 'generic_web', //Default value + 'label' => 'info_providers.from_url.method', + 'choices' => [ + 'info_providers.from_url.method.generic_web' => 'generic_web', + 'info_providers.from_url.method.ai_web' => 'ai_web', + ], + 'choice_attr' => function ($choice, $key, $value) { + //Disable all providers that are not active + $provider = $this->providerRegistry->getProviderByKey($value); + if (!$provider->isActive()) { + return ['disabled' => 'disabled']; + } + + return []; + }, + + //Render the choices as inline radio buttons + 'label_attr' => [ + 'class' => 'radio-inline', + ], + ]); + + $builder->add('no_cache', CheckboxType::class, [ + 'label' => 'info_providers.from_url.no_cache', + 'required' => false, + ]); + + $builder->add('submit', SubmitType::class, [ + 'label' => 'info_providers.search.submit', + ]); + } +} diff --git a/src/Services/InfoProviderSystem/CreateFromUrlHelper.php b/src/Services/InfoProviderSystem/CreateFromUrlHelper.php new file mode 100644 index 00000000..46a2f767 --- /dev/null +++ b/src/Services/InfoProviderSystem/CreateFromUrlHelper.php @@ -0,0 +1,52 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\InfoProviderSystem; + +use App\Entity\UserSystem\User; +use Symfony\Bundle\SecurityBundle\Security; + +final readonly class CreateFromUrlHelper +{ + public function __construct(private Security $security, private ProviderRegistry $providerRegistry) + { + } + + /** + * Checks if at least one provider can create parts from an URL and the current user is allowed to use it. + * This is used to determine if the "From URL" feature should be shown to the user. + * @return bool + */ + public function canCreateFromUrl(): bool + { + if (!$this->security->isGranted('@info_providers.create_parts')) { + return false; + } + + //Check if either the generic web provider or the ai web provider is active + $genericWebProvider = $this->providerRegistry->getProviderByKey('generic_web'); + $aiWebProvider = $this->providerRegistry->getProviderByKey('ai_web'); + + return $genericWebProvider->isActive() || $aiWebProvider->isActive(); + } +} diff --git a/src/Twig/MiscExtension.php b/src/Twig/MiscExtension.php index 390ad084..565d56f2 100644 --- a/src/Twig/MiscExtension.php +++ b/src/Twig/MiscExtension.php @@ -22,6 +22,7 @@ declare(strict_types=1); */ namespace App\Twig; +use App\Services\InfoProviderSystem\CreateFromUrlHelper; use Twig\Attribute\AsTwigFunction; use App\Settings\SettingsIcon; use Symfony\Component\HttpFoundation\Request; @@ -34,7 +35,7 @@ use Twig\Extension\AbstractExtension; final readonly class MiscExtension { - public function __construct(private EventCommentNeededHelper $eventCommentNeededHelper) + public function __construct(private EventCommentNeededHelper $eventCommentNeededHelper, private CreateFromUrlHelper $fromUrlHelper) { } @@ -84,4 +85,14 @@ final readonly class MiscExtension return $request->getBaseUrl().$request->getPathInfo().$qs; } + + /** + * Returns true if the from url provider is active, false otherwise. + * @return bool + */ + #[AsTwigFunction(name: 'create_from_url_active')] + public function create_from_url_active(): bool + { + return $this->fromUrlHelper->canCreateFromUrl(); + } } diff --git a/templates/_navbar.html.twig b/templates/_navbar.html.twig index 57331370..7719ab2b 100644 --- a/templates/_navbar.html.twig +++ b/templates/_navbar.html.twig @@ -52,7 +52,7 @@ {% trans %}info_providers.search.title{% endtrans %} - {% if settings_instance('generic_web_provider').enabled %} + {% if create_from_url_active() %}
  • diff --git a/templates/info_providers/from_url/from_url.html.twig b/templates/info_providers/from_url/from_url.html.twig index 3370a94c..15aa225f 100644 --- a/templates/info_providers/from_url/from_url.html.twig +++ b/templates/info_providers/from_url/from_url.html.twig @@ -16,6 +16,21 @@ {{ form_start(form) }} {{ form_row(form.url) }} + + {{ form_row(form.method) }} + + + +
    +
    + {{ form_row(form.no_cache) }} +
    +
    + {{ form_row(form.submit) }} {{ form_end(form) }} {% endblock %} diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index f30ffb9f..cb071128 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13157,5 +13157,29 @@ Buerklin-API Authentication server: Do not cache result details / Force fresh part detail retrieval + + + info_providers.from_url.method.generic_web + Classic Web Scraper + + + + + info_providers.from_url.method.ai_web + AI Web Scraper + + + + + info_providers.from_url.method + Method + + + + + info_providers.from_url.no_cache + Ignore cache / Force fresh info retrieval + + From 889aa08b4e1abb4323e94db1dc4aa74f369753f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 2 May 2026 23:42:26 +0200 Subject: [PATCH 28/36] Added URL delegation feature to AI provider and added option to skip that delegation --- src/Controller/InfoProviderController.php | 5 ++ src/Controller/PartController.php | 6 +- .../InfoProviderSystem/FromURLFormType.php | 5 ++ .../CreateFromUrlHelper.php | 59 +++++++++++++++++- .../Providers/AIWebProvider.php | 28 ++++++++- .../Providers/GenericWebProvider.php | 62 +++++-------------- .../Providers/InfoProviderInterface.php | 1 + .../from_url/from_url.html.twig | 1 + translations/messages.en.xlf | 6 ++ 9 files changed, 121 insertions(+), 52 deletions(-) diff --git a/src/Controller/InfoProviderController.php b/src/Controller/InfoProviderController.php index 074d3894..817a6651 100644 --- a/src/Controller/InfoProviderController.php +++ b/src/Controller/InfoProviderController.php @@ -240,12 +240,16 @@ class InfoProviderController extends AbstractController $method = $form->get('method')->getData(); $no_cache = $form->get('no_cache')->getData(); + $skip_delegation = $form->get('skip_delegation')->getData(); try { //It's okay if we use the cached results here, as its just for convenience $searchResult = $this->infoRetriever->searchByKeyword( keyword: $url, providers: [$method], + options: [ + InfoProviderInterface::OPTION_SKIP_DELEGATION => $skip_delegation, + ] ); if (count($searchResult) === 0) { @@ -257,6 +261,7 @@ class InfoProviderController extends AbstractController 'providerKey' => $searchResult->provider_key, 'providerId' => $searchResult->provider_id, 'no_cache' => $no_cache ? 1 : null, + 'skip_delegation' => $skip_delegation ? 1 : null, ]); } } catch (ExceptionInterface $e) { diff --git a/src/Controller/PartController.php b/src/Controller/PartController.php index c80afdb7..ab424f50 100644 --- a/src/Controller/PartController.php +++ b/src/Controller/PartController.php @@ -286,8 +286,12 @@ final class PartController extends AbstractController //Force info providers to not use cache, when retrieving part details for creating a new part, because otherwise we might end up with outdated information $no_cache = $request->query->getBoolean('no_cache', false); + $skip_delegation = $request->query->getBoolean('skip_delegation', false); - $dto = $infoRetriever->getDetails($providerKey, $providerId, [InfoProviderInterface::OPTION_NO_CACHE => $no_cache]); + $dto = $infoRetriever->getDetails($providerKey, $providerId, [ + InfoProviderInterface::OPTION_NO_CACHE => $no_cache, + InfoProviderInterface::OPTION_SKIP_DELEGATION => $skip_delegation, + ]); $new_part = $infoRetriever->dtoToPart($dto); if ($new_part->getCategory() === null || $new_part->getCategory()->getID() === null) { diff --git a/src/Form/InfoProviderSystem/FromURLFormType.php b/src/Form/InfoProviderSystem/FromURLFormType.php index cad7a0f5..39ef50f4 100644 --- a/src/Form/InfoProviderSystem/FromURLFormType.php +++ b/src/Form/InfoProviderSystem/FromURLFormType.php @@ -75,6 +75,11 @@ class FromURLFormType extends AbstractType 'required' => false, ]); + $builder->add('skip_delegation', CheckboxType::class, [ + 'label' => 'info_providers.from_url.skip_delegation', + 'required' => false, + ]); + $builder->add('submit', SubmitType::class, [ 'label' => 'info_providers.search.submit', ]); diff --git a/src/Services/InfoProviderSystem/CreateFromUrlHelper.php b/src/Services/InfoProviderSystem/CreateFromUrlHelper.php index 46a2f767..0291142f 100644 --- a/src/Services/InfoProviderSystem/CreateFromUrlHelper.php +++ b/src/Services/InfoProviderSystem/CreateFromUrlHelper.php @@ -24,11 +24,18 @@ declare(strict_types=1); namespace App\Services\InfoProviderSystem; use App\Entity\UserSystem\User; +use App\Exceptions\ProviderIDNotSupportedException; +use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; +use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; +use App\Services\InfoProviderSystem\Providers\InfoProviderInterface; use Symfony\Bundle\SecurityBundle\Security; final readonly class CreateFromUrlHelper { - public function __construct(private Security $security, private ProviderRegistry $providerRegistry) + public function __construct(private Security $security, + private ProviderRegistry $providerRegistry, + private PartInfoRetriever $infoRetriever, + ) { } @@ -49,4 +56,54 @@ final readonly class CreateFromUrlHelper return $genericWebProvider->isActive() || $aiWebProvider->isActive(); } + + /** + * Delegates the URL to another provider if possible, otherwise return null + * @param string $url + * @return SearchResultDTO|null + */ + public function delegateToOtherProvider(string $url, InfoProviderInterface $callingInfoProvider): ?SearchResultDTO + { + //Extract domain from url: + $host = parse_url($url, PHP_URL_HOST); + if ($host === false || $host === null) { + return null; + } + + $provider = $this->providerRegistry->getProviderHandlingDomain($host); + + if ($provider !== null && $provider->isActive() && $provider->getProviderKey() !== $callingInfoProvider->getProviderKey()) { + try { + $id = $provider->getIDFromURL($url); + if ($id !== null) { + $results = $this->infoRetriever->searchByKeyword($id, [$provider]); + if (count($results) > 0) { + return $results[0]; + } + } + return null; + } catch (ProviderIDNotSupportedException $e) { + //Ignore and continue + return null; + } + } + + return null; + } + + /** + * Delegates the URL to another provider if possible and returns the details, otherwise return null + * @param string $url + * @param InfoProviderInterface $callingInfoProvider + * @return PartDetailDTO|null + */ + public function delegateToOtherProviderDetails(string $url, InfoProviderInterface $callingInfoProvider): ?PartDetailDTO + { + $delegatedResult = $this->delegateToOtherProvider($url, $callingInfoProvider); + if ($delegatedResult !== null) { + return $this->infoRetriever->getDetailsForSearchResult($delegatedResult); + } + + return null; + } } diff --git a/src/Services/InfoProviderSystem/Providers/AIWebProvider.php b/src/Services/InfoProviderSystem/Providers/AIWebProvider.php index d53201cc..8fb7e4ec 100644 --- a/src/Services/InfoProviderSystem/Providers/AIWebProvider.php +++ b/src/Services/InfoProviderSystem/Providers/AIWebProvider.php @@ -27,6 +27,7 @@ namespace App\Services\InfoProviderSystem\Providers; use App\Exceptions\ProviderIDNotSupportedException; use App\Helpers\RandomizeUseragentHttpClient; use App\Services\AI\AIPlatformRegistry; +use App\Services\InfoProviderSystem\CreateFromUrlHelper; use App\Services\InfoProviderSystem\DTOJsonSchemaConverter; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Settings\InfoProviderSystem\AIExtractorSettings; @@ -57,7 +58,8 @@ final class AIWebProvider implements InfoProviderInterface private readonly AIExtractorSettings $settings, private readonly AIPlatformRegistry $AIPlatformRegistry, private readonly DTOJsonSchemaConverter $jsonSchemaConverter, - private readonly CacheItemPoolInterface $partInfoCache + private readonly CacheItemPoolInterface $partInfoCache, + private readonly CreateFromUrlHelper $createFromUrlHelper, ) { //Use NoPrivateNetworkHttpClient to prevent SSRF vulnerabilities, and RandomizeUseragentHttpClient to make it harder for servers to block us $this->httpClient = (new RandomizeUseragentHttpClient(new NoPrivateNetworkHttpClient($httpClient)))->withOptions( @@ -90,9 +92,23 @@ final class AIWebProvider implements InfoProviderInterface public function searchByKeyword(string $keyword, array $options = []): array { + $url = $this->fixAndValidateURL($keyword); + + if (!($options[self::OPTION_SKIP_DELEGATION] ?? false)) { + //Before loading the page, try to delegate to another provider + $delegatedPart = $this->createFromUrlHelper->delegateToOtherProvider($url, $this); + if ($delegatedPart !== null) { + return [$delegatedPart]; + } + } + try { + + $new_options = $options; + $new_options[self::OPTION_SKIP_DELEGATION] = true; //Skip delegation for the getDetails call to prevent infinite loops + return [ - $this->getDetails($keyword, $options) + $this->getDetails($keyword, $new_options) ]; } catch (ProviderIDNotSupportedException $e) { return []; } @@ -102,6 +118,14 @@ final class AIWebProvider implements InfoProviderInterface { $url = $this->fixAndValidateURL($id); + if (!($options[self::OPTION_SKIP_DELEGATION] ?? false)) { + //Before loading the page, try to delegate to another provider + $delegatedPart = $this->createFromUrlHelper->delegateToOtherProviderDetails($url, $this); + if ($delegatedPart !== null) { + return $delegatedPart; + } + } + //Check if we have a cached result for this URL, to avoid unnecessary LLM calls, which can be slow and costly. $cacheKey = 'ai_web_'.hash('xxh3', $url); diff --git a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php index 23eee528..06a9d4c1 100644 --- a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php +++ b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php @@ -25,6 +25,7 @@ namespace App\Services\InfoProviderSystem\Providers; use App\Exceptions\ProviderIDNotSupportedException; use App\Helpers\RandomizeUseragentHttpClient; +use App\Services\InfoProviderSystem\CreateFromUrlHelper; use App\Services\InfoProviderSystem\DTOs\ParameterDTO; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Services\InfoProviderSystem\DTOs\PriceDTO; @@ -50,14 +51,12 @@ class GenericWebProvider implements InfoProviderInterface use FixAndValidateUrlTrait; - public const OPTION_CHECK_FOR_DELEGATION = 'check_for_delegation'; - public const DISTRIBUTOR_NAME = 'Website'; private readonly HttpClientInterface $httpClient; public function __construct(HttpClientInterface $httpClient, private readonly GenericWebProviderSettings $settings, - private readonly ProviderRegistry $providerRegistry, private readonly PartInfoRetriever $infoRetriever, + private readonly CreateFromUrlHelper $createFromUrlHelper, ) { //Use NoPrivateNetworkHttpClient to prevent SSRF vulnerabilities, and RandomizeUseragentHttpClient to make it harder for servers to block us @@ -93,15 +92,19 @@ class GenericWebProvider implements InfoProviderInterface { $url = $this->fixAndValidateURL($keyword); - //Before loading the page, try to delegate to another provider - $delegatedPart = $this->delegateToOtherProvider($url); - if ($delegatedPart !== null) { - return [$delegatedPart]; + if (!($options[self::OPTION_SKIP_DELEGATION] ?? false)) { + //Before loading the page, try to delegate to another provider + $delegatedPart = $this->createFromUrlHelper->delegateToOtherProvider($url, $this); + if ($delegatedPart !== null) { + return [$delegatedPart]; + } } try { + $new_options = $options; + $new_options[self::OPTION_SKIP_DELEGATION] = true; //Skip delegation for the getDetails call to prevent infinite loops return [ - $this->getDetails($keyword, [self::OPTION_CHECK_FOR_DELEGATION => false]) //We already tried delegation + $this->getDetails($keyword, $new_options) ]; } catch (ProviderIDNotSupportedException $e) { return []; } @@ -278,53 +281,16 @@ class GenericWebProvider implements InfoProviderInterface return null; } - /** - * Delegates the URL to another provider if possible, otherwise return null - * @param string $url - * @return SearchResultDTO|null - */ - private function delegateToOtherProvider(string $url): ?SearchResultDTO - { - //Extract domain from url: - $host = parse_url($url, PHP_URL_HOST); - if ($host === false || $host === null) { - return null; - } - - $provider = $this->providerRegistry->getProviderHandlingDomain($host); - - if ($provider !== null && $provider->isActive() && $provider->getProviderKey() !== $this->getProviderKey()) { - try { - $id = $provider->getIDFromURL($url); - if ($id !== null) { - $results = $this->infoRetriever->searchByKeyword($id, [$provider]); - if (count($results) > 0) { - return $results[0]; - } - } - return null; - } catch (ProviderIDNotSupportedException $e) { - //Ignore and continue - return null; - } - } - - return null; - } - - public function getDetails(string $id, array $options = []): PartDetailDTO { - //We check for delegation by default - $check_for_delegation = $options[self::OPTION_CHECK_FOR_DELEGATION] ?? true; $url = $this->fixAndValidateURL($id); - if ($check_for_delegation) { + if (!($options[self::OPTION_SKIP_DELEGATION] ?? false)) { //Before loading the page, try to delegate to another provider - $delegatedPart = $this->delegateToOtherProvider($url); + $delegatedPart = $this->createFromUrlHelper->delegateToOtherProviderDetails($url, $this); if ($delegatedPart !== null) { - return $this->infoRetriever->getDetailsForSearchResult($delegatedPart); + return $delegatedPart; } } diff --git a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php index 8896d94b..a6e073a5 100644 --- a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php +++ b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php @@ -29,6 +29,7 @@ use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; interface InfoProviderInterface { public const OPTION_NO_CACHE = 'no_cache'; // if set to true, the provider should not use any cache and retrieve fresh data from the source + public const OPTION_SKIP_DELEGATION = 'skip_delegation'; // if set to true, the provider should not delegate the request to other providers, even if it supports delegation. /** * Get information about this provider diff --git a/templates/info_providers/from_url/from_url.html.twig b/templates/info_providers/from_url/from_url.html.twig index 15aa225f..49d4b116 100644 --- a/templates/info_providers/from_url/from_url.html.twig +++ b/templates/info_providers/from_url/from_url.html.twig @@ -28,6 +28,7 @@
    {{ form_row(form.no_cache) }} + {{ form_row(form.skip_delegation) }}
    diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index cb071128..fc42c414 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13181,5 +13181,11 @@ Buerklin-API Authentication server: Ignore cache / Force fresh info retrieval + + + info_providers.from_url.skip_delegation + Do not delegate to specialized info providers + + From e437bb0b7bc75c72d62a175171bb0305555131d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 2 May 2026 23:49:07 +0200 Subject: [PATCH 29/36] Improved translations of AI related stuff in settings --- src/Settings/AISettings/LMStudioSettings.php | 2 ++ translations/messages.en.xlf | 24 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Settings/AISettings/LMStudioSettings.php b/src/Settings/AISettings/LMStudioSettings.php index 627961a9..2bdad06e 100644 --- a/src/Settings/AISettings/LMStudioSettings.php +++ b/src/Settings/AISettings/LMStudioSettings.php @@ -31,6 +31,7 @@ use Jbtronics\SettingsBundle\Settings\Settings; use Jbtronics\SettingsBundle\Settings\SettingsParameter; use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\Component\Form\Extension\Core\Type\UrlType; +use Symfony\Component\Translation\StaticMessage; use Symfony\Component\Translation\TranslatableMessage as TM; #[Settings(name: 'ai_lmstudio', label: new TM("settings.ai.lmstudio"))] @@ -41,6 +42,7 @@ class LMStudioSettings implements AIPlatformSettingsInterface #[SettingsParameter(label: new TM("settings.ai.lmstudio.hosturl"), formType: UrlType::class, + formOptions: ["attr" => ["placeholder" => new StaticMessage("http://localhost:1234")]], envVar: "AI_LMSTUDIO_HOSTURL", envVarMode: EnvVarMode::OVERWRITE)] public ?string $hostURL = null; diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index fc42c414..8af54745 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13187,5 +13187,29 @@ Buerklin-API Authentication server: Do not delegate to specialized info providers + + + settings.ips.ai_extractor + AI Web Extractor + + + + + settings.ips.ai_extractor.description + This info provider uses an large language model (LLM) to extract detailed part information from arbitary shop URLs. + + + + + settings.ai.openrouter.help + Access to many AI models via openrouter.ai + + + + + settings.ai.lmstudio.hosturl + Host URL + + From 9c317db260d8ee0c49cbd5575659fc28b996b647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sat, 2 May 2026 23:51:34 +0200 Subject: [PATCH 30/36] Do not translate domain canopy domain settings choices This removes clutter from the translation panel --- src/Settings/InfoProviderSystem/CanopySettings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Settings/InfoProviderSystem/CanopySettings.php b/src/Settings/InfoProviderSystem/CanopySettings.php index 0858871b..3c97a80e 100644 --- a/src/Settings/InfoProviderSystem/CanopySettings.php +++ b/src/Settings/InfoProviderSystem/CanopySettings.php @@ -72,7 +72,7 @@ class CanopySettings /** * @var string The domain used internally for the API requests. This is not necessarily the same as the domain shown to the user, which is determined by the keys of the ALLOWED_DOMAINS constant */ - #[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: ChoiceType::class, formOptions: ["choices" => self::ALLOWED_DOMAINS])] + #[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: ChoiceType::class, formOptions: ["choices" => self::ALLOWED_DOMAINS, 'translation_domain' => false])] public string $domain = "DE"; /** From db86b8c33001bc1d871d4e33a830394d33635d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 3 May 2026 00:08:00 +0200 Subject: [PATCH 31/36] Accept all models for openrouter ai provider --- src/Services/AI/AcceptAllModelsCatalog.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Services/AI/AcceptAllModelsCatalog.php b/src/Services/AI/AcceptAllModelsCatalog.php index bf590128..a2f5c33a 100644 --- a/src/Services/AI/AcceptAllModelsCatalog.php +++ b/src/Services/AI/AcceptAllModelsCatalog.php @@ -34,6 +34,7 @@ use Symfony\Component\DependencyInjection\Attribute\AsDecorator; * This is a workaround for outdated/incomplete model catalogs provided by AI platforms, which do not contain all available models, or do not update their catalogs frequently enough. */ #[AsDecorator('ai.platform.model_catalog.lmstudio')] +#[AsDecorator('ai.platform.model_catalog.openrouter')] final readonly class AcceptAllModelsCatalog implements ModelCatalogInterface { From 21bad8126237a10831dd0e40a037bc691323c47d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 3 May 2026 00:18:38 +0200 Subject: [PATCH 32/36] Fixed phpstan issues --- src/Controller/TypeaheadController.php | 4 ++-- src/Form/Settings/AiPlatformChoiceType.php | 2 +- src/Services/AI/AIPlatforms.php | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Controller/TypeaheadController.php b/src/Controller/TypeaheadController.php index c4cd5607..f7e15b6d 100644 --- a/src/Controller/TypeaheadController.php +++ b/src/Controller/TypeaheadController.php @@ -244,7 +244,7 @@ class TypeaheadController extends AbstractController $capability_filter = $request->query->getEnum('capability', Capability::class); - $models = $cache->get('ai_models_'.$platform->value.'_'.($capability_filter?->value ?? 'all'), + $models = $cache->get('ai_models_'.$platform->value.'_'.($capability_filter->value ?? 'all'), function (ItemInterface $item) use ($platformRegistry, $platform, $capability_filter) { $item->expiresAfter(3600); //Cache for 1 hour if ($capability_filter === null) { @@ -253,7 +253,7 @@ class TypeaheadController extends AbstractController //Otherwise filter the models by the capability return array_filter($platformRegistry->getPlatform($platform)->getModelCatalog()->getModels(), - static fn(array $model) => in_array($capability_filter, $model['capabilities'] ?? [], true) + static fn(array $model) => in_array($capability_filter, $model['capabilities'], true) ); }); diff --git a/src/Form/Settings/AiPlatformChoiceType.php b/src/Form/Settings/AiPlatformChoiceType.php index eb48d933..82ea66b2 100644 --- a/src/Form/Settings/AiPlatformChoiceType.php +++ b/src/Form/Settings/AiPlatformChoiceType.php @@ -41,7 +41,7 @@ final class AiPlatformChoiceType extends AbstractType { } - public function getParent(): ?string + public function getParent(): string { return EnumType::class; } diff --git a/src/Services/AI/AIPlatforms.php b/src/Services/AI/AIPlatforms.php index ec772cf3..2f4d6317 100644 --- a/src/Services/AI/AIPlatforms.php +++ b/src/Services/AI/AIPlatforms.php @@ -52,8 +52,6 @@ enum AIPlatforms: string implements TranslatableInterface return match ($this) { self::LMSTUDIO => LMStudioSettings::class, self::OPENROUTER => OpenRouterSettings::class, - - default => throw new \InvalidArgumentException(sprintf('No settings class defined for AI platform "%s".', $this->name)), }; } From a15a5efdcee1a3b0a21af8d2d1348b096996b857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 3 May 2026 00:35:49 +0200 Subject: [PATCH 33/36] Added documentation about AI features --- README.md | 1 + docs/index.md | 1 + docs/usage/ai.md | 27 +++++++++++++++++++++++ docs/usage/information_provider_system.md | 13 +++++++++++ 4 files changed, 42 insertions(+) create mode 100644 docs/usage/ai.md diff --git a/README.md b/README.md index ad37e9c6..b857711f 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ for the first time. * Automatic thumbnail generation for pictures * Use cloud providers (like Octopart, Digikey, Farnell, LCSC or TME) to automatically get part information, datasheets, and prices for parts +* Retrieve part information from arbitrary shop websites, using either conventional data extraction from structured metadata, or AI based data extraction * API to access Part-DB from other applications/scripts * [Integration with KiCad](https://docs.part-db.de/usage/eda_integration.html): Use Part-DB as the central datasource for your KiCad and see available parts from Part-DB directly inside KiCad. diff --git a/docs/index.md b/docs/index.md index c2128946..700937f4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -47,6 +47,7 @@ It is installed on a web server and so can be accessed with any browser without * Easy migration from an existing PartKeepr instance (see [here]({%link partkeepr_migration.md %})) * Use cloud providers (like Octopart, Digikey, Farnell, Mouser, or TME) to automatically get part information, datasheets, and prices for parts (see [here]({% link usage/information_provider_system.md %})) +* Retrieve part information from arbitrary shop websites, using either conventional data extraction from structured metadata, or AI based data extraction * API to access Part-DB from other applications/scripts * [Integration with KiCad]({%link usage/eda_integration.md %}): Use Part-DB as the central datasource for your KiCad and see available parts from Part-DB directly inside KiCad. diff --git a/docs/usage/ai.md b/docs/usage/ai.md new file mode 100644 index 00000000..3a1fb419 --- /dev/null +++ b/docs/usage/ai.md @@ -0,0 +1,27 @@ +--- +layout: default +title: AI features +nav_order: 6 +parent: Usage +--- + +# AI features + +Part-DB can utilize large language Models (LLMs) to provide AI-powered features that can assist you in managing your parts and projects. +For now this is mostly the ability to extract part information from websites without any structured data. + +## AI platforms + +Part-DB is platform agnostic and can work with different AI platforms, both locally and in the cloud. They can be configured in the "AI" tab in the system settings. +Currently, the following platforms are supported: + +### OpenRouter + +[OpenRouter](https://openrouter.ai/) is a platform that provides access to various LLMs, including models from OpenAI, Anthropic, and more. +You can use OpenRouter to connect to different LLMs and use them for Part-DB's AI features. +You need to supply an API key for OpenRouter to use it as an AI platform in Part-DB. + +### LMStudio + +[LMStudio](https://lmstudio.ai/) is a local LLM hosting solution that allows you to run LLMs on your own hardware. You can use LMStudio to host your own LLM and connect it to Part-DB for AI features. +Currently only LMStudio without any authentication is supported. Supply your LMStudio instance URL (including the port) to use it as an AI platform in Part-DB. diff --git a/docs/usage/information_provider_system.md b/docs/usage/information_provider_system.md index 1600d76f..7cac6328 100644 --- a/docs/usage/information_provider_system.md +++ b/docs/usage/information_provider_system.md @@ -111,6 +111,19 @@ may have privacy and security implications. Following env configuration options are available: * `PROVIDER_GENERIC_WEB_ENABLED`: Set this to `1` to enable the Generic Web URL Provider (optional, default: `0`) +### AI Web Extractor +The AI web extractor provider can extract part information from any webpage using AI-based techniques. It is designed to handle unstructured data and can extract relevant information even from websites that do not use structured data formats like Schema.org. +This provider can be particularly useful for extracting information from websites that have complex layouts or do not follow standard e-commerce practices. +It also potentially extracts more detailed information than the Generic Web URL Provider, as it is not limited to the fields defined in the Schema.org format. + +To use the AI Web Extractor, you need to setup an AI platform, in the AI settings tab, and chose a model, which support structured output. +For many use cases a small and cheap model like `google/gemini-2.5-flash-lite` will be sufficient, coming down to costs like 0.003$ per request. +For more complex websites, or if you wanna use the LLM for translation purposes too, you should consider a more powerful model. + +You can add some additional instructions for the model, which gets added to the system prompt, to tweak the output of the model. + +The provider will download the HTML of the given URL, convert it to markdown and send it to the LLM toghether with structured data extracted from the webpage via conventional methods. + ### Octopart The Octopart provider uses the [Octopart / Nexar API](https://nexar.com/api) to search for parts and get information. From 45ed095509bbc057669b6a78e4bdf07cbe7fa4cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 3 May 2026 00:49:26 +0200 Subject: [PATCH 34/36] Updated composer dependencies --- composer.lock | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/composer.lock b/composer.lock index 52eb5562..d9795640 100644 --- a/composer.lock +++ b/composer.lock @@ -17435,16 +17435,16 @@ }, { "name": "tecnickcom/tc-lib-barcode", - "version": "2.4.37", + "version": "2.4.39", "source": { "type": "git", "url": "https://github.com/tecnickcom/tc-lib-barcode.git", - "reference": "86b89b0399797706a07c1fd4eec3158460b13f7f" + "reference": "11886fb5a44ec0f6e77302439e9ebf55034383fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/tc-lib-barcode/zipball/86b89b0399797706a07c1fd4eec3158460b13f7f", - "reference": "86b89b0399797706a07c1fd4eec3158460b13f7f", + "url": "https://api.github.com/repos/tecnickcom/tc-lib-barcode/zipball/11886fb5a44ec0f6e77302439e9ebf55034383fa", + "reference": "11886fb5a44ec0f6e77302439e9ebf55034383fa", "shasum": "" }, "require": { @@ -17528,24 +17528,24 @@ }, "funding": [ { - "url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ", - "type": "custom" + "url": "https://github.com/sponsors/tecnickcom", + "type": "github" } ], - "time": "2026-04-30T19:47:34+00:00" + "time": "2026-05-01T19:04:12+00:00" }, { "name": "tecnickcom/tc-lib-color", - "version": "2.5.0", + "version": "2.5.3", "source": { "type": "git", "url": "https://github.com/tecnickcom/tc-lib-color.git", - "reference": "ebb76dfb334b7a0b470e765a7b46c5635dce2fe0" + "reference": "136d522f1640723e490b79171e910e647403d971" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/tc-lib-color/zipball/ebb76dfb334b7a0b470e765a7b46c5635dce2fe0", - "reference": "ebb76dfb334b7a0b470e765a7b46c5635dce2fe0", + "url": "https://api.github.com/repos/tecnickcom/tc-lib-color/zipball/136d522f1640723e490b79171e910e647403d971", + "reference": "136d522f1640723e490b79171e910e647403d971", "shasum": "" }, "require": { @@ -17598,11 +17598,11 @@ }, "funding": [ { - "url": "https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ", - "type": "custom" + "url": "https://github.com/sponsors/tecnickcom", + "type": "github" } ], - "time": "2026-04-30T19:21:47+00:00" + "time": "2026-05-01T19:02:25+00:00" }, { "name": "thecodingmachine/safe", @@ -18550,7 +18550,7 @@ }, { "name": "web-auth/webauthn-lib", - "version": "5.3.0", + "version": "5.3.1", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-lib.git", @@ -18620,7 +18620,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.0" + "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.1" }, "funding": [ { @@ -18636,7 +18636,7 @@ }, { "name": "web-auth/webauthn-symfony-bundle", - "version": "5.3.0", + "version": "5.3.1", "source": { "type": "git", "url": "https://github.com/web-auth/webauthn-symfony-bundle.git", @@ -18703,7 +18703,7 @@ "webauthn" ], "support": { - "source": "https://github.com/web-auth/webauthn-symfony-bundle/tree/5.3.0" + "source": "https://github.com/web-auth/webauthn-symfony-bundle/tree/5.3.1" }, "funding": [ { @@ -19543,16 +19543,16 @@ }, { "name": "phpstan/phpstan-strict-rules", - "version": "2.0.10", + "version": "2.0.11", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "1aba28b697c1e3b6bbec8a1725f8b11b6d3e5a5f" + "reference": "9b000a578b85b32945b358b172c7b20e91189024" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/1aba28b697c1e3b6bbec8a1725f8b11b6d3e5a5f", - "reference": "1aba28b697c1e3b6bbec8a1725f8b11b6d3e5a5f", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/9b000a578b85b32945b358b172c7b20e91189024", + "reference": "9b000a578b85b32945b358b172c7b20e91189024", "shasum": "" }, "require": { @@ -19588,9 +19588,9 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", - "source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.10" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.11" }, - "time": "2026-02-11T14:17:32+00:00" + "time": "2026-05-02T06:54:10+00:00" }, { "name": "phpstan/phpstan-symfony", From b7cfdc310065057f4d880d0505ee40d75a940f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 3 May 2026 01:05:41 +0200 Subject: [PATCH 35/36] Bumped ckeditor to v48 and removed ckeditor-dev-utils, as they are no longer needed This removes also many transitive dependencies --- package.json | 4 +- webpack.config.js | 22 - yarn.lock | 3117 ++++++++++----------------------------------- 3 files changed, 679 insertions(+), 2464 deletions(-) diff --git a/package.json b/package.json index 172eabc0..99636d37 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,6 @@ "@algolia/autocomplete-js": "^1.17.0", "@algolia/autocomplete-plugin-recent-searches": "^1.17.0", "@algolia/autocomplete-theme-classic": "^1.17.0", - "@ckeditor/ckeditor5-dev-translations": "^53", - "@ckeditor/ckeditor5-dev-utils": "^53", "@jbtronics/bs-treeview": "^1.0.1", "@part-db/html5-qrcode": "^4.0.0", "@zxcvbn-ts/core": "^3.0.2", @@ -51,7 +49,7 @@ "bootbox": "^6.0.0", "bootswatch": "^5.1.3", "bs-custom-file-input": "^1.3.4", - "ckeditor5": "^47.0.0", + "ckeditor5": "^48.0.0", "clipboard": "^2.0.4", "compression-webpack-plugin": "^11.1.0", "datatables.net": "^2.0.0", diff --git a/webpack.config.js b/webpack.config.js index 08050353..18893d8b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -24,8 +24,6 @@ var Encore = require('@symfony/webpack-encore'); const zlib = require('zlib'); const CompressionPlugin = require("compression-webpack-plugin"); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; -const { CKEditorTranslationsPlugin } = require( '@ckeditor/ckeditor5-dev-translations' ); -const { styles } = require( '@ckeditor/ckeditor5-dev-utils' ); // Manually configure the runtime environment if not already configured yet by the "encore" command. // It's useful when you use tools that rely on webpack.config.js file. @@ -123,13 +121,6 @@ Encore // uncomment if you're having problems with a jQuery plugin .autoProvidejQuery() - .addPlugin( new CKEditorTranslationsPlugin( { - // See https://ckeditor.com/docs/ckeditor5/latest/features/ui-language.html - language: 'en', - addMainLanguageTranslationsToAllAssets: true, - additionalLanguages: 'all', - outputDirectory: 'ckeditor_translations' - } ) ) // Use raw-loader for CKEditor 5 SVG files. .addRule( { @@ -142,19 +133,6 @@ Encore loader.exclude = /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/; } ) - // Configure PostCSS loader. - .addLoader({ - test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/, - loader: 'postcss-loader', - options: { - postcssOptions: styles.getPostCssConfig( { - themeImporter: { - themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' ) - }, - minify: true - } ) - } - } ) ; diff --git a/yarn.lock b/yarn.lock index 9a4991c2..f9948f76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,7 +55,7 @@ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-theme-classic/-/autocomplete-theme-classic-1.19.8.tgz#33706300a2f711ac9386ec8008a0f119ffdccd7b" integrity sha512-FYmpeOyL5Wy444ZGp1IW57fevpMSBMewN37j+0WULMTJZGobnvTgVEKjYIgtv5Ku4/RNNp54rtEx2/OU6l8GYA== -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": +"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": version "7.29.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== @@ -252,7 +252,7 @@ "@babel/template" "^7.28.6" "@babel/types" "^7.29.0" -"@babel/parser@^7.18.9", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": +"@babel/parser@^7.28.6", "@babel/parser@^7.29.0": version "7.29.2" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.2.tgz#58bd50b9a7951d134988a1ae177a35ef9a703ba1" integrity sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA== @@ -816,7 +816,7 @@ "@babel/parser" "^7.28.6" "@babel/types" "^7.28.6" -"@babel/traverse@^7.18.9", "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": version "7.29.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== @@ -837,526 +837,459 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" -"@ckeditor/ckeditor5-adapter-ckfinder@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-47.7.0.tgz#cc565157bfb2f48abf7d2179ffc0ad3a685a806c" - integrity sha512-pl+x7dSoGg5JBgmfxBtnegA8sFPRSmCPZ2DZHsfvMzndgCsNsOl0lENmk+aBjHMlEHfKv0mEdSTfUYI2aKJqSw== +"@ckeditor/ckeditor5-adapter-ckfinder@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-adapter-ckfinder/-/ckeditor5-adapter-ckfinder-48.0.1.tgz#5124eca82c5f23d112f7c6a07207ba5d5bc7f044" + integrity sha512-qKrdKjiMmRvuXg6gV5vS+Z/fajl4TDa5aeiCQROR1RlNPO6oSxQJFjgYoE+nDMz2bkK08qbULnq86wgQtn+r+g== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-upload" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-upload" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-alignment@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-alignment/-/ckeditor5-alignment-47.7.0.tgz#41829e54f45267f69fdff37cd1b34a924167b663" - integrity sha512-MKt0i5RB4dxng+sOTGe7UVTCFMMMYw6lrXHKZaI4yc00U+fLrVNLThs0PdBytPKynaz8kyZhkzOM1TGX6n6Dsg== +"@ckeditor/ckeditor5-alignment@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-alignment/-/ckeditor5-alignment-48.0.1.tgz#667d7e8f995dba61ebd69798459567cc6ee4acad" + integrity sha512-ZvrIrz/VXX7o3SU9VnH1NxnqY16Mh2455pqpeB0YvdWOt4LFU+jwv/5S0EJGs2HqZJiD7NH+5zIS4PgmlKryBw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-autoformat@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-47.7.0.tgz#a21b6d5bd476f6b701ff15068dfa4177feca7ed3" - integrity sha512-B1fJBTxtoNwG1ucFz2rxYRI9rVawbRBgzQR0lgyfy4PkRvNGfKvqn72w1CEx9d2thPPAtJJ7zsYGTp4oFcbH/g== +"@ckeditor/ckeditor5-autoformat@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-autoformat/-/ckeditor5-autoformat-48.0.1.tgz#b93be4215942862bd6a52ac2bd414e1138136e2b" + integrity sha512-gn/CbnAPuWWxxgkIXCqUbA0XeKRsWe2Sbc2/Bf+w7rPX5MdlQ1KpfNSTiiM6R76tbWqw3RiAqDRuj6dEYTb4pQ== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-heading" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-heading" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-autosave@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-autosave/-/ckeditor5-autosave-47.7.0.tgz#224b31010610ca65362b6b9478575f12f9122a0b" - integrity sha512-B1qq3CMi+kjcJ9MUnmQ/cpB/Zc9sR3gw6fUhvnspcvSi9J+XSRQRJctMCIZDOrbtk6uMCBV4jXyGSUb6APx1ZQ== +"@ckeditor/ckeditor5-autosave@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-autosave/-/ckeditor5-autosave-48.0.1.tgz#c26767950a32d61f1b46e43484978d117cc41bdb" + integrity sha512-9pUOznmE2gmLqjVz61NDN5KK0QRcNm+o+nheu/DyEFQfboaMFPo68rkZwi1zIkdVVoNXDjqBHkU4LTVTxZJbRg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-basic-styles@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-47.7.0.tgz#a599be6e8569ec080f67a71b558d7f86a636be7e" - integrity sha512-enl1GhyyB0gpafbJ0w3IMol1BYTKfveCWvvLHRdqeBUHGYv3ixIAQC+gpMPLXv0dpQZLJYuJ47EglY+hjSOxXQ== +"@ckeditor/ckeditor5-basic-styles@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-basic-styles/-/ckeditor5-basic-styles-48.0.1.tgz#efc04e9f75f5c2f1c23f0a3a9eaf6f900e9df524" + integrity sha512-XEdxIhB/mD9Nwd/rQK6RxtKwwVC+Nd/V1MKv4hbsKd98L8HNjWHDUY2ApXg9dAr4KdpDzDjvhT9QYJsYdQ6A8Q== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-block-quote@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-47.7.0.tgz#b665788d175e183be7b055eb39db2681ff95daa6" - integrity sha512-J5/CdFPL2M1x5/ko2Zr+24GhLzWuPGAO0MBo/7Wz319mPy8C7Jk2Eyjk3APwaYbJFq395RpOaqZCz3I2ROgYMA== +"@ckeditor/ckeditor5-block-quote@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-block-quote/-/ckeditor5-block-quote-48.0.1.tgz#1f89b7d6ff2c79cdfdda7a6a6cc92d0972df6306" + integrity sha512-LWTl++pcvzxp8FL5LIyFV7bCTYU/ScFqikavPYmloVdAlusd1DAqutHxyCEADGfQZgPmG2TUVqWCBp6FQfDfzA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-enter" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-bookmark@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-bookmark/-/ckeditor5-bookmark-47.7.0.tgz#39fbd0fb419faa98662884d0b75babae1a265205" - integrity sha512-LeKmsvQL+9LVKwA1Ki1tNrB90zXW/lPOVgJePxax/eDfJ4wB+rwvpddmESL6Kyayh4akK6jIdqFSTWCmOzbaKA== +"@ckeditor/ckeditor5-bookmark@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-bookmark/-/ckeditor5-bookmark-48.0.1.tgz#aee53f084c0895f9c430b900d7a2153a0602acbb" + integrity sha512-N293hFCKt95dIFGphO1Z91qvQfgUc4wUSslqXmSFY+Rsmjr6efo42Q85oukH4WPrYjOjVmYoajqXzNU7QYGdxA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-link" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-link" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" -"@ckeditor/ckeditor5-ckbox@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-ckbox/-/ckeditor5-ckbox-47.7.0.tgz#c949ef81991a40a802857983050f11eb2a558b7a" - integrity sha512-yQd9JeaT4v2xcnRZq1zCCc3TKcHQ8i/6PzB8H4r8JdlHv52HzMVs6ID/Dh989AWiUWcVirTuRC5HXVLECqUOVg== +"@ckeditor/ckeditor5-ckbox@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-ckbox/-/ckeditor5-ckbox-48.0.1.tgz#51fddb7abaa076a5192e0f790c3c2bf79fbe1013" + integrity sha512-n6o7szp3u4aHMkENBV4VWaPIhp5Zn7UwQfHoVDfYKGN2YHyRenzjmLmDZW9QP/5rXYsPHMQjYVBW8CiTVNIYqQ== dependencies: - "@ckeditor/ckeditor5-cloud-services" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-image" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-upload" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" + "@ckeditor/ckeditor5-cloud-services" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-image" "48.0.1" + "@ckeditor/ckeditor5-link" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-upload" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" blurhash "2.0.5" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-ckfinder@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-47.7.0.tgz#0f35eb0bd718f73e73c1122eaa51e88f94014b8d" - integrity sha512-CJ8OwQhPA+GE9wxRcRf+e9H09pKQP84qlMY8R52yEKxlGx13t4S6XD+hknCVJ000urH/XAmpdHaPDc2XZ1X+pw== +"@ckeditor/ckeditor5-ckfinder@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-ckfinder/-/ckeditor5-ckfinder-48.0.1.tgz#50d6549ea1141a2000cc946e33241ca596e64bf7" + integrity sha512-UC/oMyN5XKcjwc95hPCWcRQvzNfMCcwsrfJN4CoV/EUgQRuc4g1oUCEAgiZxrNDbHsovY5wLIuPjLIbYihJctA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-image" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-adapter-ckfinder" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-image" "48.0.1" + "@ckeditor/ckeditor5-link" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-clipboard@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-47.7.0.tgz#c9f30b247256032da4cef19bd2975be6dd6be5e7" - integrity sha512-cW1L289XXylwUWj9hy927fZJ+ygFZIV+5Y4cmTuf4htMuXYKOrMSDMraMc3Py8/I4nvdkegRKLDrbHmgtTBiFQ== +"@ckeditor/ckeditor5-clipboard@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-clipboard/-/ckeditor5-clipboard-48.0.1.tgz#9507bcb0d3b3daa9e30c42930ea07817942d3ed3" + integrity sha512-uAS/vlrGZ3xGpRv4r1gr/gEp+5rUenHJsga9sLj0KXgkvg8wnbzY/hC0s58YOFRjOXQvMgkAwabvlDuRNQKWqg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-cloud-services@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-47.7.0.tgz#9937371c3ea61e2e55198d377d8c36acc368c507" - integrity sha512-Oic9q89t12xa7uBkzLcuF/QyUCieXFjQ5Wv5fs24+Z7mlM0kGgRlCtHHlPIw0PgwpEmk5ACWTI0TVHUpLRPJ+w== +"@ckeditor/ckeditor5-cloud-services@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-cloud-services/-/ckeditor5-cloud-services-48.0.1.tgz#3d24ddabd5395e88dd95aa151cc717f9fdaecb8c" + integrity sha512-U4TSzsqnzNQ5nVogqFONL+FuQ0F8i0dzUxcSIVwgVsRojbZs0zuufHvpLy4sYDK8qJD4MZhEkcKG0FlwNNwcqQ== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-upload" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-code-block@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-47.7.0.tgz#097dd7c177acff173badbf6fc0204fca447f8a21" - integrity sha512-qu5CIpschxz47Z7WCn6y/2jsK8oHReQElB35njtSVUwgOcGG2n2hxCbRnEBxM0Fllh3inIwAp56s8GUsyyiv1A== +"@ckeditor/ckeditor5-code-block@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-code-block/-/ckeditor5-code-block-48.0.1.tgz#822a57d2247762ffd885eaddc3dfa4cdf2f8b85f" + integrity sha512-728KFsW6Uj5Wpv+0hUEyqyLIW56Mt8EbaVjrhc3EXEKgI39vHOjgsfnxKeXmsW3Y+DDLhfx6JE5MAaIRqrGYeQ== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-enter" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-core@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-core/-/ckeditor5-core-47.7.0.tgz#c0fcb55cec1c1b5f851275688c0823aa8edcab84" - integrity sha512-ock9l03yxBIDHu9t+Usi3Yrx/+UKCB90aK/9DlbKp8bizwZh/48C0YOFuvY64YX/RjiXndL3VMCCYCaWzODdOw== +"@ckeditor/ckeditor5-core@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-core/-/ckeditor5-core-48.0.1.tgz#eb93ffffa8f59e72403ac17854293885c428db00" + integrity sha512-jhAMvv4GCD8aPWBdYC2RFS/xtuTubgGfSKGabG5cDFn1uHv+sGIiFdLEV8jhNFKrRgdEd2jT90KYx73izdm9jw== dependencies: - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-watchdog" "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-watchdog" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-dev-translations@^53", "@ckeditor/ckeditor5-dev-translations@^53.4.0": - version "53.4.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-dev-translations/-/ckeditor5-dev-translations-53.4.0.tgz#3b76d6825aadcf9c183cbc8a712033f59d860346" - integrity sha512-e76aPDJkbJen3W18QiddkklsM0V6NdBXL3pLDmnSKPqIDbknOh49Ov/ciDwxWqMIKDqf9n5PnTaRXIDONUO0TA== +"@ckeditor/ckeditor5-easy-image@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-48.0.1.tgz#2c8d1995052c6c25b689b33843fb376a65e94033" + integrity sha512-mXtS87krxR1infQ/7BIS2kY4h5dLPdJhIyPyr15W6MlT48j79CG3OfWFeXUO11RsKHFs9oB+bIqLCb8wq5Tt3w== dependencies: - "@babel/parser" "^7.18.9" - "@babel/traverse" "^7.18.9" - "@ckeditor/ckeditor5-dev-utils" "^53.4.0" - chalk "^5.0.0" - fs-extra "^11.0.0" - glob "^11.0.2" - plural-forms "^0.5.5" - pofile "^1.1.4" - rimraf "^6.0.1" - upath "^2.0.1" - webpack-sources "^3.0.0" + "@ckeditor/ckeditor5-cloud-services" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-image" "48.0.1" + "@ckeditor/ckeditor5-upload" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-dev-utils@^53", "@ckeditor/ckeditor5-dev-utils@^53.4.0": - version "53.4.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-dev-utils/-/ckeditor5-dev-utils-53.4.0.tgz#0670275678525c8ee326fb39192256c6ac9c9c19" - integrity sha512-Ppd7MsgpeVWO5xJ9x1qcYN+ar7Cb41w8WSiJFE2VvsY7wDCxIa3FffK3adB01qFa8+criH3lzhy93PiUfm0h7w== +"@ckeditor/ckeditor5-editor-balloon@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-balloon/-/ckeditor5-editor-balloon-48.0.1.tgz#bb55c5cb78f1bf2103dfaf74b6e6ee9a3ce479e0" + integrity sha512-wpYCOpNdh4DWkGsuYX9IxK0Ednij4KecvqTcFhKS6rswkiY6dfDJq89qKuyHvOZA5Mw2cElaCCX8ogY/xKeQ5Q== dependencies: - "@ckeditor/ckeditor5-dev-translations" "^53.4.0" - "@types/postcss-import" "^14.0.3" - "@types/through2" "^2.0.41" - babel-loader "^10.0.0" - chalk "^5.0.0" - cli-cursor "^5.0.0" - cli-spinners "^3.0.0" - css-loader "^7.0.0" - cssnano "^7.0.0" - esbuild-loader "^4.0.0" - fs-extra "^11.0.0" - glob "^11.0.2" - is-interactive "^2.0.0" - mini-css-extract-plugin "^2.4.2" - mocha "^11.1.0" - pacote "^21.0.0" - postcss "^8.4.12" - postcss-import "^16.0.0" - postcss-loader "^8.0.0" - postcss-mixins "^11.0.0" - postcss-nesting "^13.0.0" - raw-loader "^4.0.1" - shelljs "^0.10.0" - simple-git "^3.27.0" - style-loader "^4.0.0" - terser-webpack-plugin "^5.0.0" - through2 "^4.0.0" - upath "^2.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-easy-image@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-47.7.0.tgz#04a7424c5041025f9d0c92642035dee67119b406" - integrity sha512-gk3KDAawRvr8HprcoySSl/t7pkYgVZDnZQP6dVrzyFHo5xyPxkW1DLQFsiqwVAJPr12PVBnkYUGycTwFRf2e7Q== +"@ckeditor/ckeditor5-editor-classic@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-48.0.1.tgz#0e571a7a0e52ec2a88edbb708d46e7fe4ff62b69" + integrity sha512-EUtLco5ZP1b8EsBULlh+CJ+R2QSHpTPTe43TyugsjHR2Ead03XkhR6Xw1Wbd2KBJjlgrHOi3XuXpQNtFlbZtnQ== dependencies: - "@ckeditor/ckeditor5-cloud-services" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-upload" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-editor-balloon@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-balloon/-/ckeditor5-editor-balloon-47.7.0.tgz#3b6c433d82926c930846d6d1669318f19aab83ea" - integrity sha512-VyUa59C5hTpXW8DWjRnJsdHMkQiDOCjg7bCni7/u/9XcrgYbUWVSc4PThh4H104pS9TJSyIKyCSf+OqpyCqArA== +"@ckeditor/ckeditor5-editor-decoupled@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-decoupled/-/ckeditor5-editor-decoupled-48.0.1.tgz#df62cf6ec1f221c5e5d25a36646aa4da0697d053" + integrity sha512-NrIjEoqpuxd+FNbI6HxW8GIskjc+s7I5LGkOfyl9BcBcVNjEfqAHmfK59X7xuZ6uPxse8X61BFgDini+qgYdHg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-editor-classic@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-classic/-/ckeditor5-editor-classic-47.7.0.tgz#19efbb090601c42604db876d990260b5987eb076" - integrity sha512-iwLgAqrnc4Eu9YfQHTcgmrztPUgOj2Zyc8I3725WnRO2vil9Y6qFDx7JXYt3MhOfj358/D/ncIjSL0YSmyWgkw== +"@ckeditor/ckeditor5-editor-inline@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-inline/-/ckeditor5-editor-inline-48.0.1.tgz#fffc0e0c0e0a565a5f1fc7465e00bc84c263dbc8" + integrity sha512-ZJlG0DH548aqcNzvWAIwWrg9cOXBBv7DBKwCCPTk6D4x0VdGXnaaewdbIIj6gxIip6j9k3+YDjsloPDFAzoyBw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-editor-decoupled@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-decoupled/-/ckeditor5-editor-decoupled-47.7.0.tgz#a245bd370464493231d89c5956b5e1b49179e9e6" - integrity sha512-qQectSzm8heNQqkaaj+wx8YXKBmuiHp0F0IneQrcruPK7UScQ8pYF83k3NO+wCga4AtPXki5IDgM3VRN/6xuiQ== +"@ckeditor/ckeditor5-editor-multi-root@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-multi-root/-/ckeditor5-editor-multi-root-48.0.1.tgz#5d9b139be8277eb182239ecc8768dc4758d1472c" + integrity sha512-wu0YK4QrOGUqfAvb47nSJuC3PWUJUmKS/7qY8MOyBppoa9jrHxzsnjyMvzTNBpbMy5h0qB5OXeT0nCpF1Z22oA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-editor-inline@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-inline/-/ckeditor5-editor-inline-47.7.0.tgz#73ffc87e18e5689000bedc58471e34c756d125ff" - integrity sha512-deXc6pqT/no8zIyKnydfazK3fXXOrgkuP+4AMwNrkEqB17anWduC5LcUN0OcYz9AdEECpUsNMoONkvpdMsIS6Q== +"@ckeditor/ckeditor5-emoji@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-emoji/-/ckeditor5-emoji-48.0.1.tgz#4cecb17be007b77993a9fbbc561acedd1fc3a4bc" + integrity sha512-z1iTGRNwZ9zvIqLQSCr/aL2/kq/xmBMdat5j86//cG1Dv9a5TgwbhUBu9EZJLQvFnZ7FF18peX2mYY/MAyklhA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" - -"@ckeditor/ckeditor5-editor-multi-root@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-editor-multi-root/-/ckeditor5-editor-multi-root-47.7.0.tgz#ad12bfb6cefe71085d9263bfd18a9ff2ca1ea7c5" - integrity sha512-yvJPqmm5F3Oy8QQBHhGJj2vRKWyPcbmBjQ9Y68efeMwzwVl8toELTs7Ro6Kx8bYhIxjz3MphGExSqIQXxadZCg== - dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" - -"@ckeditor/ckeditor5-emoji@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-emoji/-/ckeditor5-emoji-47.7.0.tgz#58aa3bc2380b34297492e5d84265b131d09dfc60" - integrity sha512-bXXuPnFsDVvv7LZKoiPGKabncpKha3MNcyzseoJ+I9Ong33YUtAKwFlXje5Tuc6dp+mrDUjuRGxk0raXetj3HA== - dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-mention" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-mention" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" fuzzysort "3.1.0" -"@ckeditor/ckeditor5-engine@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-47.7.0.tgz#745faf784de5120e81c2018332524b1215ba767c" - integrity sha512-RSeJPqi0dEaJmPqisaeQwRoouKsnvAJGnBmpAzQR8eVZh4qrP7+Ek+GwSbAo5iZkhNHfmurQSF7pxQsPc/020w== +"@ckeditor/ckeditor5-engine@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-engine/-/ckeditor5-engine-48.0.1.tgz#95825069321034aa11dc017f9188651856152b0d" + integrity sha512-qT+SOBibvH3pr4I08myvyDLv09tofA83umwsA4Mk8sG+9yqeEx2AEKUP8lu6sUzfe/WKLwOUIAT3TAWWt+Oheg== dependencies: - "@ckeditor/ckeditor5-utils" "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-enter@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-47.7.0.tgz#2c103f0f7decea1282c51dd30bfdf81d60e7e390" - integrity sha512-nU5vOxTBA/6UCa2qccQvPo/Aq9d9p8g9D45jlCaPJdsqf1YJO1baxpz+1qAqjCS1MfpyaarGiQ4YAhM6GEMC1g== +"@ckeditor/ckeditor5-enter@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-enter/-/ckeditor5-enter-48.0.1.tgz#4e9368c341b509f023a23a65bd54538543643440" + integrity sha512-U48yfgYvtKNJbVO2E72KrFJjFkR06nkb//zA5uubEuwPYVQi/L3AWaXsPEviowq6Hv2nZHmOF0YcKqgNyHuBUA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-essentials@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-47.7.0.tgz#a6153af07a9b8607e46b61ff26f83fd5d9b5d735" - integrity sha512-h95DiV1Vbi3UtwFigM2m+2gjZtvNqU1ryIqINOaArikpqcMj5fZ6N8QblBwNSaeWwMTLIBXMJpck26g+C4zPHA== +"@ckeditor/ckeditor5-essentials@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-essentials/-/ckeditor5-essentials-48.0.1.tgz#7c13f61ac18a2a814368ed6124b1c46894fae845" + integrity sha512-wLiEhL11pQBAGWRCx5mWn0FSZOUq2bTvAnAQIVLUitz3pJcH4GQsAUrCfGRLm6ZRyy+oU69MddSVFeLl1Dqs7g== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-enter" "47.7.0" - "@ckeditor/ckeditor5-select-all" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-undo" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-select-all" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-undo" "48.0.1" -"@ckeditor/ckeditor5-find-and-replace@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-find-and-replace/-/ckeditor5-find-and-replace-47.7.0.tgz#839c917476eae202f466fa620e58f488aa5f79d1" - integrity sha512-es2Vqsh3OCQsBUdNCC8FEIPaIM7pP9jAH4w42E4/qnnZO56xjbiQAW/TNISswYiyfrhHFt6OAIVadvq5llWdyA== +"@ckeditor/ckeditor5-find-and-replace@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-find-and-replace/-/ckeditor5-find-and-replace-48.0.1.tgz#6bd78df79f3366fe0a5e3ac4ba226f1ca889ed5d" + integrity sha512-tfyvqZRV8BC0w0c/YCpWAyIhVVce09Z/NLcptwLkFlH3pXAoYt3iOMdctmGCNXMCFaH+J21B89hNox3twmQJqw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-font@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-font/-/ckeditor5-font-47.7.0.tgz#bf4b6158bedad9da112aef68a42a2f7a9210ebac" - integrity sha512-QJalhR9CA6tlxVydqwUv3Hunzy9oI9hqkzt4D6din1CIR+xxxp4Wokr3Zkae22jFzT7KrI7k7wAA9uD87Lu+sg== +"@ckeditor/ckeditor5-font@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-font/-/ckeditor5-font-48.0.1.tgz#a977d55f294b3e38001220c2ca8a9968929fa171" + integrity sha512-mbYk3b9XGNYi6+jQ/9Rkl25RvqzPfZCZ2RMuznwSre+wrlcnLHiyJULOen5aesuhQcOVJKloVwzV7YQu+aKUXg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-fullscreen@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-fullscreen/-/ckeditor5-fullscreen-47.7.0.tgz#cf7003c46e4ef255d28cd366a222feace4eb49e1" - integrity sha512-nOul8Dc7xeRGr84rvmoAKrAwSsWghUxPCMalLt74JVMqJR9F8pq9Yyi0Dd/5VI2X8wNCZ6IBnTQDoNbmEHN2sg== +"@ckeditor/ckeditor5-fullscreen@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-fullscreen/-/ckeditor5-fullscreen-48.0.1.tgz#22838b778c7b2538a8173bac9b3ecc56009aa98d" + integrity sha512-ZczSnvffikjGUTZc8AimIrFza7ugGkDhA9v/MxWYDz8u5fvkNUO6LsJ/dM3flAQo7QbFpjf48apj1pRo2wxBCg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-editor-classic" "47.7.0" - "@ckeditor/ckeditor5-editor-decoupled" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-editor-classic" "48.0.1" + "@ckeditor/ckeditor5-editor-decoupled" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-heading@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-47.7.0.tgz#9f56ba371bfe1c54dae83e58cb60729c0ede9ad0" - integrity sha512-6W/7lzqNOBxhDzU+cPsBJGeRZgc44Ybaph/hmU9QHEUYdYMcPX4nCHtd5C5ydI21dWvXb2g+YLyMIbtS0m8TkQ== +"@ckeditor/ckeditor5-heading@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-48.0.1.tgz#a7b6cd10c5e0dd787c7d787fc603a8fb8b9d7e20" + integrity sha512-s/6Lx1mlTomyd5o0pE7LiqfSJfUPB3gE018lZqxKjNOPqDnZ+tuzoXxHpJnmA/Ir06giSVXxpM1LkzDL6qtROg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-paragraph" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-paragraph" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-highlight@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-highlight/-/ckeditor5-highlight-47.7.0.tgz#ea3c6b249c0d24fecd1d81b37a4507c2d31e5f55" - integrity sha512-XTDHEMG4hyX6+eFEoJMyWzUTShWNn2If0bBr2A5YiEAVhPDVdv0zygT7V45npBDD0ja3qlLbfhSeSUfDg+c5uQ== +"@ckeditor/ckeditor5-highlight@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-highlight/-/ckeditor5-highlight-48.0.1.tgz#24fd0a13d3c55df2bd1d86db23cf361b19ff672d" + integrity sha512-2Ho4bVzZDd+uZ9IujbfLGZubCugGenGddFbyZ90TT7fQGuDMcYwpsc7p655cdDOeJ0BiyYXA01gN74AK13Hf7g== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-horizontal-line@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-horizontal-line/-/ckeditor5-horizontal-line-47.7.0.tgz#fb0f08a270009671eb9b2b1aef8569f199bd0f39" - integrity sha512-v+dbreSLaNFk0XrSCs2hvT4OK2JC5KTtrr8DBqq//LW7uIrW6WbONX5NksO4Pc+qRRH0k9vrd1mW3EG5MA6G8w== +"@ckeditor/ckeditor5-horizontal-line@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-horizontal-line/-/ckeditor5-horizontal-line-48.0.1.tgz#44858471499c799e03f981900e7cbe332b4c1c60" + integrity sha512-YqUtXT8uXzCKVtv5YSq7DRItelU0+tHzTmUbxoTPNaEbW2qmKqJSzKeq1VYO6hMtyrLZKyBDmYrXf7aFAzy6Vg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" -"@ckeditor/ckeditor5-html-embed@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-html-embed/-/ckeditor5-html-embed-47.7.0.tgz#0a898dc62853da5d9b4461e3f17b4dab88de689b" - integrity sha512-0gyJLXkE8V9kLVLSWa71biNN49FeqkJbDe26eIeT1baqmoFDUeGmiZZLVOgHGa8oCXUixnJDDho06gOrEHy42w== +"@ckeditor/ckeditor5-html-embed@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-html-embed/-/ckeditor5-html-embed-48.0.1.tgz#b284ca6f931799a8eae96d713fc36b01942118ac" + integrity sha512-Y1g0iP3JVZ8Ff73XeT/5lbXzX7lmhyM7v+4sC8g+zNP7++48KKHCJGrbbllESJ/oEWX6mmsFOJJy7L0yREQHHw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" -"@ckeditor/ckeditor5-html-support@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-html-support/-/ckeditor5-html-support-47.7.0.tgz#39483a55dddf8438c12fd2f25e16121c95561772" - integrity sha512-mczD/kr63l2QR4Pt+uJYGpvRvh96U82hTb0EJkqYei8IfWYXlsoaQxo0pQ6VoK8uOcLU0GCT5Sj2ruDnUd4uvw== +"@ckeditor/ckeditor5-html-support@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-html-support/-/ckeditor5-html-support-48.0.1.tgz#73c7461fd340997acc9c8d3f6f93f5bb9a93dab3" + integrity sha512-zM1co42HVyRJlOoG+fqjlD5CuTQ4dnNONt/a14Hr8taTGODnA967VXRoakVqjEo/e5FiWXThsBZRy3GoRIWjQA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-enter" "47.7.0" - "@ckeditor/ckeditor5-heading" "47.7.0" - "@ckeditor/ckeditor5-image" "47.7.0" - "@ckeditor/ckeditor5-list" "47.7.0" - "@ckeditor/ckeditor5-remove-format" "47.7.0" - "@ckeditor/ckeditor5-table" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-heading" "48.0.1" + "@ckeditor/ckeditor5-image" "48.0.1" + "@ckeditor/ckeditor5-list" "48.0.1" + "@ckeditor/ckeditor5-remove-format" "48.0.1" + "@ckeditor/ckeditor5-table" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-icons@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-icons/-/ckeditor5-icons-47.7.0.tgz#b35c3c62990198ca422938f904764eaa34bce913" - integrity sha512-4g4uH43E3EX9Sg4e8VYzaeD/GJINQlC1Zp8Gqdp22LRfQCXbkReVl/6dEZy//tmDm/9sBGzCSFXF4OhjowMS1Q== +"@ckeditor/ckeditor5-icons@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-icons/-/ckeditor5-icons-48.0.1.tgz#ca04369f2381d13e13658b18de008827080019bc" + integrity sha512-aulG/+JEtn5R1Ku0pygKfYffQfARqaEB5l7g50JFvnXDSpUGHP/mx1EbzzvdNyiAAl67PpIGe8VtxyovxC5u5Q== -"@ckeditor/ckeditor5-image@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-image/-/ckeditor5-image-47.7.0.tgz#70fccd666f3f7b6811458c942ac355c797905ec8" - integrity sha512-iTcZM9IsrhOqBZMKVv7fIU/j0ycDQgBwegCMUGHF/ZNpsAxLExSb47m3lo1SZIxINq+1D51aa6NkPGAyGubTHg== +"@ckeditor/ckeditor5-image@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-image/-/ckeditor5-image-48.0.1.tgz#39589bc1c036ff785a64e90977d6bbdb26cd27fa" + integrity sha512-ISfJBqYISHo+3p++GNCTXvNSWq88XAMugyyOQWoY7oxsbfOsqsqZ5e+MjjrWgzUNKOlzR/VRzuPHTN/r4sfQtw== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-undo" "47.7.0" - "@ckeditor/ckeditor5-upload" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-undo" "48.0.1" + "@ckeditor/ckeditor5-upload" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-indent@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-47.7.0.tgz#2b6f6996747ebab9c02ea0829cfd6f620f472017" - integrity sha512-CVmYtH3ATma0tQdaZt9hHM3j5bf8bNLbPW+99wLPnI8BMqVG+cCEUc/PuqJqq/OcUXkkrfQYUgvZ8Ki7TRGcbw== +"@ckeditor/ckeditor5-indent@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-indent/-/ckeditor5-indent-48.0.1.tgz#af8a841c12c72aadb20eeb9e02eb0576d6c6ed7c" + integrity sha512-0YShggoO85v9WILMF07Ld9afhcpekH8NeH76QYSoBQm7hk5RRUVbAFRHnTTxXwe8KY02m/mymgtHoToZFnrZeg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-heading" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-list" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-heading" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-list" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-language@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-language/-/ckeditor5-language-47.7.0.tgz#01748eb57b1c7c8ff8063e00e0a6df2124435a87" - integrity sha512-VsxHrcqPpojGwP+l7ZS31HrNbGIYnU57pZZH2vySvSMHB5HePGmwj9KqOtR2g1VPvZaET/1ODQRMBo+2kUk/iA== +"@ckeditor/ckeditor5-language@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-language/-/ckeditor5-language-48.0.1.tgz#b7f6dc026cd69275dcb08b4211673b0184b3e69e" + integrity sha512-5pwHJFGnxId1XHg9kw9ufwDxL7ott6jT7arhoPM0C3n60XwNIf9znjjmjPtkdAR/m9+EgDSADhqSyXwIdbwyqw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-link@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-link/-/ckeditor5-link-47.7.0.tgz#16a02d763d8bb15d0b70644eb9cff64ce5d7c72b" - integrity sha512-+ZydBFDnUYYNGhlB8wYsMOUQB+UmnU+Xlq40ld5opFxlKGMCnj/+FnyynzEj1i1wPdbaMVjUTEkojz1K/TzttQ== +"@ckeditor/ckeditor5-link@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-link/-/ckeditor5-link-48.0.1.tgz#d87d9cd8f2dfb590502340f3a57a83cdcf3dc862" + integrity sha512-giGxJeWN16eS5yYm+11QOjrXFocXfknfpmvyZlRYJ7NEwruYxUuf1Co5je5x/8iKBD2Qb6RLOzhBWF2WNWvErQ== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-image" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-image" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-list@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-list/-/ckeditor5-list-47.7.0.tgz#c3c477dbe2b53e0959e393e6f9bc77672413aedc" - integrity sha512-cZ/HAaVg2nPmCPpT9Ts4vGCN5XEEMnFQhKvd9J+hjOCfAZVH8dQCGIIpk+7fQIjs8i33mk8VefsSLFlZAxLUwQ== +"@ckeditor/ckeditor5-list@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-list/-/ckeditor5-list-48.0.1.tgz#2e41327a007fb5ca6e555c0be6e85bce7f57dc5a" + integrity sha512-LOjn8ZDPjI2seVRUrNGqgK6csoUGNjywmJ3CyaH2U64AkXWzQ7uTvli8WkeU3XCwIjx3E11W/dwYH69k7KKX3g== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-enter" "47.7.0" - "@ckeditor/ckeditor5-font" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-font" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-markdown-gfm@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-markdown-gfm/-/ckeditor5-markdown-gfm-47.7.0.tgz#a99234f8ac05902fb3db22ca4381e1ff671e439e" - integrity sha512-DgsROdfPXcF0YHzv7WbGTf4F4Li4uTYMOaI1uIPeDtkAovA+kdHjemB7/U7ZcqcphxCTrkTZYC+d0XY3ceakoQ== +"@ckeditor/ckeditor5-markdown-gfm@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-markdown-gfm/-/ckeditor5-markdown-gfm-48.0.1.tgz#8593dc571deb9bb12436c4544e14ce61c585ef0c" + integrity sha512-c2uYCOSgBD9yAm2T6jh368QCfCytzl9UuM0+E/tDn8hLizBUVgAAHOrhmLOWEcKcuFW5OoJ7ly9JmL7WWKLuaw== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" "@types/hast" "3.0.4" - ckeditor5 "47.7.0" hast-util-from-dom "5.0.1" hast-util-to-html "9.0.5" hast-util-to-mdast "10.1.2" @@ -1372,423 +1305,270 @@ unified "11.0.5" unist-util-visit "5.0.0" -"@ckeditor/ckeditor5-media-embed@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-47.7.0.tgz#c86629201a0857c522f4a775e4b7484c314ca7d7" - integrity sha512-RwtLuL73Ld/JoOXQobmUwZYtExtfwId3FETmzqXkVr4OT7+tYdyxDuRbELBjw0fHCPCndR90/mzlYftMbVIK+A== +"@ckeditor/ckeditor5-media-embed@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-media-embed/-/ckeditor5-media-embed-48.0.1.tgz#3fb3a5b10d74757f3633b2b54c09606b3d2875df" + integrity sha512-npwJbS+++Vf4uLYC92cLzJGRav2fH4dPwkk7L+O1UCvf5Kg3XpP53nf9a5bIk75WLWlJnm/15Z3RMH/oTPbVNA== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-undo" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-undo" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" -"@ckeditor/ckeditor5-mention@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-mention/-/ckeditor5-mention-47.7.0.tgz#2a690b99530511a4ff1f92e30be5270722c89771" - integrity sha512-VLsXMWzUBz32/peIUJo0Q0hpKuEuvbmeyBLTMg+xtDquMtur2skKqvasHFW8HxJCHGCE9x57NDfVyNoeITMApQ== +"@ckeditor/ckeditor5-mention@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-mention/-/ckeditor5-mention-48.0.1.tgz#fc4257d18a1ac8bd133177a8a87b1ebc08c8bd42" + integrity sha512-Dxidz6L+XTSGsOpzqyG0mdOKWo5XJleglZ3AjhGz7nKjcbEbQUF9PKD/FdaUi/XYJFjRcdDq8VFHUzTZ5/Zl1A== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-minimap@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-minimap/-/ckeditor5-minimap-47.7.0.tgz#5b40cacb35182ffa1b6864da7b446c58da5d1cc7" - integrity sha512-okM1UYc83CWyrtQXZXNGK+2GICjrEgE7DGAR9ZD0RxVvNm00tGTRuM2pTEhRvbMQIN3dyrfYpzo5/EQt8X2hMw== +"@ckeditor/ckeditor5-minimap@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-minimap/-/ckeditor5-minimap-48.0.1.tgz#fec2b968df751f0d438c51c8b44db28acd1b8a2c" + integrity sha512-XdqzY0KOJ9ouzz8LhoCGzLUUDmAYGU0mQ6IPlrmr0cpMS6RaMQA5kdr3YzSKIBZE56pWlRlMnGLvuqcGlqFQiw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-page-break@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-page-break/-/ckeditor5-page-break-47.7.0.tgz#f91d8ed9b4c914afe2fc0192ab2df6ad2c234205" - integrity sha512-gxdDmu5R8VPLL6jEsycIIESUH74d+aK/8rqpvVIFkpUmGmMiLxYkpD4++5mN/1uD037kvEOvI/y+L1qH7NN5dw== +"@ckeditor/ckeditor5-page-break@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-page-break/-/ckeditor5-page-break-48.0.1.tgz#b24e98e0059cd5d2a225394df7655295b7bcf1cc" + integrity sha512-ojacQc8bpkcVCon/wAXMgcws8+YQCdbDbHZehCVVtZz6knImC4y5lEcrMS1M4NqhBcGTynL7nHi/MDiw4Ry3Fw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" -"@ckeditor/ckeditor5-paragraph@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-47.7.0.tgz#57b643db328464e31b431d34112a7c1391341e04" - integrity sha512-4yEdALU/UT1lR/7GBm1n5u0Id30m8MmIvQ67fbmDBWK+eqH+MFLobpBMEmuU4KLBeRU5qhX4JapZPUNBOHa1YQ== +"@ckeditor/ckeditor5-paragraph@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-paragraph/-/ckeditor5-paragraph-48.0.1.tgz#67af00da1c9b60192c5c57f7feff3a024a3450fd" + integrity sha512-/+EXLxRk8G8qcm5g6xOG2vuFd8Wq2jdGsoHNiqRa8pJnSHRMlT8+olT4tzV4FzGtaGvcTfodCjVobDhbfJNrWA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-paste-from-office@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-47.7.0.tgz#8648e5dbb5b6344f82f5a1fb6ca4408900f79ad2" - integrity sha512-MNFJITMDP+ar01pERwIRyrhiSkAyvwfP2LZEPzHI952guhx7SprTOC/GzcTf9mK7wabESb1uI194Xa/5Fym8wQ== +"@ckeditor/ckeditor5-paste-from-office@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-paste-from-office/-/ckeditor5-paste-from-office-48.0.1.tgz#70e60e8f13f7c7ae9f621d0ae19f38e4d0ae0b92" + integrity sha512-vla3v7zsLz6JctSnn4XzxexE2DH6bpF7A4BNYsIsS1qeBIYmuvOU0gsVI6+viBQTGfDx++p1GGar7XuaR0loUA== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" -"@ckeditor/ckeditor5-remove-format@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-remove-format/-/ckeditor5-remove-format-47.7.0.tgz#1455b7fda38f27c6adbbfb85a0d201a80153c1f4" - integrity sha512-pCwoN2oqAuQ58fgsKyTWpfakCn3o+g9hH225IcJwq9IXiEHgvbvjTdK/8ATjSbPb3G+e4OFglYo7RuElGhFXqw== +"@ckeditor/ckeditor5-remove-format@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-remove-format/-/ckeditor5-remove-format-48.0.1.tgz#44dca342f5a98f893836deb1decc18276a607f6b" + integrity sha512-LwhU/NOOjIy9ejr/zkJOBh7bTxg3kea1gXhWG7S1z6+F7K6f4mvrjiVO5yutThbp8bWLUZlKxNiSIJ79etgXdw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-restricted-editing@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-restricted-editing/-/ckeditor5-restricted-editing-47.7.0.tgz#f86abcd1f243c7f17d15bd0ba4cf0c548ffc0825" - integrity sha512-jIndEBQoVHV1aotNa9Ceec/xYo33XNa2GQgxxnCcZ5GxU2GOj4qI9wbXVRES0RceLk6AH+k0j+U4jOMgpXeqIA== +"@ckeditor/ckeditor5-restricted-editing@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-restricted-editing/-/ckeditor5-restricted-editing-48.0.1.tgz#ae00231f40347838bcfc90fead37aae948d2b592" + integrity sha512-yUIkiCC0vPo7atsC0PlKkVQDcmV4foUnZdizhdSmDnDNnDimqvLNIa0pGDb9D2MrMVUMPhv+8eCE+QpOKNm/+Q== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-select-all@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-47.7.0.tgz#015125a72cf9022261f561858f62fbe131cd0adf" - integrity sha512-KT+2rDWwSynw2lQBmSdrh6emKahHxMOk3GqpSwX28jR+M6sDIFvNGQ0y2AvhGbphn69Tp+fZ85p6b3A/wj52rg== +"@ckeditor/ckeditor5-select-all@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-select-all/-/ckeditor5-select-all-48.0.1.tgz#923671d34423aaab7246126ed0bfaab448f57ae3" + integrity sha512-KoAQnaJ/buWUjKgj0k/p5wsOSWfi1qEJQDHWvrKY6tPuULD1/PtqVOY124Y0zai/ndZOpvT1X0tyaOXXA2ipig== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-show-blocks@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-show-blocks/-/ckeditor5-show-blocks-47.7.0.tgz#fbe793e73594e0af18c1222821b76c9f2a0076eb" - integrity sha512-lgeWUZw8Taa2zzs5GJkARmtt2YUWD797snGZZxcLuOECicXgPonqqKceU0zHGZNC+vUul63EDXA/uDd4xRy1Vg== +"@ckeditor/ckeditor5-show-blocks@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-show-blocks/-/ckeditor5-show-blocks-48.0.1.tgz#7791c7e9722c751f86aff74cf3876299cd979c7d" + integrity sha512-BR9uJxxuRhwBrVIbzw/O09q4d8iAkzz88rUHXgDe1pICzUUqrqYw0/qjzgc4EL30IvPdTtm5UmtU5dOVuFmVNg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-source-editing@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-source-editing/-/ckeditor5-source-editing-47.7.0.tgz#b6232479ce523c98f7929d4a50891314023493b6" - integrity sha512-HQPVq48p6hoZus3rrGe5BY8ailE+4v/fR5kIzTT2aiCQ0mo/k6V5TcsDs5KNJBRRlXBvQt3H3Vc9gZ/6JRUizg== +"@ckeditor/ckeditor5-source-editing@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-source-editing/-/ckeditor5-source-editing-48.0.1.tgz#73769857d147167c2190c46d3393b609016c97d4" + integrity sha512-n+uSghFxWyMg1DEWme14A8n/FLWglRtuIRBpgcUbft0Rdpe3nD44uCFNjmgbYhHjGX+Bz3DBrEbSnKxquv7kdw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-theme-lark" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-special-characters@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-special-characters/-/ckeditor5-special-characters-47.7.0.tgz#f90b9fbba11f35c8d28d241812da47a26a3cce39" - integrity sha512-AhPZ9KdrytVucNdt6jMOXve/9aTiPRIdEe1WaZ4GMNhSbWEj1qeT/UbPnJm8puIJ/Epmvq7bXPjV9qgXu4/5Pw== +"@ckeditor/ckeditor5-special-characters@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-special-characters/-/ckeditor5-special-characters-48.0.1.tgz#04a9025b7efd62a3b488512a19a3179397dfcf93" + integrity sha512-ZziowQbdNUFokvjlIe6ZBg+3IYyUW4vUiEaudiA9NPN15W6dXvJNyJ0ECYako8NtcVLB8OBR/Ow/q723TIcGQA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-style@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-style/-/ckeditor5-style-47.7.0.tgz#cb0873a06824993d22362e55617a8efa71bf76ee" - integrity sha512-fwaXaZP7tfsstKPfm5aW+DvJB5RpaSCASEYGbvXdTvjHANL6RAKx4SX+voOyxid+vZfdbYPJ6WrARWUI/jF3DA== +"@ckeditor/ckeditor5-style@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-style/-/ckeditor5-style-48.0.1.tgz#e1636cac8016622b63832951c5efee5bb6476299" + integrity sha512-bX+OaEHlvno4TrqkSB2b5J76r0zhovfRbpMzyS4Ij1KWJyVKVMesEt4tOeasUYN34q62DKQBO6aCksiuzk8r3A== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-html-support" "47.7.0" - "@ckeditor/ckeditor5-list" "47.7.0" - "@ckeditor/ckeditor5-table" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-html-support" "48.0.1" + "@ckeditor/ckeditor5-list" "48.0.1" + "@ckeditor/ckeditor5-table" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-table@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-table/-/ckeditor5-table-47.7.0.tgz#a5a0132db64993bc2d237193a8b4096c4ed1059f" - integrity sha512-F0bnZ0j97ooDCv2AaqQyUo9J3rYQYpjAppdwilCaoYHmfpGnx++SI6rqTSfb29pHSOhXoVLwmeGR7sit4OxOYg== +"@ckeditor/ckeditor5-table@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-table/-/ckeditor5-table-48.0.1.tgz#f31b2c2ab34fd9dcdca3d595589397a47e5b5dee" + integrity sha512-RVnNxYprfDE8AQtvIxZT1JJZ2En7aj/qKA+lo5E6j0CngmGRLTkXHTcTXy5YuwdKMo8RM1SAAexNzlvLHHqRQA== dependencies: - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-theme-lark@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-theme-lark/-/ckeditor5-theme-lark-47.7.0.tgz#2c9d6a5449353f08749f3094b479c28874ef6de1" - integrity sha512-MKyDX8Qgg/tskT7VJZC/s71tYYstOZmYGlZj82AKRxTMYC8KB5w0ikCVzxkOAbD3eYOc8xlyZkYHQznnx6NiJA== +"@ckeditor/ckeditor5-typing@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-48.0.1.tgz#f12d114cc34b7f9b7da5e9e037b2168765e3fb49" + integrity sha512-mfUHVEnm4XuyWofg/4o+DL6h4WPPanToEJL0Ku5QZhZNqJ1jysCADXAkmOwzkSXowT4y/dyGF9do6Z8DL3PH5w== dependencies: - "@ckeditor/ckeditor5-ui" "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-typing@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-typing/-/ckeditor5-typing-47.7.0.tgz#ff0f2eddd60a1bd827e36cfda17bc37022d08300" - integrity sha512-oM3K004DbInyb3uq9ciCgRAO91eq/q5SFcjD7dtItwUYboD1jzTnmV6Yp+QdxX2kJLICHzsfyAgyZKTUvEZtlw== +"@ckeditor/ckeditor5-ui@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-48.0.1.tgz#4a444e2601204757f6bce6f31fd086c04dac3c7a" + integrity sha512-pRZBfqPBPXo9BaKgY+YeYg9atr7V/5MhUKDjI9WBAkg5JVKqR6eih2F9NjhrCbMEP0CeJKxdjgfl6SipnZkVkg== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - es-toolkit "1.39.5" - -"@ckeditor/ckeditor5-ui@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-ui/-/ckeditor5-ui-47.7.0.tgz#78dac851009779d6189633a2deba9768cfa28613" - integrity sha512-eiNbp7JhBR/kAZ2DvT06u8KJpDhESGjIrLESGIn8/OzBYCpX+wqpx0Gj6WuKgK134bUI61qsYsLNqR15WcTaWA== - dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-editor-multi-root" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-editor-multi-root" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" "@types/color-convert" "2.0.4" color-convert "3.1.0" color-parse "2.0.2" - es-toolkit "1.39.5" + es-toolkit "1.45.1" vanilla-colorful "0.7.2" -"@ckeditor/ckeditor5-undo@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-47.7.0.tgz#c460097dd2a21f5903dca043451b6d4c2a5b7759" - integrity sha512-DGGQZX+Bf8HnOlgPWtz2kVoVAuTLtFYYkJa9ihUmrdOHlbGB/mQu5DAtZSUBp/6pYabBu1vAlkiQTIUT78wOsw== +"@ckeditor/ckeditor5-undo@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-undo/-/ckeditor5-undo-48.0.1.tgz#195131b02e05ba772747890210e271e37e9421fe" + integrity sha512-OMezYgjdQ2ZFYM/+Z52CEGCIHIofX/MvSy/jVGXaY5ROS54prjfxkEq20yr1DepRCck319cOOCpRa9SbA/+byA== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-upload@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-47.7.0.tgz#d5134d3c12a7d2c097711768a733fc4e026da255" - integrity sha512-OJrDuje7ZpKDed3RPAXnuGPsNV3xuBKwLC1AwKghG7c121GPSU+uILgHL0puefrVnbZbJ+JRrMjyf1LJKFfZww== +"@ckeditor/ckeditor5-upload@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-upload/-/ckeditor5-upload-48.0.1.tgz#df25e89bf643d32bcabf3426ae256204c7fa86e7" + integrity sha512-ssABMlpkCCXqJOZwPerqSDND5TTMGuc6h9hZ28QdMTf/wAa5DL+XdZeMSTbEU5L4PjcBtbh9ri6iLJ33c9Hxrw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" -"@ckeditor/ckeditor5-utils@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-47.7.0.tgz#d676f2335121e5fadb0007edc053d66f77ea6e58" - integrity sha512-HBVctgNr/0AP9QV8tZ5zg+lY15bAcS3s8tS3yVngaN0Zrmn77XIGXixqYrOX6J64gBlJ541WDb20Uo0Z2PF4+Q== +"@ckeditor/ckeditor5-utils@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-utils/-/ckeditor5-utils-48.0.1.tgz#e865147420b70a8ea13d1213e09f88c3c0b0a86a" + integrity sha512-Oe0yUdgwJG7vSQZ0lLF04mG8EAgkE21norfVc3hyp8zJV24MB13/6lyZe3dhmWO20tEFrppXIDiEaN94nblpew== dependencies: - "@ckeditor/ckeditor5-ui" "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-ui" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-watchdog@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-47.7.0.tgz#a9179a52a85a51ff1c3df759e615a96eefa5d4d2" - integrity sha512-EYLj784TzBJZ5AAZzuAHGCoI12n54XPspnDxy4Un3k0fxjS0scxgB4Q5h4r3NMgeC8PfkYVeAw/I8rBZ7Dd33Q== +"@ckeditor/ckeditor5-watchdog@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-watchdog/-/ckeditor5-watchdog-48.0.1.tgz#9f686e6845422f2f65243ce2790691ca433bfa6c" + integrity sha512-Rpn8kXTHidmozRiB7lcX5lsYl2IIQfiWNQ+rskYBNZsctOJlViPXDyyXk5yG8aSBjk1bKIbCa8wlCBrqkWqL1g== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-editor-multi-root" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-widget@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-47.7.0.tgz#bbeea896d8fc629a9414638fb92359c87d536792" - integrity sha512-HoFEdRIb8DEo0QcIUqjw0HKSCROqWdPYYM4cH0YwTMektjA4KScUTN/8SEi4IMU913bTVuKpMeFBEYot4DSziQ== +"@ckeditor/ckeditor5-widget@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-widget/-/ckeditor5-widget-48.0.1.tgz#882cb27b54b7256ed5b54086f6caf055457de83d" + integrity sha512-bMyJW4uNIqPg4OoSCBs6AVTct8GTak8LiDZeKoA8u+yUMDb4SbLP4+5RmrGQusSseSZ6Kcf3ZMpnnhXTwtTp6w== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-enter" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" -"@ckeditor/ckeditor5-word-count@47.7.0": - version "47.7.0" - resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-word-count/-/ckeditor5-word-count-47.7.0.tgz#f745581a3b0c61f583973fe0b403d79be2a7b02c" - integrity sha512-moeWGmQ6TOR8g9nPndHvanjyTWmT0bTKRzXdTruzI5CPJgxOvFRCDZVN+gzXeFq+5juzwA9nw+OW1PF6D9N6lw== +"@ckeditor/ckeditor5-word-count@48.0.1": + version "48.0.1" + resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-word-count/-/ckeditor5-word-count-48.0.1.tgz#0ddb6cb38ed28612d16a027fb6abb23ad89ffba0" + integrity sha512-U7mSd7AGQzWYS0W2BiicIC0RvawcCj8kARKtPjcqV50d80hgR4BPjOtNAM9u2hDfHwT8yat7KG3NJ4cyOiXUQw== dependencies: - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - ckeditor5 "47.7.0" - es-toolkit "1.39.5" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + es-toolkit "1.45.1" "@colordx/core@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@colordx/core/-/core-5.2.0.tgz#fcf1f637b3f93f12aae57bd3929f3f90a7773627" integrity sha512-wifnqsGCXRh+lJdX4975nKEPJaSk7k8rMiA/VeGrS4tOTn06WZrow6cUA7wFJKPXfcqj0rXeH4BMgGoKZvBf7g== -"@csstools/selector-resolve-nested@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz#848c6f44cb65e3733e478319b9342b7aa436fac7" - integrity sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g== - -"@csstools/selector-specificity@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz#037817b574262134cabd68fc4ec1a454f168407b" - integrity sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw== - "@discoveryjs/json-ext@^0.6.1", "@discoveryjs/json-ext@^0.6.3": version "0.6.3" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz#f13c7c205915eb91ae54c557f5e92bddd8be0e83" integrity sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ== -"@esbuild/aix-ppc64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz#82b74f92aa78d720b714162939fb248c90addf53" - integrity sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg== - -"@esbuild/android-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz#f78cb8a3121fc205a53285adb24972db385d185d" - integrity sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ== - -"@esbuild/android-arm@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.7.tgz#593e10a1450bbfcac6cb321f61f468453bac209d" - integrity sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ== - -"@esbuild/android-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.7.tgz#453143d073326033d2d22caf9e48de4bae274b07" - integrity sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg== - -"@esbuild/darwin-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz#6f23000fb9b40b7e04b7d0606c0693bd0632f322" - integrity sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw== - -"@esbuild/darwin-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz#27393dd18bb1263c663979c5f1576e00c2d024be" - integrity sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ== - -"@esbuild/freebsd-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz#22e4638fa502d1c0027077324c97640e3adf3a62" - integrity sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w== - -"@esbuild/freebsd-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz#9224b8e4fea924ce2194e3efc3e9aebf822192d6" - integrity sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ== - -"@esbuild/linux-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz#4f5d1c27527d817b35684ae21419e57c2bda0966" - integrity sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A== - -"@esbuild/linux-arm@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz#b9e9d070c8c1c0449cf12b20eac37d70a4595921" - integrity sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA== - -"@esbuild/linux-ia32@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz#3f80fb696aa96051a94047f35c85b08b21c36f9e" - integrity sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg== - -"@esbuild/linux-loong64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz#9be1f2c28210b13ebb4156221bba356fe1675205" - integrity sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q== - -"@esbuild/linux-mips64el@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz#4ab5ee67a3dfcbcb5e8fd7883dae6e735b1163b8" - integrity sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw== - -"@esbuild/linux-ppc64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz#dac78c689f6499459c4321e5c15032c12307e7ea" - integrity sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ== - -"@esbuild/linux-riscv64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz#050f7d3b355c3a98308e935bc4d6325da91b0027" - integrity sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ== - -"@esbuild/linux-s390x@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz#d61f715ce61d43fe5844ad0d8f463f88cbe4fef6" - integrity sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw== - -"@esbuild/linux-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz#ca8e1aa478fc8209257bf3ac8f79c4dc2982f32a" - integrity sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA== - -"@esbuild/netbsd-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz#1650f2c1b948deeb3ef948f2fc30614723c09690" - integrity sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w== - -"@esbuild/netbsd-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz#65772ab342c4b3319bf0705a211050aac1b6e320" - integrity sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw== - -"@esbuild/openbsd-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz#37ed7cfa66549d7955852fce37d0c3de4e715ea1" - integrity sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A== - -"@esbuild/openbsd-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz#01bf3d385855ef50cb33db7c4b52f957c34cd179" - integrity sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg== - -"@esbuild/openharmony-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz#6c1f94b34086599aabda4eac8f638294b9877410" - integrity sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw== - -"@esbuild/sunos-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz#4b0dd17ae0a6941d2d0fd35a906392517071a90d" - integrity sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA== - -"@esbuild/win32-arm64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz#34193ab5565d6ff68ca928ac04be75102ccb2e77" - integrity sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA== - -"@esbuild/win32-ia32@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz#eb67f0e4482515d8c1894ede631c327a4da9fc4d" - integrity sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw== - -"@esbuild/win32-x64@0.27.7": - version "0.27.7" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz#8fe30b3088b89b4873c3a6cc87597ae3920c0a8b" - integrity sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg== - "@formatjs/ecma402-abstract@2.3.6": version "2.3.6" resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz#d6ca9d3579054fe1e1a0a0b5e872e0d64922e4e1" @@ -1835,11 +1615,6 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-7.2.0.tgz#188c1053ce422ad1f934d7df242a973fcb89636d" integrity sha512-3DguDv/oUE+7vjMeTSOjCSG+KeawgVQOHrKRnvUuqYh1mfArrh7s+s8hXW3e4RerBA1+Wh+hBqf8sJNpqNrBWg== -"@gar/promise-retry@^1.0.0", "@gar/promise-retry@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@gar/promise-retry/-/promise-retry-1.0.3.tgz#65e726428e794bc4453948e0a41e6de4215ce8b0" - integrity sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA== - "@hotwired/stimulus-webpack-helpers@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@hotwired/stimulus-webpack-helpers/-/stimulus-webpack-helpers-1.0.1.tgz#4cd74487adeca576c9865ac2b9fe5cb20cef16dd" @@ -1855,30 +1630,6 @@ resolved "https://registry.yarnpkg.com/@hotwired/turbo/-/turbo-8.0.23.tgz#a6eebc9ab4a5faadae265a4cbec8cfcb5731e77c" integrity sha512-GZ7cijxEZ6Ig71u7rD6LHaRv/wcE/hNsc+nEfiWOkLNqUgLOwo5MNGWOy5ZV9ZUDSiQx1no7YxjTNnT4O6//cQ== -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@isaacs/cliui@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-9.0.0.tgz#4d0a3f127058043bf2e7ee169eaf30ed901302f3" - integrity sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg== - -"@isaacs/fs-minipass@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz#2d59ae3ab4b38fb4270bfa23d30f8e2e86c7fe32" - integrity sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w== - dependencies: - minipass "^7.0.4" - "@jbtronics/bs-treeview@^1.0.1": version "1.0.7" resolved "https://registry.yarnpkg.com/@jbtronics/bs-treeview/-/bs-treeview-1.0.7.tgz#42a5ea40ce1bfe6cffbc1b811dc4e32dd8d0273a" @@ -1964,18 +1715,6 @@ picocolors "^1.1.1" string-width "^4.2.3" -"@kwsites/file-exists@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99" - integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw== - dependencies: - debug "^4.1.1" - -"@kwsites/promise-deferred@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" - integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== - "@noble/ciphers@^1.0.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-1.3.0.tgz#f64b8ff886c240e644e5573c097f86e5b43676dc" @@ -1986,108 +1725,6 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@npmcli/agent@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-4.0.0.tgz#2bb2b1c0a170940511554a7986ae2a8be9fedcce" - integrity sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA== - dependencies: - agent-base "^7.1.0" - http-proxy-agent "^7.0.0" - https-proxy-agent "^7.0.1" - lru-cache "^11.2.1" - socks-proxy-agent "^8.0.3" - -"@npmcli/fs@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-5.0.0.tgz#674619771907342b3d1ac197aaf1deeb657e3539" - integrity sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og== - dependencies: - semver "^7.3.5" - -"@npmcli/git@^7.0.0": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-7.0.2.tgz#680c3271fe51401c07ee41076be678851e600ff0" - integrity sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg== - dependencies: - "@gar/promise-retry" "^1.0.0" - "@npmcli/promise-spawn" "^9.0.0" - ini "^6.0.0" - lru-cache "^11.2.1" - npm-pick-manifest "^11.0.1" - proc-log "^6.0.0" - semver "^7.3.5" - which "^6.0.0" - -"@npmcli/installed-package-contents@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz#18e5070704cfe0278f9ae48038558b6efd438426" - integrity sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA== - dependencies: - npm-bundled "^5.0.0" - npm-normalize-package-bin "^5.0.0" - -"@npmcli/node-gyp@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz#35475a58b5d791764a7252231197a14deefe8e47" - integrity sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ== - -"@npmcli/package-json@^7.0.0": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-7.0.5.tgz#e29481dfc586d1625a6553799e6bec52ae0487a5" - integrity sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ== - dependencies: - "@npmcli/git" "^7.0.0" - glob "^13.0.0" - hosted-git-info "^9.0.0" - json-parse-even-better-errors "^5.0.0" - proc-log "^6.0.0" - semver "^7.5.3" - spdx-expression-parse "^4.0.0" - -"@npmcli/promise-spawn@^9.0.0": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz#20e80cbdd2f24ad263a15de3ebbb1673cb82005b" - integrity sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q== - dependencies: - which "^6.0.0" - -"@npmcli/redact@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/redact/-/redact-4.0.0.tgz#c91121e02b7559a997614a2c1057cd7fc67608c4" - integrity sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q== - -"@npmcli/run-script@^10.0.0": - version "10.0.4" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-10.0.4.tgz#99cddae483ce3dbf1a10f5683a4e6aaa02345ac0" - integrity sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg== - dependencies: - "@npmcli/node-gyp" "^5.0.0" - "@npmcli/package-json" "^7.0.0" - "@npmcli/promise-spawn" "^9.0.0" - node-gyp "^12.1.0" - proc-log "^6.0.0" - "@orchidjs/sifter@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@orchidjs/sifter/-/sifter-1.1.0.tgz#b36154ad0cda4898305d1ac44f318b41048a0438" @@ -2107,11 +1744,6 @@ dependencies: barcode-detector "^3.0.0" -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - "@polka/url@^1.0.0-next.24": version "1.0.0-next.29" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1" @@ -2122,64 +1754,6 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@sigstore/bundle@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-4.0.0.tgz#854eda43eb6a59352037e49000177c8904572f83" - integrity sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A== - dependencies: - "@sigstore/protobuf-specs" "^0.5.0" - -"@sigstore/core@^3.1.0", "@sigstore/core@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-3.2.0.tgz#beaea6ea4d7d4caadadb7453168e35636b78830e" - integrity sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA== - -"@sigstore/protobuf-specs@^0.5.0": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.5.1.tgz#5401e444b6ab0db7d1969c91c43e7954927a52fe" - integrity sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g== - -"@sigstore/sign@^4.1.0": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-4.1.1.tgz#34765fe4a190d693340c0771a3d150a397bcfc55" - integrity sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ== - dependencies: - "@gar/promise-retry" "^1.0.2" - "@sigstore/bundle" "^4.0.0" - "@sigstore/core" "^3.2.0" - "@sigstore/protobuf-specs" "^0.5.0" - make-fetch-happen "^15.0.4" - proc-log "^6.1.0" - -"@sigstore/tuf@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-4.0.2.tgz#7d2fa2abcd5afa5baf752671d14a1c6ed0ed3196" - integrity sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ== - dependencies: - "@sigstore/protobuf-specs" "^0.5.0" - tuf-js "^4.1.0" - -"@sigstore/verify@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/verify/-/verify-3.1.0.tgz#4046d4186421db779501fe87fa5acaa5d4d21b08" - integrity sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag== - dependencies: - "@sigstore/bundle" "^4.0.0" - "@sigstore/core" "^3.1.0" - "@sigstore/protobuf-specs" "^0.5.0" - -"@simple-git/args-pathspec@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@simple-git/args-pathspec/-/args-pathspec-1.0.3.tgz#9ef4a2ad5f49ab4056362d03f93f775b93118ca5" - integrity sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA== - -"@simple-git/argv-parser@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@simple-git/argv-parser/-/argv-parser-1.1.1.tgz#275b839c6eeb5030872c73b1ea839a416885da9d" - integrity sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw== - dependencies: - "@simple-git/args-pathspec" "^1.0.3" - "@sinclair/typebox@^0.34.0": version "0.34.49" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.49.tgz#4f1369234f2ecf693866476c3b2e1b54d2a9d68e" @@ -2230,19 +1804,6 @@ webpack-manifest-plugin "^5.0.1" yargs-parser "^21.0.0" -"@tufjs/canonical-json@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz#a52f61a3d7374833fca945b2549bc30a2dd40d0a" - integrity sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA== - -"@tufjs/models@4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-4.1.0.tgz#494b39cf5e2f6855d80031246dd236d8086069b3" - integrity sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww== - dependencies: - "@tufjs/canonical-json" "2.0.0" - minimatch "^10.1.1" - "@types/color-convert@2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.4.tgz#843398ae71e951dc5415d202dfd5e43108823eeb" @@ -2314,7 +1875,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -2338,20 +1899,6 @@ dependencies: undici-types "~7.19.0" -"@types/postcss-import@^14.0.3": - version "14.0.3" - resolved "https://registry.yarnpkg.com/@types/postcss-import/-/postcss-import-14.0.3.tgz#149236eeb5c87d5b576df5f335faa1fe49f33e5a" - integrity sha512-raZhRVTf6Vw5+QbmQ7LOHSDML71A5rj4+EqDzAbrZPfxfoGzFxMHRCq16VlddGIZpHELw0BG4G0YE2ANkdZiIQ== - dependencies: - postcss "^8.0.0" - -"@types/through2@^2.0.41": - version "2.0.41" - resolved "https://registry.yarnpkg.com/@types/through2/-/through2-2.0.41.tgz#3e5e1720d71ffdfa03c22f2aad6593d12a47034f" - integrity sha512-ryQ0tidWkb1O1JuYvWKyMLYEtOWDqF5mHerJzKz/gQpoAaJq2l/dsMPBF0B5BNVT34rbARYJ5/tsZwLfUi2kwQ== - dependencies: - "@types/node" "*" - "@types/trusted-types@^2.0.7": version "2.0.7" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" @@ -2562,11 +2109,6 @@ resolved "https://registry.yarnpkg.com/@zxcvbn-ts/language-ja/-/language-ja-3.0.2.tgz#299bb6f5465f99405577491b1b31352058540c76" integrity sha512-YjQyt+eMe3EdpeJiSt81AMF8HfEXXCary/VRoG+0erZBzRjfJ1U3JdSiu9wFFxiEF8Cb5FEmTQ6nQPyraezH6Q== -abbrev@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-4.0.0.tgz#ec933f0e27b6cd60e89b5c6b2a304af42209bb05" - integrity sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA== - acorn-import-phases@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" @@ -2592,11 +2134,6 @@ adjust-sourcemap-loader@^4.0.0: loader-utils "^2.0.0" regex-parser "^2.2.11" -agent-base@^7.1.0, agent-base@^7.1.2: - version "7.1.4" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" - integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -2604,11 +2141,6 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" @@ -2616,16 +2148,6 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5: - version "6.14.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.14.0.tgz#fd067713e228210636ebb08c60bd3765d6dbe73a" - integrity sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - ajv@^8.0.0, ajv@^8.9.0: version "8.18.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.18.0.tgz#8864186b6738d003eb3a933172bb3833e10cefbc" @@ -2641,28 +2163,13 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" - integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -ansi-styles@^6.1.0: - version "6.2.3" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" - integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - attr-accept@^2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e" @@ -2704,16 +2211,6 @@ bail@^2.0.0: resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -balanced-match@^4.0.2: - version "4.0.4" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" - integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== - barcode-detector@^3.0.0, barcode-detector@^3.0.5: version "3.1.2" resolved "https://registry.yarnpkg.com/barcode-detector/-/barcode-detector-3.1.2.tgz#8032a211ebb6cb5cc25724c5c56322c77ed02503" @@ -2766,20 +2263,6 @@ bootswatch@^5.1.3: resolved "https://registry.yarnpkg.com/bootswatch/-/bootswatch-5.3.8.tgz#534538ce50285e52cb715823f8b4d734f73956e7" integrity sha512-88mnH9tv+x6DV+scBxYFOpM4YSDVhyfEgbhqaEfvkHNctKI9qRcACxIP9nmBZ5mSeLXtsgax1VsRkUs1eWjlAQ== -brace-expansion@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.0.tgz#4f41a41190216ee36067ec381526fe9539c4f0ae" - integrity sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w== - dependencies: - balanced-match "^1.0.0" - -brace-expansion@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.5.tgz#dcc3a37116b79f3e1b46db994ced5d570e930fdb" - integrity sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ== - dependencies: - balanced-match "^4.0.2" - braces@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" @@ -2794,11 +2277,6 @@ brotli@^1.3.2: dependencies: base64-js "^1.1.2" -browser-stdout@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - browserify-zlib@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" @@ -2827,37 +2305,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -cacache@^20.0.0, cacache@^20.0.1: - version "20.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-20.0.4.tgz#9b547dc3db0c1f87cba6dbbff91fb17181b4bbb1" - integrity sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA== - dependencies: - "@npmcli/fs" "^5.0.0" - fs-minipass "^3.0.0" - glob "^13.0.0" - lru-cache "^11.1.0" - minipass "^7.0.3" - minipass-collect "^2.0.1" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^7.0.2" - ssri "^13.0.0" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase-css@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -2886,11 +2333,6 @@ chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.0.0: - version "5.6.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" - integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== - character-entities-html4@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" @@ -2906,18 +2348,6 @@ character-entities@^2.0.0: resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== -chokidar@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" - integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== - dependencies: - readdirp "^4.0.1" - -chownr@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-3.0.0.tgz#9855e64ecd240a9cc4267ce8a4aa5d24a1da15e4" - integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g== - chrome-trace-event@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" @@ -2928,84 +2358,71 @@ ci-info@^4.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.4.0.tgz#7d54eff9f54b45b62401c26032696eb59c8bd18c" integrity sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg== -ckeditor5@47.7.0, ckeditor5@^47.0.0: - version "47.7.0" - resolved "https://registry.yarnpkg.com/ckeditor5/-/ckeditor5-47.7.0.tgz#3dfc1c41e0c53130e0ddbab125b377b32f088e7a" - integrity sha512-j81Od9mv5+SkQdOV7OrwrxCqkv9p19V+x+H6ndpgTzchIn3o/pQYBG3pWloG5nb0oC9aebayxanUp/O/EIqHCQ== +ckeditor5@^48.0.0: + version "48.0.1" + resolved "https://registry.yarnpkg.com/ckeditor5/-/ckeditor5-48.0.1.tgz#ee40cb3953da435cf0532680dc347389fcb1f4e2" + integrity sha512-8db92XXDEwU7KkwGBjMrWlfKifI+ISw9DHvZVMK7khY69CyAJizl9TjDQiDT0l+05KkgETzDvZ0j4RYvKq0wUg== dependencies: - "@ckeditor/ckeditor5-adapter-ckfinder" "47.7.0" - "@ckeditor/ckeditor5-alignment" "47.7.0" - "@ckeditor/ckeditor5-autoformat" "47.7.0" - "@ckeditor/ckeditor5-autosave" "47.7.0" - "@ckeditor/ckeditor5-basic-styles" "47.7.0" - "@ckeditor/ckeditor5-block-quote" "47.7.0" - "@ckeditor/ckeditor5-bookmark" "47.7.0" - "@ckeditor/ckeditor5-ckbox" "47.7.0" - "@ckeditor/ckeditor5-ckfinder" "47.7.0" - "@ckeditor/ckeditor5-clipboard" "47.7.0" - "@ckeditor/ckeditor5-cloud-services" "47.7.0" - "@ckeditor/ckeditor5-code-block" "47.7.0" - "@ckeditor/ckeditor5-core" "47.7.0" - "@ckeditor/ckeditor5-easy-image" "47.7.0" - "@ckeditor/ckeditor5-editor-balloon" "47.7.0" - "@ckeditor/ckeditor5-editor-classic" "47.7.0" - "@ckeditor/ckeditor5-editor-decoupled" "47.7.0" - "@ckeditor/ckeditor5-editor-inline" "47.7.0" - "@ckeditor/ckeditor5-editor-multi-root" "47.7.0" - "@ckeditor/ckeditor5-emoji" "47.7.0" - "@ckeditor/ckeditor5-engine" "47.7.0" - "@ckeditor/ckeditor5-enter" "47.7.0" - "@ckeditor/ckeditor5-essentials" "47.7.0" - "@ckeditor/ckeditor5-find-and-replace" "47.7.0" - "@ckeditor/ckeditor5-font" "47.7.0" - "@ckeditor/ckeditor5-fullscreen" "47.7.0" - "@ckeditor/ckeditor5-heading" "47.7.0" - "@ckeditor/ckeditor5-highlight" "47.7.0" - "@ckeditor/ckeditor5-horizontal-line" "47.7.0" - "@ckeditor/ckeditor5-html-embed" "47.7.0" - "@ckeditor/ckeditor5-html-support" "47.7.0" - "@ckeditor/ckeditor5-icons" "47.7.0" - "@ckeditor/ckeditor5-image" "47.7.0" - "@ckeditor/ckeditor5-indent" "47.7.0" - "@ckeditor/ckeditor5-language" "47.7.0" - "@ckeditor/ckeditor5-link" "47.7.0" - "@ckeditor/ckeditor5-list" "47.7.0" - "@ckeditor/ckeditor5-markdown-gfm" "47.7.0" - "@ckeditor/ckeditor5-media-embed" "47.7.0" - "@ckeditor/ckeditor5-mention" "47.7.0" - "@ckeditor/ckeditor5-minimap" "47.7.0" - "@ckeditor/ckeditor5-page-break" "47.7.0" - "@ckeditor/ckeditor5-paragraph" "47.7.0" - "@ckeditor/ckeditor5-paste-from-office" "47.7.0" - "@ckeditor/ckeditor5-remove-format" "47.7.0" - "@ckeditor/ckeditor5-restricted-editing" "47.7.0" - "@ckeditor/ckeditor5-select-all" "47.7.0" - "@ckeditor/ckeditor5-show-blocks" "47.7.0" - "@ckeditor/ckeditor5-source-editing" "47.7.0" - "@ckeditor/ckeditor5-special-characters" "47.7.0" - "@ckeditor/ckeditor5-style" "47.7.0" - "@ckeditor/ckeditor5-table" "47.7.0" - "@ckeditor/ckeditor5-theme-lark" "47.7.0" - "@ckeditor/ckeditor5-typing" "47.7.0" - "@ckeditor/ckeditor5-ui" "47.7.0" - "@ckeditor/ckeditor5-undo" "47.7.0" - "@ckeditor/ckeditor5-upload" "47.7.0" - "@ckeditor/ckeditor5-utils" "47.7.0" - "@ckeditor/ckeditor5-watchdog" "47.7.0" - "@ckeditor/ckeditor5-widget" "47.7.0" - "@ckeditor/ckeditor5-word-count" "47.7.0" - -cli-cursor@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" - integrity sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw== - dependencies: - restore-cursor "^5.0.0" - -cli-spinners@^3.0.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-3.4.0.tgz#1f11f6d48c4e5bc6849fcb4efa0dc98f9e7299ea" - integrity sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw== + "@ckeditor/ckeditor5-adapter-ckfinder" "48.0.1" + "@ckeditor/ckeditor5-alignment" "48.0.1" + "@ckeditor/ckeditor5-autoformat" "48.0.1" + "@ckeditor/ckeditor5-autosave" "48.0.1" + "@ckeditor/ckeditor5-basic-styles" "48.0.1" + "@ckeditor/ckeditor5-block-quote" "48.0.1" + "@ckeditor/ckeditor5-bookmark" "48.0.1" + "@ckeditor/ckeditor5-ckbox" "48.0.1" + "@ckeditor/ckeditor5-ckfinder" "48.0.1" + "@ckeditor/ckeditor5-clipboard" "48.0.1" + "@ckeditor/ckeditor5-cloud-services" "48.0.1" + "@ckeditor/ckeditor5-code-block" "48.0.1" + "@ckeditor/ckeditor5-core" "48.0.1" + "@ckeditor/ckeditor5-easy-image" "48.0.1" + "@ckeditor/ckeditor5-editor-balloon" "48.0.1" + "@ckeditor/ckeditor5-editor-classic" "48.0.1" + "@ckeditor/ckeditor5-editor-decoupled" "48.0.1" + "@ckeditor/ckeditor5-editor-inline" "48.0.1" + "@ckeditor/ckeditor5-editor-multi-root" "48.0.1" + "@ckeditor/ckeditor5-emoji" "48.0.1" + "@ckeditor/ckeditor5-engine" "48.0.1" + "@ckeditor/ckeditor5-enter" "48.0.1" + "@ckeditor/ckeditor5-essentials" "48.0.1" + "@ckeditor/ckeditor5-find-and-replace" "48.0.1" + "@ckeditor/ckeditor5-font" "48.0.1" + "@ckeditor/ckeditor5-fullscreen" "48.0.1" + "@ckeditor/ckeditor5-heading" "48.0.1" + "@ckeditor/ckeditor5-highlight" "48.0.1" + "@ckeditor/ckeditor5-horizontal-line" "48.0.1" + "@ckeditor/ckeditor5-html-embed" "48.0.1" + "@ckeditor/ckeditor5-html-support" "48.0.1" + "@ckeditor/ckeditor5-icons" "48.0.1" + "@ckeditor/ckeditor5-image" "48.0.1" + "@ckeditor/ckeditor5-indent" "48.0.1" + "@ckeditor/ckeditor5-language" "48.0.1" + "@ckeditor/ckeditor5-link" "48.0.1" + "@ckeditor/ckeditor5-list" "48.0.1" + "@ckeditor/ckeditor5-markdown-gfm" "48.0.1" + "@ckeditor/ckeditor5-media-embed" "48.0.1" + "@ckeditor/ckeditor5-mention" "48.0.1" + "@ckeditor/ckeditor5-minimap" "48.0.1" + "@ckeditor/ckeditor5-page-break" "48.0.1" + "@ckeditor/ckeditor5-paragraph" "48.0.1" + "@ckeditor/ckeditor5-paste-from-office" "48.0.1" + "@ckeditor/ckeditor5-remove-format" "48.0.1" + "@ckeditor/ckeditor5-restricted-editing" "48.0.1" + "@ckeditor/ckeditor5-select-all" "48.0.1" + "@ckeditor/ckeditor5-show-blocks" "48.0.1" + "@ckeditor/ckeditor5-source-editing" "48.0.1" + "@ckeditor/ckeditor5-special-characters" "48.0.1" + "@ckeditor/ckeditor5-style" "48.0.1" + "@ckeditor/ckeditor5-table" "48.0.1" + "@ckeditor/ckeditor5-typing" "48.0.1" + "@ckeditor/ckeditor5-ui" "48.0.1" + "@ckeditor/ckeditor5-undo" "48.0.1" + "@ckeditor/ckeditor5-upload" "48.0.1" + "@ckeditor/ckeditor5-utils" "48.0.1" + "@ckeditor/ckeditor5-watchdog" "48.0.1" + "@ckeditor/ckeditor5-widget" "48.0.1" + "@ckeditor/ckeditor5-word-count" "48.0.1" clipboard@^2.0.4: version "2.0.11" @@ -3016,15 +2433,6 @@ clipboard@^2.0.4: select "^1.1.2" tiny-emitter "^2.0.0" -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" @@ -3145,17 +2553,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.1.tgz#df110631a8547b5d1a98915271986f06e3011379" - integrity sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ== - dependencies: - env-paths "^2.2.1" - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - -cross-spawn@^7.0.3, cross-spawn@^7.0.6: +cross-spawn@^7.0.3: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -3169,7 +2567,7 @@ css-declaration-sorter@^7.2.0: resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-7.4.0.tgz#9c215fbda2dcf4083bae69f125688158ae847deb" integrity sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw== -css-loader@^7.0.0, css-loader@^7.1.0: +css-loader@^7.1.0: version "7.1.4" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.4.tgz#8f6bf9f8fc8cbef7d2ef6e80acc6545eaefa90b1" integrity sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw== @@ -3284,7 +2682,7 @@ cssnano-utils@^5.0.2: resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-5.0.2.tgz#92939eda38fb934151a8c87bd60764d1a27c5597" integrity sha512-kt41WLK7FLKfePzPi645Y+/NtW/nNM7Su6nlNUfJyRNW3JcuU3JU7+cWJc+JexTeZ8dRBvFufefdG2XpXkIo0A== -cssnano@^7.0.0, cssnano@^7.0.4: +cssnano@^7.0.4: version "7.1.7" resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-7.1.7.tgz#152658ec9d24f080851c3010e61673d539765af7" integrity sha512-N5LGn/OlhMxDTvKACwUPMzT34SSj1b022pvUAE/Vh6r2WD1aUCbc+QNIP/JjX9VVxebdJWZQ3352Lt4oF7dQ/g== @@ -3399,18 +2797,13 @@ datatables.net@2.3.7, datatables.net@^2, datatables.net@^2.0.0: dependencies: jquery ">=1.7" -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4, debug@^4.3.5, debug@^4.4.0, debug@^4.4.3: +debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: ms "^2.1.3" -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - decimal.js@^10.4.3: version "10.6.0" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.6.0.tgz#e649a43e3ab953a72192ff5983865e509f37ed9a" @@ -3445,11 +2838,6 @@ dfa@^1.2.0: resolved "https://registry.yarnpkg.com/dfa/-/dfa-1.2.0.tgz#96ac3204e2d29c49ea5b57af8d92c2ae12790657" integrity sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q== -diff@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a" - integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== - dom-converter@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" @@ -3519,11 +2907,6 @@ domutils@^3.0.1: domelementtype "^2.3.0" domhandler "^5.0.3" -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - electron-to-chromium@^1.5.328: version "1.5.341" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.341.tgz#427b826ac41d406162b7700e6032c2b9cc4ecc5c" @@ -3534,11 +2917,6 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -3562,23 +2940,11 @@ entities@^4.2.0: resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -env-paths@^2.2.0, env-paths@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - envinfo@^7.14.0: version "7.21.0" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.21.0.tgz#04a251be79f92548541f37d13c8b6f22940c3bae" integrity sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow== -error-ex@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414" - integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ== - dependencies: - is-arrayish "^0.2.1" - error-stack-parser@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" @@ -3596,63 +2962,16 @@ es-module-lexer@^2.0.0: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== -es-toolkit@1.39.5: - version "1.39.5" - resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.39.5.tgz#ee2a78a66aafb76c7345af0ea8c06722c78ef1fd" - integrity sha512-z9V0qU4lx1TBXDNFWfAASWk6RNU6c6+TJBKE+FLIg8u0XJ6Yw58Hi0yX8ftEouj6p1QARRlXLFfHbIli93BdQQ== +es-toolkit@1.45.1: + version "1.45.1" + resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.45.1.tgz#21b28b2bd43178fd4c9c937c445d5bcaccce907b" + integrity sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw== -esbuild-loader@^4.0.0: - version "4.4.3" - resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-4.4.3.tgz#0d0f302e3260b2318d1256c17807dfea4bc449ed" - integrity sha512-Wpui03EzqC151xFteKlgJQhbyZl5CgnBpUHXVuao02nItULlkaTeiLdEMPTmR2zdwpEBWkXVNoT5dDOYJluUzg== - dependencies: - esbuild "^0.27.1" - get-tsconfig "^4.10.1" - loader-utils "^2.0.4" - webpack-sources "^3.3.4" - -esbuild@^0.27.1: - version "0.27.7" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.27.7.tgz#bcadce22b2f3fd76f257e3a64f83a64986fea11f" - integrity sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w== - optionalDependencies: - "@esbuild/aix-ppc64" "0.27.7" - "@esbuild/android-arm" "0.27.7" - "@esbuild/android-arm64" "0.27.7" - "@esbuild/android-x64" "0.27.7" - "@esbuild/darwin-arm64" "0.27.7" - "@esbuild/darwin-x64" "0.27.7" - "@esbuild/freebsd-arm64" "0.27.7" - "@esbuild/freebsd-x64" "0.27.7" - "@esbuild/linux-arm" "0.27.7" - "@esbuild/linux-arm64" "0.27.7" - "@esbuild/linux-ia32" "0.27.7" - "@esbuild/linux-loong64" "0.27.7" - "@esbuild/linux-mips64el" "0.27.7" - "@esbuild/linux-ppc64" "0.27.7" - "@esbuild/linux-riscv64" "0.27.7" - "@esbuild/linux-s390x" "0.27.7" - "@esbuild/linux-x64" "0.27.7" - "@esbuild/netbsd-arm64" "0.27.7" - "@esbuild/netbsd-x64" "0.27.7" - "@esbuild/openbsd-arm64" "0.27.7" - "@esbuild/openbsd-x64" "0.27.7" - "@esbuild/openharmony-arm64" "0.27.7" - "@esbuild/sunos-x64" "0.27.7" - "@esbuild/win32-arm64" "0.27.7" - "@esbuild/win32-ia32" "0.27.7" - "@esbuild/win32-x64" "0.27.7" - -escalade@^3.1.1, escalade@^3.2.0: +escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - escape-string-regexp@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" @@ -3693,26 +3012,6 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exponential-backoff@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6" - integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA== - exports-loader@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-5.0.0.tgz#0e5c50baf8526237c0a2743116a3e3fa788d194f" @@ -3725,27 +3024,11 @@ extend@^3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" - integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.8" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - fast-uri@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" @@ -3756,18 +3039,6 @@ fastest-levenshtein@1.0.16, fastest-levenshtein@^1.0.12, fastest-levenshtein@^1. resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== -fastq@^1.6.0: - version "1.20.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.1.tgz#ca750a10dc925bc8b18839fd203e3ef4b3ced675" - integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== - dependencies: - reusify "^1.0.4" - -fdir@^6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" - integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== - fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -3811,30 +3082,6 @@ fontkit@^2.0.4: unicode-properties "^1.4.0" unicode-trie "^2.0.0" -foreground-child@^3.1.0, foreground-child@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" - integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== - dependencies: - cross-spawn "^7.0.6" - signal-exit "^4.0.1" - -fs-extra@^11.0.0: - version "11.3.4" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.4.tgz#ab6934eca8bcf6f7f6b82742e33591f86301d6fc" - integrity sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" @@ -3850,73 +3097,16 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-tsconfig@^4.10.1: - version "4.14.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.14.0.tgz#985d85c52a9903864280ccc2448d413fbf1efed8" - integrity sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA== - dependencies: - resolve-pkg-maps "^1.0.0" - github-slugger@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-2.0.0.tgz#52cf2f9279a21eb6c59dd385b410f0c0adda8f1a" integrity sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw== -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^10.4.5: - version "10.5.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.5.0.tgz#8ec0355919cd3338c28428a23d4f24ecc5fe738c" - integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" - -glob@^11.0.2: - version "11.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-11.1.0.tgz#4f826576e4eb99c7dad383793d2f9f08f67e50a6" - integrity sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw== - dependencies: - foreground-child "^3.3.1" - jackspeak "^4.1.1" - minimatch "^10.1.1" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^2.0.0" - -glob@^13.0.0, glob@^13.0.3: - version "13.0.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-13.0.6.tgz#078666566a425147ccacfbd2e332deb66a2be71d" - integrity sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw== - dependencies: - minimatch "^10.2.2" - minipass "^7.1.3" - path-scurry "^2.0.2" - good-listener@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" @@ -3924,7 +3114,7 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6: +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -4087,18 +3277,6 @@ hastscript@9.0.1, hastscript@^9.0.0: property-information "^7.0.0" space-separated-tokens "^2.0.0" -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hosted-git-info@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-9.0.2.tgz#b38c8a802b274e275eeeccf9f4a1b1a0a8557ada" - integrity sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg== - dependencies: - lru-cache "^11.1.0" - htm@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/htm/-/htm-3.1.1.tgz#49266582be0dc66ed2235d5ea892307cc0c24b78" @@ -4124,64 +3302,16 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-cache-semantics@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" - integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== - -http-proxy-agent@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" - integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== - dependencies: - agent-base "^7.1.0" - debug "^4.3.4" - -https-proxy-agent@^7.0.1: - version "7.0.6" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" - integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== - dependencies: - agent-base "^7.1.2" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@^0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" - integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ignore-walk@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-8.0.0.tgz#380c173badc3a18c57ff33440753f0052f572b14" - integrity sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A== - dependencies: - minimatch "^10.0.3" - immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -import-fresh@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" - integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - import-local@^3.0.2: version "3.2.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" @@ -4190,16 +3320,11 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -inherits@^2.0.3, inherits@~2.0.3: +inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-6.0.0.tgz#efc7642b276f6a37d22fdf56ef50889d7146bf30" - integrity sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ== - interpret@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" @@ -4215,16 +3340,6 @@ intl-messageformat@^10.5.11: "@formatjs/icu-messageformat-parser" "2.11.4" tslib "^2.8.0" -ip-address@^10.0.1: - version "10.1.0" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4" - integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - is-core-module@^2.16.1: version "2.16.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" @@ -4237,43 +3352,16 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-interactive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" - integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - is-plain-obj@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" @@ -4286,16 +3374,6 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -4313,32 +3391,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isexe@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-4.0.0.tgz#48f6576af8e87a18feb796b7ed5e2e5903b43dca" - integrity sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw== - isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -jackspeak@^3.1.2: - version "3.4.3" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" - integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jackspeak@^4.1.1: - version "4.2.3" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.2.3.tgz#27ef80f33b93412037c3bea4f8eddf80e1931483" - integrity sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg== - dependencies: - "@isaacs/cliui" "^9.0.0" - jest-regex-util@30.0.1: version "30.0.1" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-30.0.1.tgz#f17c1de3958b67dfe485354f5a10093298f2a49b" @@ -4376,11 +3433,6 @@ jest-worker@^30.0.5: merge-stream "^2.0.0" supports-color "^8.1.1" -jiti@^2.5.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.6.1.tgz#178ef2fc9a1a594248c20627cd820187a4d78d92" - integrity sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ== - jquery@>=1.7, jquery@^3.5.1: version "3.7.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" @@ -4396,13 +3448,6 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== - dependencies: - argparse "^2.0.1" - jsesc@^3.0.2, jsesc@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" @@ -4413,21 +3458,6 @@ json-formatter-js@^2.3.4: resolved "https://registry.yarnpkg.com/json-formatter-js/-/json-formatter-js-2.5.23.tgz#b7dd0a1da7e6cbea8e76743d7d8dc1238866cc73" integrity sha512-Cbm8wHXjo/C56aCePP1VuKvjxoMEmL7g7Ckss1oWFFlCsvOEEbye1kTeaNNaqba1Cl6YpIOYAnK65pUQ8mDIUQ== -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-parse-even-better-errors@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz#93c89f529f022e5dadc233409324f0167b1e903e" - integrity sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - json-schema-traverse@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" @@ -4438,20 +3468,6 @@ json5@^2.1.2, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonfile@^6.0.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.1.tgz#b6e31717f22cc37330b081ce0051ed5de53af2f6" - integrity sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - jszip@^3.2.0: version "3.10.1" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" @@ -4494,17 +3510,12 @@ linebreak@^1.1.0: base64-js "0.0.8" unicode-trie "^2.0.0" -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - loader-runner@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== -loader-utils@^2.0.0, loader-utils@^2.0.4: +loader-utils@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -4552,29 +3563,11 @@ lodash@^4.17.20, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.18.1.tgz#ff2b66c1f6326d59513de2407bf881439812771c" integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q== -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - longest-streak@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== -lru-cache@^10.2.0: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== - -lru-cache@^11.0.0, lru-cache@^11.1.0, lru-cache@^11.2.1: - version "11.3.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.3.5.tgz#29047d348c0b2793e3112a01c739bb7c6d855637" - integrity sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -4582,24 +3575,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -make-fetch-happen@^15.0.0, make-fetch-happen@^15.0.1, make-fetch-happen@^15.0.4: - version "15.0.5" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-15.0.5.tgz#b0e3dd53d487b2733e4ea232c2bebf1bd16afb03" - integrity sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg== - dependencies: - "@gar/promise-retry" "^1.0.0" - "@npmcli/agent" "^4.0.0" - "@npmcli/redact" "^4.0.0" - cacache "^20.0.1" - http-cache-semantics "^4.1.1" - minipass "^7.0.2" - minipass-fetch "^5.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^1.0.0" - proc-log "^6.0.0" - ssri "^13.0.0" - markdown-table@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a" @@ -4783,11 +3758,6 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - micromark-core-commonmark@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz#c691630e485021a68cf28dbc2b2ca27ebf678cd4" @@ -5061,7 +4031,7 @@ micromark@^4.0.0: micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" -micromatch@^4.0.0, micromatch@^4.0.8: +micromatch@^4.0.0: version "4.0.8" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -5074,17 +4044,7 @@ mime-db@^1.54.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-function@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076" - integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== - -mini-css-extract-plugin@^2.4.2, mini-css-extract-plugin@^2.6.0: +mini-css-extract-plugin@^2.6.0: version "2.10.2" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.2.tgz#5c85ec9450c05d26e32531b465a15a08c3a57253" integrity sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg== @@ -5092,105 +4052,6 @@ mini-css-extract-plugin@^2.4.2, mini-css-extract-plugin@^2.6.0: schema-utils "^4.0.0" tapable "^2.2.1" -minimatch@^10.0.3, minimatch@^10.1.1, minimatch@^10.2.2: - version "10.2.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.5.tgz#bd48687a0be38ed2961399105600f832095861d1" - integrity sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg== - dependencies: - brace-expansion "^5.0.5" - -minimatch@^9.0.4, minimatch@^9.0.5: - version "9.0.9" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.9.tgz#9b0cb9fcb78087f6fd7eababe2511c4d3d60574e" - integrity sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg== - dependencies: - brace-expansion "^2.0.2" - -minipass-collect@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863" - integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw== - dependencies: - minipass "^7.0.3" - -minipass-fetch@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-5.0.2.tgz#3973a605ddfd8abb865e50d6fc634853c8239729" - integrity sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ== - dependencies: - minipass "^7.0.3" - minipass-sized "^2.0.0" - minizlib "^3.0.1" - optionalDependencies: - iconv-lite "^0.7.2" - -minipass-flush@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.7.tgz#145c383d5ae294b36030aa80d4e872d08bebcb73" - integrity sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-2.0.0.tgz#2228ee97e3f74f6b22ba6d1319addb7621534306" - integrity sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA== - dependencies: - minipass "^7.1.2" - -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3, minipass@^7.0.4, minipass@^7.1.2, minipass@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.3.tgz#79389b4eb1bb2d003a9bba87d492f2bd37bdc65b" - integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A== - -minizlib@^3.0.1, minizlib@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-3.1.0.tgz#6ad76c3a8f10227c9b51d1c9ac8e30b27f5a251c" - integrity sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw== - dependencies: - minipass "^7.1.2" - -mocha@^11.1.0: - version "11.7.5" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-11.7.5.tgz#58f5bbfa5e0211ce7e5ee6128107cefc2515a627" - integrity sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig== - dependencies: - browser-stdout "^1.3.1" - chokidar "^4.0.1" - debug "^4.3.5" - diff "^7.0.0" - escape-string-regexp "^4.0.0" - find-up "^5.0.0" - glob "^10.4.5" - he "^1.2.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - log-symbols "^4.1.0" - minimatch "^9.0.5" - ms "^2.1.3" - picocolors "^1.1.1" - serialize-javascript "^6.0.2" - strip-json-comments "^3.1.1" - supports-color "^8.1.1" - workerpool "^9.2.0" - yargs "^17.7.2" - yargs-parser "^21.1.1" - yargs-unparser "^2.0.0" - mrmime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" @@ -5206,32 +4067,11 @@ nanoid@^3.3.11: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== -negotiator@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" - integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== - neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-gyp@^12.1.0: - version "12.3.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-12.3.0.tgz#a0e0d9364779451eaf4148b6f9a7366f98000b3f" - integrity sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg== - dependencies: - env-paths "^2.2.0" - exponential-backoff "^3.1.1" - graceful-fs "^4.2.6" - nopt "^9.0.0" - proc-log "^6.0.0" - semver "^7.3.5" - tar "^7.5.4" - tinyglobby "^0.2.12" - undici "^6.25.0" - which "^6.0.0" - node-notifier@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-9.0.1.tgz#cea837f4c5e733936c7b9005e6545cea825d1af4" @@ -5249,81 +4089,6 @@ node-releases@^2.0.36: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.37.tgz#9bd4f10b77ba39c2b9402d4e8399c482a797f671" integrity sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg== -nopt@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-9.0.0.tgz#6bff0836b2964d24508b6b41b5a9a49c4f4a1f96" - integrity sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw== - dependencies: - abbrev "^4.0.0" - -npm-bundled@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-5.0.0.tgz#5025d847cfd06c7b8d9432df01695d0133d9ee80" - integrity sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw== - dependencies: - npm-normalize-package-bin "^5.0.0" - -npm-install-checks@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-8.0.0.tgz#f5d18e909bb8318d85093e9d8f36ac427c1cbe30" - integrity sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA== - dependencies: - semver "^7.1.1" - -npm-normalize-package-bin@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz#2b207ff260f2e525ddce93356614e2f736728f89" - integrity sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag== - -npm-package-arg@^13.0.0: - version "13.0.2" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-13.0.2.tgz#72a80f2afe8329860e63854489415e9e9a2f78a7" - integrity sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA== - dependencies: - hosted-git-info "^9.0.0" - proc-log "^6.0.0" - semver "^7.3.5" - validate-npm-package-name "^7.0.0" - -npm-packlist@^10.0.1: - version "10.0.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-10.0.4.tgz#aa2e0e4daf910eae8c5745c2645cf8bb8813de01" - integrity sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng== - dependencies: - ignore-walk "^8.0.0" - proc-log "^6.0.0" - -npm-pick-manifest@^11.0.1: - version "11.0.3" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz#76cf6593a351849006c36b38a7326798e2a76d13" - integrity sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ== - dependencies: - npm-install-checks "^8.0.0" - npm-normalize-package-bin "^5.0.0" - npm-package-arg "^13.0.0" - semver "^7.3.5" - -npm-registry-fetch@^19.0.0: - version "19.1.1" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz#51e96d21f409a9bc4f96af218a8603e884459024" - integrity sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw== - dependencies: - "@npmcli/redact" "^4.0.0" - jsonparse "^1.3.1" - make-fetch-happen "^15.0.0" - minipass "^7.0.2" - minipass-fetch "^5.0.0" - minizlib "^3.0.1" - npm-package-arg "^13.0.0" - proc-log "^6.0.0" - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -5331,20 +4096,6 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -onetime@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-7.0.0.tgz#9f16c92d8c9ef5120e3acd9dd9957cceecc1ab60" - integrity sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ== - dependencies: - mimic-function "^5.0.0" - opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" @@ -5378,44 +4129,11 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.4.tgz#b81814255f542e252d5729dca4d66e5ec14935b8" - integrity sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ== - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -package-json-from-dist@^1.0.0, package-json-from-dist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" - integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== - -pacote@^21.0.0: - version "21.5.0" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-21.5.0.tgz#475fe00db73585dec296590bec484109522e9e6f" - integrity sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ== - dependencies: - "@gar/promise-retry" "^1.0.0" - "@npmcli/git" "^7.0.0" - "@npmcli/installed-package-contents" "^4.0.0" - "@npmcli/package-json" "^7.0.0" - "@npmcli/promise-spawn" "^9.0.0" - "@npmcli/run-script" "^10.0.0" - cacache "^20.0.0" - fs-minipass "^3.0.0" - minipass "^7.0.2" - npm-package-arg "^13.0.0" - npm-packlist "^10.0.1" - npm-pick-manifest "^11.0.1" - npm-registry-fetch "^19.0.0" - proc-log "^6.0.0" - sigstore "^4.0.0" - ssri "^13.0.0" - tar "^7.4.3" - pako@^0.2.5: version "0.2.9" resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" @@ -5426,29 +4144,12 @@ pako@~1.0.2, pako@~1.0.5: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -5458,22 +4159,6 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== - dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -path-scurry@^2.0.0, path-scurry@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.2.tgz#6be0d0ee02a10d9e0de7a98bae65e182c9061f85" - integrity sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg== - dependencies: - lru-cache "^11.0.0" - minipass "^7.1.2" - pdfkit@^0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.18.0.tgz#573efa7f4c78a8ab1362232a05a589b97b292216" @@ -5505,16 +4190,11 @@ picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.2.tgz#5a942915e26b372dc0f0e6753149a16e6b1c5601" integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA== -picomatch@^4.0.3, picomatch@^4.0.4: +picomatch@^4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== -pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" @@ -5522,11 +4202,6 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -plural-forms@^0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/plural-forms/-/plural-forms-0.5.5.tgz#d15ca5597aff37373c97edc039ba11659461120e" - integrity sha512-rJw4xp22izsfJOVqta5Hyvep2lR3xPkFUtj7dyQtpf/FbxUiX7PQCajTn2EHDRylizH5N/Uqqodfdu22I0ju+g== - png-js@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.1.0.tgz#60a135216601f807b88a6d61ac93bd42a32c5ee1" @@ -5534,11 +4209,6 @@ png-js@^1.0.0: dependencies: browserify-zlib "^0.2.0" -pofile@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.1.4.tgz#eab7e29f5017589b2a61b2259dff608c0cad76a2" - integrity sha512-r6Q21sKsY1AjTVVjOuU02VYKVNQGJNQHjTIvs4dEbeuuYfxgYk/DGD2mqqq4RDaVkwdSq0VEtmQUOPe/wH8X3g== - popper.js@^1.14.7: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" @@ -5592,31 +4262,6 @@ postcss-discard-overridden@^7.0.2: resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-7.0.2.tgz#aa12b18fa1f2dc7e6d6e51fe062ed839639329c0" integrity sha512-Ym01X4v6U3sY8X0P1J9P+RTar+7JyLTOzDrxKSeaArFsLmkVu4KcAKPBWDYRIyZ/q4jwpSPnOnekeSSqXSXKUw== -postcss-import@^16.0.0: - version "16.1.1" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-16.1.1.tgz#cfbe79e6c9232b0dbbe1c18f35308825cfe8ff2a" - integrity sha512-2xVS1NCZAfjtVdvXiyegxzJ447GyqCeEI5V7ApgQVOWnros1p5lGNovJNapwPpMombyFBfqDwt7AD3n2l0KOfQ== - dependencies: - postcss-value-parser "^4.0.0" - read-cache "^1.0.0" - resolve "^1.1.7" - -postcss-js@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.1.0.tgz#003b63c6edde948766e40f3daf7e997ae43a5ce6" - integrity sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw== - dependencies: - camelcase-css "^2.0.1" - -postcss-loader@^8.0.0: - version "8.2.1" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-8.2.1.tgz#c3d9b35498af906fe6c25eb62583c06f619f92fc" - integrity sha512-k98jtRzthjj3f76MYTs9JTpRqV1RaaMhEU0Lpw9OTmQZQdppg4B30VZ74BojuBHt3F4KyubHJoXCMUeM8Bqeow== - dependencies: - cosmiconfig "^9.0.0" - jiti "^2.5.1" - semver "^7.6.2" - postcss-merge-longhand@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-7.0.6.tgz#b24f1dfb297b1ae6d1ba33aa88176b23c2069d3c" @@ -5670,16 +4315,6 @@ postcss-minify-selectors@^7.1.0: cssesc "^3.0.0" postcss-selector-parser "^7.1.1" -postcss-mixins@^11.0.0: - version "11.0.3" - resolved "https://registry.yarnpkg.com/postcss-mixins/-/postcss-mixins-11.0.3.tgz#edae34c010a3b42d94207309fe38683404e79575" - integrity sha512-HZa6DHlN7uCkp7GTFNvhpyK/Gi9+vrVG7FPl2oQdj+sXUuYo4ri9OsWBseTnvnLfWxRWOq8/VwcHcixtZPrRRg== - dependencies: - postcss-js "^4.0.1" - postcss-simple-vars "^7.0.1" - sugarss "^4.0.1" - tinyglobby "^0.2.7" - postcss-modules-extract-imports@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" @@ -5708,15 +4343,6 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nesting@^13.0.0: - version "13.0.2" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-13.0.2.tgz#fde0d4df772b76d03b52eccc84372e8d1ca1402e" - integrity sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ== - dependencies: - "@csstools/selector-resolve-nested" "^3.1.0" - "@csstools/selector-specificity" "^5.0.0" - postcss-selector-parser "^7.0.0" - postcss-normalize-charset@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-7.0.2.tgz#0d0b39ea2df240af4985f31ffa47690679a7a9a5" @@ -5810,11 +4436,6 @@ postcss-selector-parser@^7.0.0, postcss-selector-parser@^7.1.1: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-simple-vars@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz#836b3097a54dcd13dbd3c36a5dbdd512fad2954c" - integrity sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A== - postcss-svgo@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-7.1.2.tgz#67ffebb2910523cba32188732bbe8d8095bda9c2" @@ -5830,12 +4451,12 @@ postcss-unique-selectors@^7.0.6: dependencies: postcss-selector-parser "^7.1.1" -postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.0.0, postcss@^8.2.14, postcss@^8.4.12, postcss@^8.4.40: +postcss@^8.2.14, postcss@^8.4.40: version "8.5.10" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.10.tgz#8992d8c30acf3f12169e7c09514a12fed7e48356" integrity sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ== @@ -5857,11 +4478,6 @@ pretty-error@^4.0.0: lodash "^4.17.20" renderkid "^3.0.0" -proc-log@^6.0.0, proc-log@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-6.1.0.tgz#18519482a37d5198e231133a70144a50f21f0215" - integrity sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ== - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -5872,16 +4488,6 @@ property-information@^7.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== -punycode@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -5889,30 +4495,6 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -raw-loader@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" - integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -read-cache@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" - integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== - dependencies: - pify "^2.3.0" - -readable-stream@3: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" @@ -5926,11 +4508,6 @@ readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readdirp@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" - integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== - rechoir@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" @@ -6083,11 +4660,6 @@ renderkid@^3.0.0: lodash "^4.17.21" strip-ansi "^6.0.1" -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -6100,21 +4672,11 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - resolve-url-loader@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795" @@ -6126,7 +4688,7 @@ resolve-url-loader@^5.0.0: postcss "^8.2.14" source-map "0.6.1" -resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.11: +resolve@^1.20.0, resolve@^1.22.11: version "1.22.12" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f" integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA== @@ -6136,40 +4698,12 @@ resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.11: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -restore-cursor@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-5.1.0.tgz#0766d95699efacb14150993f55baf0953ea1ebe7" - integrity sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA== - dependencies: - onetime "^7.0.0" - signal-exit "^4.1.0" - restructure@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/restructure/-/restructure-3.0.2.tgz#e6b2fad214f78edee21797fa8160fef50eb9b49a" integrity sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw== -reusify@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" - integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== - -rimraf@^6.0.1: - version "6.1.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.1.3.tgz#afbee236b3bd2be331d4e7ce4493bac1718981af" - integrity sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA== - dependencies: - glob "^13.0.3" - package-json-from-dist "^1.0.1" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -6179,25 +4713,11 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - sax@^1.4.3, sax@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/sax/-/sax-1.6.0.tgz#da59637629307b97e7c4cb28e080a7bc38560d5b" integrity sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA== -schema-utils@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - "schema-utils@^3.0.0 || ^4.0.0", schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" @@ -6218,7 +4738,7 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.5.3, semver@^7.6.2, semver@^7.6.3: +semver@^7.3.2, semver@^7.3.4, semver@^7.6.3: version "7.7.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== @@ -6259,52 +4779,11 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shelljs@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.10.0.tgz#e3bbae99b0f3f0cc5dce05b46a346fae2090e883" - integrity sha512-Jex+xw5Mg2qMZL3qnzXIfaxEtBaC4n7xifqaqtrZDdlheR70OGkydrPJWT0V1cA1k3nanC86x9FwAmQl6w3Klw== - dependencies: - execa "^5.1.1" - fast-glob "^3.3.2" - shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1, signal-exit@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -sigstore@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-4.1.0.tgz#d34b92a544a05e003a2430209d26d8dfafd805a0" - integrity sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA== - dependencies: - "@sigstore/bundle" "^4.0.0" - "@sigstore/core" "^3.1.0" - "@sigstore/protobuf-specs" "^0.5.0" - "@sigstore/sign" "^4.1.0" - "@sigstore/tuf" "^4.0.1" - "@sigstore/verify" "^3.1.0" - -simple-git@^3.27.0: - version "3.36.0" - resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.36.0.tgz#019b28c0a35847ee34299c6fb63770ab1b2dffb7" - integrity sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q== - dependencies: - "@kwsites/file-exists" "^1.1.1" - "@kwsites/promise-deferred" "^1.1.1" - "@simple-git/args-pathspec" "^1.0.3" - "@simple-git/argv-parser" "^1.1.0" - debug "^4.4.0" - sirv@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/sirv/-/sirv-3.0.2.tgz#f775fccf10e22a40832684848d636346f41cd970" @@ -6314,28 +4793,6 @@ sirv@^3.0.2: mrmime "^2.0.0" totalist "^3.0.0" -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -socks-proxy-agent@^8.0.3: - version "8.0.5" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz#b9cdb4e7e998509d7659d689ce7697ac21645bee" - integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw== - dependencies: - agent-base "^7.1.2" - debug "^4.3.4" - socks "^2.8.3" - -socks@^2.8.3: - version "2.8.7" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea" - integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A== - dependencies: - ip-address "^10.0.1" - smart-buffer "^4.2.0" - source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -6369,31 +4826,6 @@ space-separated-tokens@^2.0.0: resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== -spdx-exceptions@^2.1.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" - integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== - -spdx-expression-parse@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz#a23af9f3132115465dac215c099303e4ceac5794" - integrity sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.23" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz#b069e687b1291a32f126893ed76a27a745ee2133" - integrity sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw== - -ssri@^13.0.0: - version "13.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-13.0.1.tgz#2d8946614d33f4d0c84946bb370dce7a9379fd18" - integrity sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ== - dependencies: - minipass "^7.0.3" - stackframe@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" @@ -6404,7 +4836,7 @@ stimulus-use@^0.52.0: resolved "https://registry.yarnpkg.com/stimulus-use/-/stimulus-use-0.52.3.tgz#d6f35fa93277274957a2ed98a7b04b4d702cb1d6" integrity sha512-stZ5dID6FUrGCR/ChWUa0FT5Z8iqkzT6lputOAb50eF+Ayg7RzJj4U/HoRlp2NV333QfvoRidru9HLbom4hZVw== -"string-width-cjs@npm:string-width@^4.2.0": +string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6413,31 +4845,6 @@ stimulus-use@^0.52.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -6453,13 +4860,6 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -6467,23 +4867,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.2.0.tgz#d22a269522836a627af8d04b5c3fd2c7fa3e32e3" - integrity sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w== - dependencies: - ansi-regex "^6.2.2" - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - style-loader@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-4.0.0.tgz#0ea96e468f43c69600011e0589cb05c44f3b17a5" @@ -6497,11 +4880,6 @@ stylehacks@^7.0.10: browserslist "^4.28.2" postcss-selector-parser "^7.1.1" -sugarss@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-4.0.1.tgz#128a783ed71ee0fc3b489ce1f7d5a89bc1e24383" - integrity sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw== - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -6544,18 +4922,7 @@ tapable@^2.0.0, tapable@^2.2.1, tapable@^2.3.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.3.tgz#5da7c9992c46038221267985ab28421a8879f160" integrity sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A== -tar@^7.4.3, tar@^7.5.4: - version "7.5.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.13.tgz#0d214ed56781a26edc313581c0e2d929ceeb866d" - integrity sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng== - dependencies: - "@isaacs/fs-minipass" "^4.0.0" - chownr "^3.0.0" - minipass "^7.1.2" - minizlib "^3.1.0" - yallist "^5.0.0" - -terser-webpack-plugin@^5.0.0, terser-webpack-plugin@^5.3.0, terser-webpack-plugin@^5.3.17: +terser-webpack-plugin@^5.3.0, terser-webpack-plugin@^5.3.17: version "5.4.0" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz#95fc4cf4437e587be11ecf37d08636089174d76b" integrity sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g== @@ -6575,13 +4942,6 @@ terser@^5.31.1: commander "^2.20.0" source-map-support "~0.5.20" -through2@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" - integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== - dependencies: - readable-stream "3" - tiny-emitter@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" @@ -6592,14 +4952,6 @@ tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== -tinyglobby@^0.2.12, tinyglobby@^0.2.7: - version "0.2.16" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.16.tgz#1c3b7eb953fce42b226bc5a1ee06428281aff3d6" - integrity sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg== - dependencies: - fdir "^6.5.0" - picomatch "^4.0.4" - tmp@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" @@ -6656,15 +5008,6 @@ tslib@^2.8.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -tuf-js@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-4.1.0.tgz#ae4ef9afa456fcb4af103dc50a43bc031f066603" - integrity sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ== - dependencies: - "@tufjs/models" "4.1.0" - debug "^4.4.3" - make-fetch-happen "^15.0.1" - type-fest@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-5.6.0.tgz#502f7a003b7309e96a7e17052cc2ab2c7e5c7a31" @@ -6682,11 +5025,6 @@ undici-types@~7.19.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.19.2.tgz#1b67fc26d0f157a0cba3a58a5b5c1e2276b8ba2a" integrity sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg== -undici@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-6.25.0.tgz#8c4efb8c998dc187fc1cfb5dde1ef19a211849fb" - integrity sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg== - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" @@ -6794,16 +5132,6 @@ unist-util-visit@^5.0.0: unist-util-is "^6.0.0" unist-util-visit-parents "^6.0.0" -universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - -upath@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" - integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== - update-browserslist-db@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" @@ -6812,14 +5140,7 @@ update-browserslist-db@^1.2.3: escalade "^3.2.0" picocolors "^1.1.1" -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -6834,11 +5155,6 @@ uuid@^8.3.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -validate-npm-package-name@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz#e57c3d721a4c8bbff454a246e7f7da811559ea0d" - integrity sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A== - vanilla-colorful@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/vanilla-colorful/-/vanilla-colorful-0.7.2.tgz#3fb1f4b9f15b797e20fd1ce8e0364f33b073f4a2" @@ -6941,7 +5257,7 @@ webpack-sources@^2.2.0: source-list-map "^2.0.1" source-map "^0.6.1" -webpack-sources@^3.0.0, webpack-sources@^3.3.4: +webpack-sources@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.4.tgz#a338b95eb484ecc75fbb196cbe8a2890618b4891" integrity sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q== @@ -6983,50 +5299,11 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" -which@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/which/-/which-6.0.1.tgz#021642443a198fb93b784a5606721cb18cfcbfce" - integrity sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg== - dependencies: - isexe "^4.0.0" - wildcard@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== -workerpool@^9.2.0: - version "9.3.4" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-9.3.4.tgz#f6c92395b2141afd78e2a889e80cb338fe9fca41" - integrity sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - ws@^8.19.0: version "8.20.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.0.tgz#4cd9532358eba60bc863aad1623dfb045a4d4af8" @@ -7039,54 +5316,16 @@ xmldoc@^2.0.3: dependencies: sax "^1.4.3" -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yallist@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-5.0.0.tgz#00e2de443639ed0d78fd87de0d27469fbcffb533" - integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== - -yargs-parser@^21.0.0, yargs-parser@^21.1.1: +yargs-parser@^21.0.0: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs-unparser@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@^17.7.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" From 54cb43d235ad1cda40c5e35fb9fe76f5e0cf8d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 3 May 2026 01:08:14 +0200 Subject: [PATCH 36/36] Updated yarn dependencies --- yarn.lock | 511 +++++++++++++++++++++++++++--------------------------- 1 file changed, 260 insertions(+), 251 deletions(-) diff --git a/yarn.lock b/yarn.lock index f9948f76..3ea1a62b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -64,10 +64,10 @@ js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d" - integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg== +"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.3": + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.3.tgz#e3f5347f0589596c91d227ccb6a541d37fb1307b" + integrity sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg== "@babel/core@^7.19.6": version "7.29.0" @@ -120,16 +120,16 @@ semver "^6.3.1" "@babel/helper-create-class-features-plugin@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz#611ff5482da9ef0db6291bcd24303400bca170fb" - integrity sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow== + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz#67328947d956f06fc7b48def269bf0489155fd42" + integrity sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA== 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.28.6" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - "@babel/traverse" "^7.28.6" + "@babel/traverse" "^7.29.0" semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1", "@babel/helper-create-regexp-features-plugin@^7.28.5": @@ -253,9 +253,9 @@ "@babel/types" "^7.29.0" "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": - version "7.29.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.2.tgz#58bd50b9a7951d134988a1ae177a35ef9a703ba1" - integrity sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA== + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.3.tgz#116f70a77958307fceac27747573032f8a62f88e" + integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA== dependencies: "@babel/types" "^7.29.0" @@ -281,6 +281,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" +"@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@^7.29.3": + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.3.tgz#2e14f9335803d892ccb67ef487e23cf9726156fe" + integrity sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd" @@ -723,17 +731,18 @@ "@babel/helper-plugin-utils" "^7.28.6" "@babel/preset-env@^7.19.4": - version "7.29.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.2.tgz#5a173f22c7d8df362af1c9fe31facd320de4a86c" - integrity sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw== + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.29.3.tgz#2bbd5b0162e6a762adfe356f4aecdef837a3d574" + integrity sha512-ySZypNLAIH1ClygLDQzVMoGQRViATnkHkYYV6TcNDz+8+jwZCdsguGvsb3EY5d9wyWyhmF1iSuFM0Yh5XPnqSA== dependencies: - "@babel/compat-data" "^7.29.0" + "@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.6" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" @@ -1559,10 +1568,10 @@ "@ckeditor/ckeditor5-utils" "48.0.1" es-toolkit "1.45.1" -"@colordx/core@^5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@colordx/core/-/core-5.2.0.tgz#fcf1f637b3f93f12aae57bd3929f3f90a7773627" - integrity sha512-wifnqsGCXRh+lJdX4975nKEPJaSk7k8rMiA/VeGrS4tOTn06WZrow6cUA7wFJKPXfcqj0rXeH4BMgGoKZvBf7g== +"@colordx/core@^5.4.3": + version "5.4.3" + resolved "https://registry.yarnpkg.com/@colordx/core/-/core-5.4.3.tgz#35a8d239b324a6cdf9a16de9970a32c8abc24824" + integrity sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ== "@discoveryjs/json-ext@^0.6.1", "@discoveryjs/json-ext@^0.6.3": version "0.6.3" @@ -2149,9 +2158,9 @@ ajv-keywords@^5.1.0: fast-deep-equal "^3.1.3" ajv@^8.0.0, ajv@^8.9.0: - version "8.18.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.18.0.tgz#8864186b6738d003eb3a933172bb3833e10cefbc" - integrity sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A== + version "8.20.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.20.0.tgz#304b3636add88ba7d936760dd50ece006dea95f9" + integrity sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA== dependencies: fast-deep-equal "^3.1.3" fast-uri "^3.0.1" @@ -2229,9 +2238,9 @@ base64-js@^1.1.2, base64-js@^1.3.0: integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== baseline-browser-mapping@^2.10.12: - version "2.10.20" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.20.tgz#7c99b86d43ae9be3810cac515f4675802e1f6b87" - integrity sha512-1AaXxEPfXT+GvTBJFuy4yXVHWJBXa4OdbIebGN/wX5DlsIkU0+wzGnd2lOzokSk51d5LUmqjgBLRLlypLUqInQ== + version "2.10.25" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.25.tgz#183b45c0d3bdd12addb352426555fb3627eb022a" + integrity sha512-QO/VHsXCQdnzADMfmkeOPvHdIAkoB7i0/rGjINPJEetLx75hNttVWGQ/jycHUDP9zZ9rupbm60WRxcwViB0MiA== big.js@^5.2.2: version "5.2.2" @@ -2316,9 +2325,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001782: - version "1.0.30001788" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz#31e97d1bfec332b3f2d7eea7781460c97629b3bf" - integrity sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ== + version "1.0.30001791" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz#dfb93d85c40ad380c57123e72e10f3c575786b51" + integrity sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ== ccount@^2.0.0: version "2.0.1" @@ -2641,53 +2650,53 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^7.0.15: - version "7.0.15" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-7.0.15.tgz#464501cc908de8a9c18b8a59af36a21e1d955705" - integrity sha512-60kx7lJ40//HA85cIfQXSOJFby2D2V1pOMNHVCxue3KFWCjRzmiQyL9OvI+NAhwUlaojOfF9eK3nGvrJLCBUfQ== +cssnano-preset-default@^7.0.16: + version "7.0.16" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-7.0.16.tgz#b0c9576c87488dfa00388e3a0c8b27ee946aa352" + integrity sha512-W0hiFi/ca/u2OTptL11OdApaz1vh9jyfd2ku9dMjou6KdpdgbMTagaXHKNl5kaEyRSCu9GIIaPRp5YLdqRAZMw== dependencies: browserslist "^4.28.2" css-declaration-sorter "^7.2.0" - cssnano-utils "^5.0.2" + cssnano-utils "^5.0.3" postcss-calc "^10.1.1" - postcss-colormin "^7.0.9" - postcss-convert-values "^7.0.11" - postcss-discard-comments "^7.0.7" - postcss-discard-duplicates "^7.0.3" - postcss-discard-empty "^7.0.2" - postcss-discard-overridden "^7.0.2" - postcss-merge-longhand "^7.0.6" - postcss-merge-rules "^7.0.10" - postcss-minify-font-values "^7.0.2" - postcss-minify-gradients "^7.0.4" - postcss-minify-params "^7.0.8" - postcss-minify-selectors "^7.1.0" - postcss-normalize-charset "^7.0.2" - postcss-normalize-display-values "^7.0.2" - postcss-normalize-positions "^7.0.3" - postcss-normalize-repeat-style "^7.0.3" - postcss-normalize-string "^7.0.2" - postcss-normalize-timing-functions "^7.0.2" - postcss-normalize-unicode "^7.0.8" - postcss-normalize-url "^7.0.2" - postcss-normalize-whitespace "^7.0.2" - postcss-ordered-values "^7.0.3" - postcss-reduce-initial "^7.0.8" - postcss-reduce-transforms "^7.0.2" - postcss-svgo "^7.1.2" - postcss-unique-selectors "^7.0.6" + postcss-colormin "^7.0.10" + postcss-convert-values "^7.0.12" + postcss-discard-comments "^7.0.8" + postcss-discard-duplicates "^7.0.4" + postcss-discard-empty "^7.0.3" + postcss-discard-overridden "^7.0.3" + postcss-merge-longhand "^7.0.7" + postcss-merge-rules "^7.0.11" + postcss-minify-font-values "^7.0.3" + postcss-minify-gradients "^7.0.5" + postcss-minify-params "^7.0.9" + postcss-minify-selectors "^7.1.1" + postcss-normalize-charset "^7.0.3" + postcss-normalize-display-values "^7.0.3" + postcss-normalize-positions "^7.0.4" + postcss-normalize-repeat-style "^7.0.4" + postcss-normalize-string "^7.0.3" + postcss-normalize-timing-functions "^7.0.3" + postcss-normalize-unicode "^7.0.9" + postcss-normalize-url "^7.0.3" + postcss-normalize-whitespace "^7.0.3" + postcss-ordered-values "^7.0.4" + postcss-reduce-initial "^7.0.9" + postcss-reduce-transforms "^7.0.3" + postcss-svgo "^7.1.3" + postcss-unique-selectors "^7.0.7" -cssnano-utils@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-5.0.2.tgz#92939eda38fb934151a8c87bd60764d1a27c5597" - integrity sha512-kt41WLK7FLKfePzPi645Y+/NtW/nNM7Su6nlNUfJyRNW3JcuU3JU7+cWJc+JexTeZ8dRBvFufefdG2XpXkIo0A== +cssnano-utils@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-5.0.3.tgz#f64e6a777bf37d99d6b2a6524c6b6c0681f01da0" + integrity sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg== cssnano@^7.0.4: - version "7.1.7" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-7.1.7.tgz#152658ec9d24f080851c3010e61673d539765af7" - integrity sha512-N5LGn/OlhMxDTvKACwUPMzT34SSj1b022pvUAE/Vh6r2WD1aUCbc+QNIP/JjX9VVxebdJWZQ3352Lt4oF7dQ/g== + version "7.1.8" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-7.1.8.tgz#a6508bd13f3b206676c6594fa19ef45a89acc9dc" + integrity sha512-OGXtXqXmwEoIGfXM2QoD35vweUAtx+J8ZvLSZHOEV0Jv9Hs9ScTdGGjRzZXun5J4PEZhEoytKig2O2NR8NXxKw== dependencies: - cssnano-preset-default "^7.0.15" + cssnano-preset-default "^7.0.16" lilconfig "^3.1.3" csso@^5.0.5: @@ -2698,11 +2707,11 @@ csso@^5.0.5: css-tree "~2.2.0" datatables.net-bs5@^2, datatables.net-bs5@^2.0.0: - version "2.3.7" - resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-2.3.7.tgz#ddef957ee23b03c2d4bc1d48735b39c6182e5d53" - integrity sha512-RiCEMpMXDBeMDwjSrMpmcXDU6mibRMuOn7Wk7k3SlOfLEY3FQHO7S2m+K7teXYeaNlCLyjJMU+6BUUwlBCpLFw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-2.3.8.tgz#7266636ff488429988ca664bc8cb0b7c5e48c563" + integrity sha512-TbFH99QSWm93Kn3teHLFKeyOqYbaiddlHvRFdXUwAvh/fjTMhACWmHG+I43ss8d23OEFHV0WIbN4lpPusZm5zw== dependencies: - datatables.net "2.3.7" + datatables.net "2.3.8" jquery ">=1.7" datatables.net-buttons-bs5@^3.0.0: @@ -2790,10 +2799,10 @@ datatables.net-select@3.1.3: datatables.net "^2" jquery ">=1.7" -datatables.net@2.3.7, datatables.net@^2, datatables.net@^2.0.0: - version "2.3.7" - resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.7.tgz#3cd34f6f5d1f40a46b5a20a4ba32604bdbcd6738" - integrity sha512-AvsjG/Nkp6OxeyBKYZauemuzQCPogE1kOtKwG4sYjvdqGCSLiGaJagQwXv4YxG+ts5vaJr6qKGG9ec3g6vTo3w== +datatables.net@2.3.8, datatables.net@^2, datatables.net@^2.0.0: + version "2.3.8" + resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.8.tgz#55a8dbe3bd2196951c498ab79bf44602a2bf3229" + integrity sha512-uhViowhlDlheAuo5a8TrkQqADsjrtGeOyvrigvr4t0+K3MyAWqClORXWAYIcN9VLX6iIX0C8O9gwJNd01hITRg== dependencies: jquery ">=1.7" @@ -2883,9 +2892,9 @@ domhandler@^5.0.2, domhandler@^5.0.3: domelementtype "^2.3.0" dompurify@^3.0.3: - version "3.4.1" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.1.tgz#521d04483ac12631b2aedf434a5f5390933b8789" - integrity sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw== + version "3.4.2" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.2.tgz#f0ff81be682c485505097ba8195a058d8f575218" + integrity sha512-lHeS9SA/IKeIFFyYciHBr2n0v1VMPlSj843HdLOwjb2OxNwdq9Xykxqhk+FE42MzAdHvInbAolSE4mhahPpjXA== optionalDependencies: "@types/trusted-types" "^2.0.7" @@ -2908,9 +2917,9 @@ domutils@^3.0.1: domhandler "^5.0.3" electron-to-chromium@^1.5.328: - version "1.5.341" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.341.tgz#427b826ac41d406162b7700e6032c2b9cc4ecc5c" - integrity sha512-1sZTssferjgDgaqRTc0ieP+ozzpOy7LQTPTtEW3yQFn4+ORdIAZWV5BthXPyHF7YqLvFJCUPhNhdAJQYlYUgiw== + version "1.5.349" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.349.tgz#9b9c6a6d84d1107557c18a9336099ce0ee890e5b" + integrity sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A== emoji-regex@^8.0.0: version "8.0.0" @@ -2923,12 +2932,12 @@ emojis-list@^3.0.0: integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== enhanced-resolve@^5.0.0, enhanced-resolve@^5.20.0: - version "5.20.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz#eeeb3966bea62c348c40a0cc9e7912e2557d0be0" - integrity sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA== + version "5.21.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz#bb8e6fabaf74930de70e61397798750429e5b1ae" + integrity sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA== dependencies: graceful-fs "^4.2.4" - tapable "^2.3.0" + tapable "^2.3.3" entities@^2.0.0: version "2.2.0" @@ -2958,9 +2967,9 @@ es-errors@^1.3.0: integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-module-lexer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" - integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.1.0.tgz#1dfcbb5ea3bbfb63f28e1fc3676c3676d1c9624c" + integrity sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ== es-toolkit@1.45.1: version "1.45.1" @@ -3511,9 +3520,9 @@ linebreak@^1.1.0: unicode-trie "^2.0.0" loader-runner@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" - integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== + version "4.3.2" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.2.tgz#9913d3a15971f8f635915e601fb5c9d495d918e9" + integrity sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w== loader-utils@^2.0.0: version "2.0.4" @@ -4063,9 +4072,9 @@ ms@^2.1.3: integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== nanoid@^3.3.11: - version "3.3.11" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" - integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + version "3.3.12" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05" + integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ== neo-async@^2.6.2: version "2.6.2" @@ -4085,9 +4094,9 @@ node-notifier@^9.0.0: which "^2.0.2" node-releases@^2.0.36: - version "2.0.37" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.37.tgz#9bd4f10b77ba39c2b9402d4e8399c482a797f671" - integrity sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg== + version "2.0.38" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.38.tgz#791569b9e4424a044e12c3abfad418ed83ce9947" + integrity sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw== nth-check@^2.0.1: version "2.1.1" @@ -4222,93 +4231,93 @@ postcss-calc@^10.1.1: postcss-selector-parser "^7.0.0" postcss-value-parser "^4.2.0" -postcss-colormin@^7.0.9: - version "7.0.9" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-7.0.9.tgz#688b4f22599c9aedd3126f978580b43a4ced009f" - integrity sha512-EZpoUlmbXQUpe+g4ZaGM2kjGlHrQ7Bjzb3xHcNrC9ysI1tGoib6DAYvxg6aB7MGxsjgLF+Qx/jwZQkJ5cKDvXA== - dependencies: - "@colordx/core" "^5.2.0" - browserslist "^4.28.2" - caniuse-api "^3.0.0" - postcss-value-parser "^4.2.0" - -postcss-convert-values@^7.0.11: - version "7.0.11" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-7.0.11.tgz#d13c80e74732d841894ba315410bfaae9be79545" - integrity sha512-H+s7P0f9jJylSysAHs3/5MhAx7GthDO05uw1h56L2xyEqpiLTFLEqBNw3PUYzD5p/AKwWaigCXf6FGELpOw9lw== - dependencies: - browserslist "^4.28.2" - postcss-value-parser "^4.2.0" - -postcss-discard-comments@^7.0.7: - version "7.0.7" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-7.0.7.tgz#6e8226e8e818e37a98c7b6af5c66aa7b730e0d17" - integrity sha512-FJhE3fSte7HaRNL4iwD8LTG9vWqj3puxXIdig6LfrFqc1TJRUhY4kXOkeTXZZfTXYny+k+SO7fd2fymj1wduJg== - dependencies: - postcss-selector-parser "^7.1.1" - -postcss-discard-duplicates@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.3.tgz#4a1c51219a1f347838744829db1064deb0758770" - integrity sha512-9cRxXwhEM/aNZon1qZyToX4NmjbFbxOGbww+0CnbYFDbbPRGZ8jg4IbM8UlA+CzkXxM35itxyaHKNqBBg/RTDg== - -postcss-discard-empty@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-7.0.2.tgz#4af6e7cb088ef807564a7e60bfe8db32feb8abcd" - integrity sha512-NZFouOmOwtngJVgkNeI1LtkzFdYqIurxgy4wq3qNvIiXFURTZ3b/K7q3dP3QitlWQ5imHDQL0qSorItQhoxb1g== - -postcss-discard-overridden@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-7.0.2.tgz#aa12b18fa1f2dc7e6d6e51fe062ed839639329c0" - integrity sha512-Ym01X4v6U3sY8X0P1J9P+RTar+7JyLTOzDrxKSeaArFsLmkVu4KcAKPBWDYRIyZ/q4jwpSPnOnekeSSqXSXKUw== - -postcss-merge-longhand@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-7.0.6.tgz#b24f1dfb297b1ae6d1ba33aa88176b23c2069d3c" - integrity sha512-lDsWeKRsssX/9vKFpingoRiuvGajtOGCJhs1kyaTJ5fzaVzs0aPPYe38UZ/ukMFEA5iuRIjQJHIkH2niYO3ubQ== - dependencies: - postcss-value-parser "^4.2.0" - stylehacks "^7.0.10" - -postcss-merge-rules@^7.0.10: +postcss-colormin@^7.0.10: version "7.0.10" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-7.0.10.tgz#6b8d2c1e0fa72cf5c045356610c86108eb5af397" - integrity sha512-UXYKxkg8Cy1so/evF7AE/25PNXZb3E0SrvjdbtbGf+MW+doLenKqRLQzz6YZW469ktiXK2MVLFWtel/DftCV0Q== + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-7.0.10.tgz#8564621ba92496e30fc0ead4ab29be4718c30614" + integrity sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg== + dependencies: + "@colordx/core" "^5.4.3" + browserslist "^4.28.2" + caniuse-api "^3.0.0" + postcss-value-parser "^4.2.0" + +postcss-convert-values@^7.0.12: + version "7.0.12" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-7.0.12.tgz#2fa2737bfe799fdff3f87309c70bcef16d971eb5" + integrity sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q== + dependencies: + browserslist "^4.28.2" + postcss-value-parser "^4.2.0" + +postcss-discard-comments@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-7.0.8.tgz#1eaf1d8b76572cdc50074ff9945e342af678d8dc" + integrity sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q== + dependencies: + postcss-selector-parser "^7.1.1" + +postcss-discard-duplicates@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.4.tgz#1ddaabe81b7412e056fc406e1a2241319632869c" + integrity sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw== + +postcss-discard-empty@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-7.0.3.tgz#67b4b07b4fc75dfb602cd97fea61b60dda223e18" + integrity sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw== + +postcss-discard-overridden@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-7.0.3.tgz#366895511ed1d5ffe2d16a84c530d05e554ebff0" + integrity sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ== + +postcss-merge-longhand@^7.0.7: + version "7.0.7" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-7.0.7.tgz#9c1e2b6566c20aee31bc9167e9379cb9b8823342" + integrity sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^7.0.11" + +postcss-merge-rules@^7.0.11: + version "7.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-7.0.11.tgz#ddf279e103eb6130e35908a07faffe33c21491b0" + integrity sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q== dependencies: browserslist "^4.28.2" caniuse-api "^3.0.0" - cssnano-utils "^5.0.2" + cssnano-utils "^5.0.3" postcss-selector-parser "^7.1.1" -postcss-minify-font-values@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-7.0.2.tgz#8d831d8ddfe75d5062451d56f10d36a31e5cbea3" - integrity sha512-Z82NUmnvhPrvMUaHfkaAVBmWQq9F8Dox4Dy0LiwbaTxfmDUWLQtS+0WCgKViwdWCPPajiY9YzoQftgqKdXkM5g== +postcss-minify-font-values@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-7.0.3.tgz#e14218a8b85e390b9602dfba6fe66a228ae90b28" + integrity sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA== dependencies: postcss-value-parser "^4.2.0" -postcss-minify-gradients@^7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-7.0.4.tgz#145615c2382e9c26e780a483b3ee0939688419b5" - integrity sha512-g8MNeNyN+lbwKy8DCtJ6zU6awBL0InBsSOaKmgZ1MdRLVItLQUNFNAzzzBnOp4qowOcyyB6GetTlQ0/0UNXvag== +postcss-minify-gradients@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-7.0.5.tgz#6baf5a896a067b0e9b1efb78cb75d6dced33e9b7" + integrity sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ== dependencies: - "@colordx/core" "^5.2.0" - cssnano-utils "^5.0.2" + "@colordx/core" "^5.4.3" + cssnano-utils "^5.0.3" postcss-value-parser "^4.2.0" -postcss-minify-params@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-7.0.8.tgz#5d7f6e303bbf23ebc68899c0b1443a30cc4321d6" - integrity sha512-DIUKM5DZGTmxN7KFKT+rxt0FdPDmRrdK/k3n3+6Po+N/QYn06juwagHcfOVBG0CfCHwcnI612GAUCZc3eT+ZEg== +postcss-minify-params@^7.0.9: + version "7.0.9" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-7.0.9.tgz#afbab58c912c1e5d97c05184a7b0df662f2e87c0" + integrity sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA== dependencies: browserslist "^4.28.2" - cssnano-utils "^5.0.2" + cssnano-utils "^5.0.3" postcss-value-parser "^4.2.0" -postcss-minify-selectors@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-7.1.0.tgz#578e2ab5fb1b5156c4f18d7d64861ff656fd0aea" - integrity sha512-HYl/6I0aL+UvpA10t65BSa7h+tVjBgE6oRI5N/3ylX3vtwvlDL67G3FT3vYDPnTksxr0riiyJcT0tBtyRVoloA== +postcss-minify-selectors@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-7.1.1.tgz#2de3a0f9fc07d745d4164adc59865b3a0c9b1b87" + integrity sha512-MZWXwSTfcpmNVJIs7tddar/275a4/zT5nG9/gEndHPRZGTAQNpiSkk8s/dq+yZVX2jKfvVn1d5X8Z5SJHWnDoQ== dependencies: browserslist "^4.28.1" caniuse-api "^3.0.0" @@ -4343,88 +4352,88 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-normalize-charset@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-7.0.2.tgz#0d0b39ea2df240af4985f31ffa47690679a7a9a5" - integrity sha512-YoINoiR4YKlzfB95Y93b0DSxWy7FLw+1SADIaznMHb88AKizpzfF80tolmiDEbYr1UM4r4Hw+NZq37SwT5f3uw== - -postcss-normalize-display-values@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.2.tgz#a90f6ec503b2c6441f04040108c5a123d7e0abe1" - integrity sha512-wu/NTSjnp8sX5TnEHVPN+eScjAtRs18ELtEduG+Ek3GxjeUDUT+VAA3PJjVIXBcVIk6fiLYFj2iKH0q99S3T2Q== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-positions@^7.0.3: +postcss-normalize-charset@^7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-7.0.3.tgz#79d185099da6d06b0eb417908e1564ba97082594" - integrity sha512-1CJI++oA3yK/fQlPUcEngUfcSWS08Pkt9fK+jVgL53mmtHDBHi0YiuB0m3D9BXwZjmfvCc2GQmFqCAF/CVcPzQ== - dependencies: - postcss-value-parser "^4.2.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-7.0.3.tgz#73862324ca03c14e37a2ef1da7a1a6139336e788" + integrity sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q== -postcss-normalize-repeat-style@^7.0.3: +postcss-normalize-display-values@^7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.3.tgz#479c79c371d685533c73ef491d7adf9a9759e74c" - integrity sha512-RvImJ2Ml4LZSx31qC2C8LDiz65IgBNATtwEr9r3Aue+D0cCGbj4rjNojb/uGpEm4QxnOTzFqMvaDYuKiT1Cmpg== + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.3.tgz#feea4f9b52d6acf165ecfd36162b4254dd7f7ee8" + integrity sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-string@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-7.0.2.tgz#a2d2111f320b88fa859212867beb8dd1f5f9e8c0" - integrity sha512-FqtrUh2BU2MnVeLeWBbJ2rwOjuDnA91XvoImc1BbgMWIxdxiPTaquflBHsmFBA3xh3pC3wPZO9W5MaIc7wU/Xw== +postcss-normalize-positions@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-7.0.4.tgz#2fc7bcb651fed59b90e21b2e81f546475be65e2d" + integrity sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-timing-functions@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.2.tgz#50b5b10f99f05bc1d920c6ff471f2ab9794b3fbf" - integrity sha512-5H5fpXBnMACEXzn7k9RP7qWZ1eWg8cuZkUuFygStY7icOj+UucwMWXeMmdkF/iITvTVa7fP85tdRCJeznpdFfQ== +postcss-normalize-repeat-style@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.4.tgz#6df15d1ea9766dd53366edcf9f3dc6d0266e19c0" + integrity sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-unicode@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.8.tgz#315b2f008aa4a94d02de67ec84d9e9b1cd99f9bf" - integrity sha512-imCM3cwK3hvlAG4z1AzYM24m8BPA3/Jk/S71wfbn2I6+E2b+UwFaGvlNqydihXTSl3OFPeQXztqCzg+NGeSibQ== +postcss-normalize-string@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-7.0.3.tgz#bf6f38814fc632ae8528a7cd101877835e266e47" + integrity sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.3.tgz#db0034b9227a008230733cf4a86757821735104f" + integrity sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^7.0.9: + version "7.0.9" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.9.tgz#f3d4f13af7471c9fcc5de184ba5ea889d7484f3b" + integrity sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg== dependencies: browserslist "^4.28.2" postcss-value-parser "^4.2.0" -postcss-normalize-url@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-7.0.2.tgz#5d530aa724a31cfd6b68b904eb542fd1af9cb7d3" - integrity sha512-bLnNY7t76NLRb9QQyCVmCN4qwoHxiq6vABH/CXav9wTuR6dNGHGQ72AyO/+h2quWxZk3l7BqxNL1vtDi9H6y1g== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-whitespace@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.2.tgz#eb91bdb73f04570e4fb7055493e61b5aedd69fb7" - integrity sha512-TNSVkuhkeOhl36WruQlflxOb7HweoeZowSusNpfsM1+ZvqJ24Mc+xksu05ecMQxlu+0zgI8pyznO2EWqDCQbLA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-ordered-values@^7.0.3: +postcss-normalize-url@^7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-7.0.3.tgz#8ad4cc375b9258904f88eefbfe6a9f13f3fe31b7" - integrity sha512-FTt6R9RF7NAYfpOHa2XFPm89FVuo5GiIbcfwOXFy1MYF38BeiNW9ke8ybw9Pk62eEsUlRVVbxHWA3B7ERYqOOA== + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-7.0.3.tgz#bf8807b7d0f58228cf7b958e6a024e32ec87b74e" + integrity sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q== dependencies: - cssnano-utils "^5.0.2" postcss-value-parser "^4.2.0" -postcss-reduce-initial@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-7.0.8.tgz#81a3ac97722d55f415cbd18736e596b2fc9330e4" - integrity sha512-VeVRmbgpgTZuRcDQdqnsB4iYTeS2dBRV07UdwK6V3x61F1xTQ2pgIzHBIR4rQYRlXRNKBTGYYhEL1eNA7w9vaQ== +postcss-normalize-whitespace@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.3.tgz#d32556f2c97e217ec3d08d9b2e7f9d1b474e8cb9" + integrity sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-ordered-values@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-7.0.4.tgz#b86108fa6f873fc78fbaa0cdc4b59cf3b3275ec3" + integrity sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg== + dependencies: + cssnano-utils "^5.0.3" + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^7.0.9: + version "7.0.9" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-7.0.9.tgz#08e975ad180efe01ebca60e50aec23382ca8163f" + integrity sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ== dependencies: browserslist "^4.28.2" caniuse-api "^3.0.0" -postcss-reduce-transforms@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.2.tgz#f40d635a56f6417c7e02bbebb0bf082d4f84d988" - integrity sha512-OV5P9hMnf7kEkeXVXyS5ESqxbIls7a3TqFymUAV5JICO/9YCBEU+QQhQjZiDHaLwFdV7/CL481kVeBUk5FdY3w== +postcss-reduce-transforms@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.3.tgz#904b6176da1d809fc2d1f453b0eefb5db0b6ad0e" + integrity sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g== dependencies: postcss-value-parser "^4.2.0" @@ -4436,18 +4445,18 @@ postcss-selector-parser@^7.0.0, postcss-selector-parser@^7.1.1: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-svgo@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-7.1.2.tgz#67ffebb2910523cba32188732bbe8d8095bda9c2" - integrity sha512-ixExc8m+/68yuSYQzV/1DgtTup/7nI2dN9eiDS5GMRUzeCH4q9UcqeZPwcSVhdf8ay9fRwXDUHwcY5/XzQSszQ== +postcss-svgo@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-7.1.3.tgz#d225c0df52d984659277b9d9f6b255cf8b2942d3" + integrity sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw== dependencies: postcss-value-parser "^4.2.0" svgo "^4.0.1" -postcss-unique-selectors@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-7.0.6.tgz#fdbb14c57ebb3afa4b79c086841cf23e7d1473b6" - integrity sha512-cDxnYw1QuBMW5w3svZ0BlYF0IA4Amr+1JoTLXzu6vDFPNwohN2QU+sPZNx15b930LR7ce+/600h28/cYoxO9vw== +postcss-unique-selectors@^7.0.7: + version "7.0.7" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-7.0.7.tgz#f377aa479c646a5b1049f54f603cd89d88606512" + integrity sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w== dependencies: postcss-selector-parser "^7.1.1" @@ -4457,9 +4466,9 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@^8.2.14, postcss@^8.4.40: - version "8.5.10" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.10.tgz#8992d8c30acf3f12169e7c09514a12fed7e48356" - integrity sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ== + version "8.5.13" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.13.tgz#6cfaf647f2e7ef69850208eccd849e0d3f65d420" + integrity sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag== dependencies: nanoid "^3.3.11" picocolors "^1.1.1" @@ -4872,10 +4881,10 @@ style-loader@^4.0.0: resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-4.0.0.tgz#0ea96e468f43c69600011e0589cb05c44f3b17a5" integrity sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA== -stylehacks@^7.0.10: - version "7.0.10" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-7.0.10.tgz#1fdeab7bb40c85074e60286f8053700d9d7436cc" - integrity sha512-sRJ7klmhe/Fl5woJcbJUa2qP1Ueffsl1CQI4ePvqXLkZmcIuAt09aP9uT/FOFPqXh9Rh8M5UkgEnwTdTKn/Aag== +stylehacks@^7.0.11: + version "7.0.11" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-7.0.11.tgz#b6c97388d4f7f97560f3c69e3bfe1d3db74bb2c2" + integrity sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg== dependencies: browserslist "^4.28.2" postcss-selector-parser "^7.1.1" @@ -4917,15 +4926,15 @@ tagged-tag@^1.0.0: resolved "https://registry.yarnpkg.com/tagged-tag/-/tagged-tag-1.0.0.tgz#a0b5917c2864cba54841495abfa3f6b13edcf4d6" integrity sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng== -tapable@^2.0.0, tapable@^2.2.1, tapable@^2.3.0: +tapable@^2.0.0, tapable@^2.2.1, tapable@^2.3.0, tapable@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.3.tgz#5da7c9992c46038221267985ab28421a8879f160" integrity sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A== terser-webpack-plugin@^5.3.0, terser-webpack-plugin@^5.3.17: - version "5.4.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz#95fc4cf4437e587be11ecf37d08636089174d76b" - integrity sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g== + version "5.5.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.5.0.tgz#d92b8e2c892dd09c683c38120394267e8d8660ef" + integrity sha512-UYhptBwhWvfIjKd/UuFo6D8uq9xpGLDK+z8EDsj/zWhrTaH34cKEbrkMKfV5YWqGBvAYA3tlzZbs2R+qYrbQJA== dependencies: "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" @@ -4933,9 +4942,9 @@ terser-webpack-plugin@^5.3.0, terser-webpack-plugin@^5.3.17: terser "^5.31.1" terser@^5.31.1: - version "5.46.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.46.1.tgz#40e4b1e35d5f13130f82793a8b3eeb7ec3a92eee" - integrity sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ== + version "5.46.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.46.2.tgz#b9529672d5b0024c7959571c83b82f65077b2a4f" + integrity sha512-uxfo9fPcSgLDYob/w1FuL0c99MWiJDnv+5qXSQc5+Ki5NjVNsYi66INnMFBjf6uFz6OnX12piJQPF4IpjJTNTw== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.15.0" @@ -5258,9 +5267,9 @@ webpack-sources@^2.2.0: source-map "^0.6.1" webpack-sources@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.4.tgz#a338b95eb484ecc75fbb196cbe8a2890618b4891" - integrity sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q== + version "3.4.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.4.1.tgz#009d110999ebd9fb3a6fa8d32eec6f84d940e65d" + integrity sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A== webpack@^5.74.0: version "5.106.2"