From 98d92ce8f8f78d03fd2b8c0e049732c1dbcea1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Tue, 28 Oct 2025 12:09:38 +0100 Subject: [PATCH 001/131] feat: add internal rate limit for rdap queries --- config/packages/messenger.yaml | 15 ++- config/packages/rate_limiter.yaml | 9 +- src/Command/ProcessWatchlistCommand.php | 4 +- src/Command/RegisterDomainCommand.php | 4 +- src/Controller/MeController.php | 4 +- ...nEventNotif.php => DetectDomainChange.php} | 2 +- ...istTrigger.php => ProcessAllWatchlist.php} | 2 +- ...FromWatchlist.php => ProcessWatchlist.php} | 2 +- src/Message/UpdateDomain.php | 15 +++ ...dler.php => DetectDomainChangeHandler.php} | 6 +- ...ler.php => ProcessAllWatchlistHandler.php} | 12 +- ...andler.php => ProcessWatchlistHandler.php} | 57 +------- src/MessageHandler/UpdateDomainHandler.php | 127 ++++++++++++++++++ ...edule.php => ProcessWatchlistSchedule.php} | 8 +- src/State/AutoRegisterDomainProvider.php | 8 +- .../ProcessWatchlistTriggerHandlerTest.php | 12 +- .../UpdateDomainsFromWatchlistHandlerTest.php | 8 +- 17 files changed, 203 insertions(+), 92 deletions(-) rename src/Message/{SendDomainEventNotif.php => DetectDomainChange.php} (85%) rename src/Message/{ProcessWatchlistTrigger.php => ProcessAllWatchlist.php} (87%) rename src/Message/{UpdateDomainsFromWatchlist.php => ProcessWatchlist.php} (71%) create mode 100644 src/Message/UpdateDomain.php rename src/MessageHandler/{SendDomainEventNotifHandler.php => DetectDomainChangeHandler.php} (97%) rename src/MessageHandler/{ProcessWatchlistTriggerHandler.php => ProcessAllWatchlistHandler.php} (71%) rename src/MessageHandler/{UpdateDomainsFromWatchlistHandler.php => ProcessWatchlistHandler.php} (55%) create mode 100644 src/MessageHandler/UpdateDomainHandler.php rename src/Scheduler/{SendNotifWatchlistTriggerSchedule.php => ProcessWatchlistSchedule.php} (76%) diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index ca8a7b3..17ffa87 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -9,6 +9,14 @@ framework: retry_strategy: max_retries: 3 multiplier: 2 + rdap_async: + dsn: '%env(MESSENGER_TRANSPORT_DSN)%' + retry_strategy: + delay: 1000 + multiplier: 2 + max_retries: 10 + max_delay: 10000 + failed: 'doctrine://default?queue_name=failed' # sync: 'sync://' @@ -23,11 +31,12 @@ framework: Symfony\Component\Notifier\Message\SmsMessage: async App\Message\OrderDomain: async - App\Message\ProcessWatchlistTrigger: async - App\Message\SendDomainEventNotif: async - App\Message\UpdateDomainsFromWatchlist: async + App\Message\DetectDomainChange: async + App\Message\ProcessAllWatchlist: async + App\Message\ProcessWatchlist: async App\Message\UpdateRdapServers: async App\Message\ValidateConnectorCredentials: async + App\Message\UpdateDomain: async # Route your messages to the transports # 'App\Message\YourMessage': async diff --git a/config/packages/rate_limiter.yaml b/config/packages/rate_limiter.yaml index 11e6dc1..b93e8c5 100644 --- a/config/packages/rate_limiter.yaml +++ b/config/packages/rate_limiter.yaml @@ -20,7 +20,12 @@ framework: limit: 5 rate: { interval: '5 minutes' } - rdap_requests: + user_rdap_requests: policy: sliding_window limit: 10 - interval: '1 hour' \ No newline at end of file + interval: '1 hour' + + rdap_requests: + policy: sliding_window + limit: 2 + interval: '1 second' diff --git a/src/Command/ProcessWatchlistCommand.php b/src/Command/ProcessWatchlistCommand.php index 1d4a84a..a923f13 100644 --- a/src/Command/ProcessWatchlistCommand.php +++ b/src/Command/ProcessWatchlistCommand.php @@ -2,7 +2,7 @@ namespace App\Command; -use App\Message\ProcessWatchlistTrigger; +use App\Message\ProcessAllWatchlist; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -33,7 +33,7 @@ class ProcessWatchlistCommand extends Command { $io = new SymfonyStyle($input, $output); - $this->bus->dispatch(new ProcessWatchlistTrigger()); + $this->bus->dispatch(new ProcessAllWatchlist()); $io->success('Watchlist processing triggered!'); diff --git a/src/Command/RegisterDomainCommand.php b/src/Command/RegisterDomainCommand.php index 7d4e281..9a611d1 100644 --- a/src/Command/RegisterDomainCommand.php +++ b/src/Command/RegisterDomainCommand.php @@ -3,7 +3,7 @@ namespace App\Command; use App\Entity\Watchlist; -use App\Message\SendDomainEventNotif; +use App\Message\DetectDomainChange; use App\Repository\DomainRepository; use App\Service\RDAPService; use Random\Randomizer; @@ -64,7 +64,7 @@ class RegisterDomainCommand extends Command /** @var Watchlist $watchlist */ foreach ($watchlists as $watchlist) { - $this->bus->dispatch(new SendDomainEventNotif($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); + $this->bus->dispatch(new DetectDomainChange($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); } } } catch (\Throwable $e) { diff --git a/src/Controller/MeController.php b/src/Controller/MeController.php index 20ca66e..4590eb2 100644 --- a/src/Controller/MeController.php +++ b/src/Controller/MeController.php @@ -12,14 +12,14 @@ class MeController extends AbstractController { public function __construct( private readonly SerializerInterface $serializer, - private readonly RateLimiterFactory $rdapRequestsLimiter, + private readonly RateLimiterFactory $userRdapRequestsLimiter, ) { } public function __invoke(): Response { $user = $this->getUser(); - $limiter = $this->rdapRequestsLimiter->create($user->getUserIdentifier()); + $limiter = $this->userRdapRequestsLimiter->create($user->getUserIdentifier()); $limit = $limiter->consume(0); $data = $this->serializer->serialize($user, 'json', ['groups' => 'user:list']); diff --git a/src/Message/SendDomainEventNotif.php b/src/Message/DetectDomainChange.php similarity index 85% rename from src/Message/SendDomainEventNotif.php rename to src/Message/DetectDomainChange.php index 9866617..dfe6831 100644 --- a/src/Message/SendDomainEventNotif.php +++ b/src/Message/DetectDomainChange.php @@ -2,7 +2,7 @@ namespace App\Message; -final class SendDomainEventNotif +final class DetectDomainChange { public function __construct( public string $watchlistToken, diff --git a/src/Message/ProcessWatchlistTrigger.php b/src/Message/ProcessAllWatchlist.php similarity index 87% rename from src/Message/ProcessWatchlistTrigger.php rename to src/Message/ProcessAllWatchlist.php index 4e44f16..bf405b9 100644 --- a/src/Message/ProcessWatchlistTrigger.php +++ b/src/Message/ProcessAllWatchlist.php @@ -2,7 +2,7 @@ namespace App\Message; -final class ProcessWatchlistTrigger +final class ProcessAllWatchlist { /* * Add whatever properties and methods you need diff --git a/src/Message/UpdateDomainsFromWatchlist.php b/src/Message/ProcessWatchlist.php similarity index 71% rename from src/Message/UpdateDomainsFromWatchlist.php rename to src/Message/ProcessWatchlist.php index 41bed74..136f593 100644 --- a/src/Message/UpdateDomainsFromWatchlist.php +++ b/src/Message/ProcessWatchlist.php @@ -2,7 +2,7 @@ namespace App\Message; -final readonly class UpdateDomainsFromWatchlist +final readonly class ProcessWatchlist { public function __construct( public string $watchlistToken, diff --git a/src/Message/UpdateDomain.php b/src/Message/UpdateDomain.php new file mode 100644 index 0000000..758b1ce --- /dev/null +++ b/src/Message/UpdateDomain.php @@ -0,0 +1,15 @@ +watchlistRepository->findOneBy(['token' => $message->watchlistToken]); diff --git a/src/MessageHandler/ProcessWatchlistTriggerHandler.php b/src/MessageHandler/ProcessAllWatchlistHandler.php similarity index 71% rename from src/MessageHandler/ProcessWatchlistTriggerHandler.php rename to src/MessageHandler/ProcessAllWatchlistHandler.php index 52010ad..64a96a9 100644 --- a/src/MessageHandler/ProcessWatchlistTriggerHandler.php +++ b/src/MessageHandler/ProcessAllWatchlistHandler.php @@ -3,8 +3,8 @@ namespace App\MessageHandler; use App\Entity\Watchlist; -use App\Message\ProcessWatchlistTrigger; -use App\Message\UpdateDomainsFromWatchlist; +use App\Message\ProcessAllWatchlist; +use App\Message\ProcessWatchlist; use App\Repository\WatchlistRepository; use Random\Randomizer; use Symfony\Component\Messenger\Attribute\AsMessageHandler; @@ -12,7 +12,7 @@ use Symfony\Component\Messenger\Exception\ExceptionInterface; use Symfony\Component\Messenger\MessageBusInterface; #[AsMessageHandler] -final readonly class ProcessWatchlistTriggerHandler +final readonly class ProcessAllWatchlistHandler { public function __construct( private WatchlistRepository $watchlistRepository, @@ -23,11 +23,13 @@ final readonly class ProcessWatchlistTriggerHandler /** * @throws ExceptionInterface */ - public function __invoke(ProcessWatchlistTrigger $message): void + public function __invoke(ProcessAllWatchlist $message): void { /* * We shuffle the watch lists to process them in an order that we consider random. * The shuffling is provided by a high-level API of a CSPRNG number generator. + * + * ProcessAllWatchlist -> ProcessWatchlist -> UpdateDomain -> (DetectDomainChange & OrderDomain) */ $randomizer = new Randomizer(); @@ -35,7 +37,7 @@ final readonly class ProcessWatchlistTriggerHandler /** @var Watchlist $watchlist */ foreach ($watchlists as $watchlist) { - $this->bus->dispatch(new UpdateDomainsFromWatchlist($watchlist->getToken())); + $this->bus->dispatch(new ProcessWatchlist($watchlist->getToken())); } } } diff --git a/src/MessageHandler/UpdateDomainsFromWatchlistHandler.php b/src/MessageHandler/ProcessWatchlistHandler.php similarity index 55% rename from src/MessageHandler/UpdateDomainsFromWatchlistHandler.php rename to src/MessageHandler/ProcessWatchlistHandler.php index c0aa1e8..3a14848 100644 --- a/src/MessageHandler/UpdateDomainsFromWatchlistHandler.php +++ b/src/MessageHandler/ProcessWatchlistHandler.php @@ -4,53 +4,36 @@ namespace App\MessageHandler; use App\Entity\Domain; use App\Entity\Watchlist; -use App\Exception\DomainNotFoundException; -use App\Exception\TldNotSupportedException; -use App\Exception\UnknownRdapServerException; use App\Message\OrderDomain; -use App\Message\SendDomainEventNotif; -use App\Message\UpdateDomainsFromWatchlist; -use App\Notifier\DomainDeletedNotification; -use App\Repository\DomainRepository; +use App\Message\ProcessWatchlist; +use App\Message\UpdateDomain; use App\Repository\WatchlistRepository; -use App\Service\ChatNotificationService; use App\Service\Provider\AbstractProvider; use App\Service\Provider\CheckDomainProviderInterface; use App\Service\RDAPService; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\MessageBusInterface; -use Symfony\Component\Mime\Address; -use Symfony\Component\Notifier\Recipient\Recipient; #[AsMessageHandler] -final readonly class UpdateDomainsFromWatchlistHandler +final readonly class ProcessWatchlistHandler { - private Address $sender; - public function __construct( private RDAPService $RDAPService, - private ChatNotificationService $chatNotificationService, - private MailerInterface $mailer, - string $mailerSenderEmail, - string $mailerSenderName, private MessageBusInterface $bus, private WatchlistRepository $watchlistRepository, private LoggerInterface $logger, #[Autowire(service: 'service_container')] private ContainerInterface $locator, - private DomainRepository $domainRepository, ) { - $this->sender = new Address($mailerSenderEmail, $mailerSenderName); } /** * @throws \Throwable */ - public function __invoke(UpdateDomainsFromWatchlist $message): void + public function __invoke(ProcessWatchlist $message): void { /** @var Watchlist $watchlist */ $watchlist = $this->watchlistRepository->findOneBy(['token' => $message->watchlistToken]); @@ -98,37 +81,7 @@ final readonly class UpdateDomainsFromWatchlistHandler /** @var Domain $domain */ foreach ($watchlist->getDomains()->filter(fn ($domain) => $this->RDAPService->isToBeUpdated($domain, false, null !== $watchlist->getConnector())) as $domain ) { - $updatedAt = $domain->getUpdatedAt(); - $deleted = $domain->getDeleted(); - - try { - /* - * Domain name update - * We send messages that correspond to the sending of notifications that will not be processed here. - */ - $this->RDAPService->registerDomain($domain->getLdhName()); - $this->bus->dispatch(new SendDomainEventNotif($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); - } catch (DomainNotFoundException) { - $newDomain = $this->domainRepository->findOneBy(['ldhName' => $domain->getLdhName()]); - - if (!$deleted && null !== $newDomain && $newDomain->getDeleted()) { - $notification = new DomainDeletedNotification($this->sender, $domain); - $this->mailer->send($notification->asEmailMessage(new Recipient($watchlist->getUser()->getEmail()))->getMessage()); - $this->chatNotificationService->sendChatNotification($watchlist, $notification); - } - - if ($watchlist->getConnector()) { - /* - * If the domain name no longer appears in the WHOIS AND a connector is associated with this Watchlist, - * this connector is used to purchase the domain name. - */ - $this->bus->dispatch(new OrderDomain($watchlist->getToken(), $domain->getLdhName())); - } - } catch (TldNotSupportedException|UnknownRdapServerException) { - /* - * In this case, the domain name can no longer be updated. Unfortunately, there is nothing more that can be done. - */ - } + $this->bus->dispatch(new UpdateDomain($domain->getLdhName(), $watchlist->getToken())); } } diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php new file mode 100644 index 0000000..720a4be --- /dev/null +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -0,0 +1,127 @@ +sender = new Address($mailerSenderEmail, $mailerSenderName); + } + + /** + * @throws TransportExceptionInterface + * @throws \Symfony\Component\Notifier\Exception\TransportExceptionInterface + * @throws RedirectionExceptionInterface + * @throws DecodingExceptionInterface + * @throws ClientExceptionInterface + * @throws OptimisticLockException + * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface + * @throws UnsupportedDsnSchemeException + * @throws ServerExceptionInterface + * @throws MalformedDomainException + * @throws ExceptionInterface + */ + public function __invoke(UpdateDomain $message): void + { + $domain = $this->domainRepository->findOneBy(['ldhName' => $message->ldhName]); + /** @var ?RdapServer $rdapServer */ + $rdapServer = $domain->getTld()->getRdapServers()->first(); + if (null === $rdapServer) { + $this->logger->warning('No RDAP server for this domain name', [ + 'ldhName' => $domain->getLdhName(), + ]); + + return; + } + $limiter = $this->rdapRequestsLimiter->create($rdapServer->getUrl()); + $limit = $limiter->consume(); + + if (!$limit->isAccepted()) { + $retryAfter = $limit->getRetryAfter()->getTimestamp() - time(); + + $this->logger->warning('Security rate limit reached for this RDAP server', [ + 'url' => $rdapServer->getUrl(), + 'retryAfter' => $retryAfter, + ]); + + throw new RecoverableMessageHandlingException('Rate limit reached', 0, null, $retryAfter); + } + + $watchlist = $this->watchlistRepository->findOneBy(['token' => $message->watchlistToken]); + + $updatedAt = $domain->getUpdatedAt(); + $deleted = $domain->getDeleted(); + + try { + /* + * Domain name update + * We send messages that correspond to the sending of notifications that will not be processed here. + */ + $this->RDAPService->registerDomain($domain->getLdhName()); + $this->bus->dispatch(new DetectDomainChange($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); + } catch (DomainNotFoundException) { + $newDomain = $this->domainRepository->findOneBy(['ldhName' => $domain->getLdhName()]); + + if (!$deleted && null !== $newDomain && $newDomain->getDeleted()) { + $notification = new DomainDeletedNotification($this->sender, $domain); + $this->mailer->send($notification->asEmailMessage(new Recipient($watchlist->getUser()->getEmail()))->getMessage()); + $this->chatNotificationService->sendChatNotification($watchlist, $notification); + } + + if ($watchlist->getConnector()) { + /* + * If the domain name no longer appears in the WHOIS AND a connector is associated with this Watchlist, + * this connector is used to purchase the domain name. + */ + $this->bus->dispatch(new OrderDomain($watchlist->getToken(), $domain->getLdhName())); + } + } catch (TldNotSupportedException|UnknownRdapServerException) { + /* + * In this case, the domain name can no longer be updated. Unfortunately, there is nothing more that can be done. + */ + } + } +} diff --git a/src/Scheduler/SendNotifWatchlistTriggerSchedule.php b/src/Scheduler/ProcessWatchlistSchedule.php similarity index 76% rename from src/Scheduler/SendNotifWatchlistTriggerSchedule.php rename to src/Scheduler/ProcessWatchlistSchedule.php index bad174e..0487f5c 100644 --- a/src/Scheduler/SendNotifWatchlistTriggerSchedule.php +++ b/src/Scheduler/ProcessWatchlistSchedule.php @@ -2,15 +2,15 @@ namespace App\Scheduler; -use App\Message\ProcessWatchlistTrigger; +use App\Message\ProcessAllWatchlist; use Symfony\Component\Scheduler\Attribute\AsSchedule; use Symfony\Component\Scheduler\RecurringMessage; use Symfony\Component\Scheduler\Schedule; use Symfony\Component\Scheduler\ScheduleProviderInterface; use Symfony\Contracts\Cache\CacheInterface; -#[AsSchedule('notif_watchlist')] -final readonly class SendNotifWatchlistTriggerSchedule implements ScheduleProviderInterface +#[AsSchedule('process_watchlist')] +final readonly class ProcessWatchlistSchedule implements ScheduleProviderInterface { public function __construct( private CacheInterface $cache, @@ -21,7 +21,7 @@ final readonly class SendNotifWatchlistTriggerSchedule implements ScheduleProvid { return (new Schedule()) ->add( - RecurringMessage::every('5 minutes', new ProcessWatchlistTrigger()), + RecurringMessage::every('5 minutes', new ProcessAllWatchlist()), ) ->stateful($this->cache); } diff --git a/src/State/AutoRegisterDomainProvider.php b/src/State/AutoRegisterDomainProvider.php index e640526..6089563 100644 --- a/src/State/AutoRegisterDomainProvider.php +++ b/src/State/AutoRegisterDomainProvider.php @@ -10,7 +10,7 @@ use App\Exception\DomainNotFoundException; use App\Exception\MalformedDomainException; use App\Exception\TldNotSupportedException; use App\Exception\UnknownRdapServerException; -use App\Message\SendDomainEventNotif; +use App\Message\DetectDomainChange; use App\Repository\DomainRepository; use App\Service\RDAPService; use Doctrine\ORM\EntityManagerInterface; @@ -37,7 +37,7 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface private RDAPService $RDAPService, private KernelInterface $kernel, private ParameterBagInterface $parameterBag, - private RateLimiterFactory $rdapRequestsLimiter, + private RateLimiterFactory $userRdapRequestsLimiter, private Security $security, private LoggerInterface $logger, private DomainRepository $domainRepository, @@ -92,7 +92,7 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface } if (false === $this->kernel->isDebug() && true === $this->parameterBag->get('limited_features')) { - $limiter = $this->rdapRequestsLimiter->create($userId); + $limiter = $this->userRdapRequestsLimiter->create($userId); $limit = $limiter->consume(); if (!$limit->isAccepted()) { @@ -131,7 +131,7 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface /** @var Watchlist $watchlist */ foreach ($watchlists as $watchlist) { - $this->bus->dispatch(new SendDomainEventNotif($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); + $this->bus->dispatch(new DetectDomainChange($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); } return $domain; diff --git a/tests/MessageHandler/ProcessWatchlistTriggerHandlerTest.php b/tests/MessageHandler/ProcessWatchlistTriggerHandlerTest.php index 91d45cb..341becd 100644 --- a/tests/MessageHandler/ProcessWatchlistTriggerHandlerTest.php +++ b/tests/MessageHandler/ProcessWatchlistTriggerHandlerTest.php @@ -2,9 +2,9 @@ namespace App\Tests\MessageHandler; -use App\Message\ProcessWatchlistTrigger; -use App\Message\UpdateDomainsFromWatchlist; -use App\MessageHandler\ProcessWatchlistTriggerHandler; +use App\Message\ProcessAllWatchlist; +use App\Message\ProcessWatchlist; +use App\MessageHandler\ProcessAllWatchlistHandler; use App\Tests\State\WatchlistUpdateProcessorTest; use PHPUnit\Framework\Attributes\DependsExternal; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; @@ -16,16 +16,16 @@ final class ProcessWatchlistTriggerHandlerTest extends KernelTestCase public function testSendMessage() { $container = self::getContainer(); - $handler = $container->get(ProcessWatchlistTriggerHandler::class); + $handler = $container->get(ProcessAllWatchlistHandler::class); /** @var TraceableMessageBus $bus */ $bus = $container->get('messenger.bus.default'); $bus->reset(); - $handler(new ProcessWatchlistTrigger()); + $handler(new ProcessAllWatchlist()); $dispatched = $bus->getDispatchedMessages(); $this->assertNotEmpty($dispatched); - $this->assertInstanceOf(UpdateDomainsFromWatchlist::class, $dispatched[0]['message']); + $this->assertInstanceOf(ProcessWatchlist::class, $dispatched[0]['message']); } } diff --git a/tests/MessageHandler/UpdateDomainsFromWatchlistHandlerTest.php b/tests/MessageHandler/UpdateDomainsFromWatchlistHandlerTest.php index 3a345db..7c3a7be 100644 --- a/tests/MessageHandler/UpdateDomainsFromWatchlistHandlerTest.php +++ b/tests/MessageHandler/UpdateDomainsFromWatchlistHandlerTest.php @@ -4,8 +4,8 @@ namespace App\Tests\MessageHandler; use App\Entity\Domain; use App\Entity\Watchlist; -use App\Message\UpdateDomainsFromWatchlist; -use App\MessageHandler\UpdateDomainsFromWatchlistHandler; +use App\Message\ProcessWatchlist; +use App\MessageHandler\ProcessWatchlistHandler; use App\Tests\State\WatchlistUpdateProcessorTest; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\Attributes\DependsExternal; @@ -20,7 +20,7 @@ final class UpdateDomainsFromWatchlistHandlerTest extends KernelTestCase { $container = self::getContainer(); $entityManager = $container->get(EntityManagerInterface::class); - $handler = $container->get(UpdateDomainsFromWatchlistHandler::class); + $handler = $container->get(ProcessWatchlistHandler::class); $bus = $container->get('messenger.bus.default'); $deletedDomainLdhName = new UuidV4().'.com'; @@ -40,7 +40,7 @@ final class UpdateDomainsFromWatchlistHandlerTest extends KernelTestCase /* @var TraceableMessageBus $bus */ $bus->reset(); - $handler(new UpdateDomainsFromWatchlist($watchlist->getToken())); + $handler(new ProcessWatchlist($watchlist->getToken())); $this->expectNotToPerformAssertions(); } From 4c1d0f731bd453e8e3e32e349157d5dc3b75c101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Tue, 28 Oct 2025 12:11:11 +0100 Subject: [PATCH 002/131] fix: correct transport for UpdateDomain --- config/packages/messenger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 17ffa87..7ba03ff 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -36,7 +36,7 @@ framework: App\Message\ProcessWatchlist: async App\Message\UpdateRdapServers: async App\Message\ValidateConnectorCredentials: async - App\Message\UpdateDomain: async + App\Message\UpdateDomain: rdap_async # Route your messages to the transports # 'App\Message\YourMessage': async From 6256ed8604ff749e2cf6bc1ee236784e4fd1fe8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Tue, 28 Oct 2025 13:08:16 +0100 Subject: [PATCH 003/131] refactor: remove rate limiter and use retry strategy --- config/packages/messenger.yaml | 6 +--- config/packages/rate_limiter.yaml | 5 --- .../ProcessWatchlistHandler.php | 3 +- src/MessageHandler/UpdateDomainHandler.php | 33 +++++++++---------- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 7ba03ff..15ccfa9 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -14,8 +14,7 @@ framework: retry_strategy: delay: 1000 multiplier: 2 - max_retries: 10 - max_delay: 10000 + max_delay: 86400000 failed: 'doctrine://default?queue_name=failed' # sync: 'sync://' @@ -37,6 +36,3 @@ framework: App\Message\UpdateRdapServers: async App\Message\ValidateConnectorCredentials: async App\Message\UpdateDomain: rdap_async - - # Route your messages to the transports - # 'App\Message\YourMessage': async diff --git a/config/packages/rate_limiter.yaml b/config/packages/rate_limiter.yaml index b93e8c5..6c0af89 100644 --- a/config/packages/rate_limiter.yaml +++ b/config/packages/rate_limiter.yaml @@ -24,8 +24,3 @@ framework: policy: sliding_window limit: 10 interval: '1 hour' - - rdap_requests: - policy: sliding_window - limit: 2 - interval: '1 second' diff --git a/src/MessageHandler/ProcessWatchlistHandler.php b/src/MessageHandler/ProcessWatchlistHandler.php index 3a14848..0af5c26 100644 --- a/src/MessageHandler/ProcessWatchlistHandler.php +++ b/src/MessageHandler/ProcessWatchlistHandler.php @@ -79,8 +79,7 @@ final readonly class ProcessWatchlistHandler */ /** @var Domain $domain */ - foreach ($watchlist->getDomains()->filter(fn ($domain) => $this->RDAPService->isToBeUpdated($domain, false, null !== $watchlist->getConnector())) as $domain - ) { + foreach ($watchlist->getDomains()->filter(fn ($domain) => $this->RDAPService->isToBeUpdated($domain, false, null !== $watchlist->getConnector())) as $domain) { $this->bus->dispatch(new UpdateDomain($domain->getLdhName(), $watchlist->getToken())); } } diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php index 720a4be..2aef5eb 100644 --- a/src/MessageHandler/UpdateDomainHandler.php +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -3,6 +3,7 @@ namespace App\MessageHandler; use App\Entity\RdapServer; +use App\Entity\Watchlist; use App\Exception\DomainNotFoundException; use App\Exception\MalformedDomainException; use App\Exception\TldNotSupportedException; @@ -22,11 +23,9 @@ use Symfony\Component\Mailer\Exception\TransportExceptionInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\Exception\ExceptionInterface; -use Symfony\Component\Messenger\Exception\RecoverableMessageHandlingException; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Mime\Address; use Symfony\Component\Notifier\Recipient\Recipient; -use Symfony\Component\RateLimiter\RateLimiterFactory; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; @@ -46,7 +45,7 @@ final readonly class UpdateDomainHandler private MessageBusInterface $bus, private WatchlistRepository $watchlistRepository, private DomainRepository $domainRepository, - private RateLimiterFactory $rdapRequestsLimiter, private LoggerInterface $logger, + private LoggerInterface $logger, ) { $this->sender = new Address($mailerSenderEmail, $mailerSenderName); } @@ -63,6 +62,7 @@ final readonly class UpdateDomainHandler * @throws ServerExceptionInterface * @throws MalformedDomainException * @throws ExceptionInterface + * @throws \Exception */ public function __invoke(UpdateDomain $message): void { @@ -76,22 +76,17 @@ final readonly class UpdateDomainHandler return; } - $limiter = $this->rdapRequestsLimiter->create($rdapServer->getUrl()); - $limit = $limiter->consume(); - - if (!$limit->isAccepted()) { - $retryAfter = $limit->getRetryAfter()->getTimestamp() - time(); - - $this->logger->warning('Security rate limit reached for this RDAP server', [ - 'url' => $rdapServer->getUrl(), - 'retryAfter' => $retryAfter, - ]); - - throw new RecoverableMessageHandlingException('Rate limit reached', 0, null, $retryAfter); - } $watchlist = $this->watchlistRepository->findOneBy(['token' => $message->watchlistToken]); + if (!$this->RDAPService->isToBeUpdated($domain, false, null !== $watchlist->getConnector())) { + $this->logger->debug('The domain name is already present in the database and does not need to be updated at this time', [ + 'ldhName' => $domain->getLdhName(), + ]); + + return; + } + $updatedAt = $domain->getUpdatedAt(); $deleted = $domain->getDeleted(); @@ -101,7 +96,6 @@ final readonly class UpdateDomainHandler * We send messages that correspond to the sending of notifications that will not be processed here. */ $this->RDAPService->registerDomain($domain->getLdhName()); - $this->bus->dispatch(new DetectDomainChange($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); } catch (DomainNotFoundException) { $newDomain = $this->domainRepository->findOneBy(['ldhName' => $domain->getLdhName()]); @@ -123,5 +117,10 @@ final readonly class UpdateDomainHandler * In this case, the domain name can no longer be updated. Unfortunately, there is nothing more that can be done. */ } + + /** @var Watchlist $wl */ + foreach ($domain->getWatchlists()->getIterator() as $wl) { + $this->bus->dispatch(new DetectDomainChange($wl->getToken(), $domain->getLdhName(), $updatedAt)); + } } } From fb726ac88aa29f384ce03ac09120d09372521bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Tue, 28 Oct 2025 13:24:16 +0100 Subject: [PATCH 004/131] fix: dispatch DetectDomainChange if registerDomain is successful --- src/MessageHandler/UpdateDomainHandler.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php index 2aef5eb..81a2eac 100644 --- a/src/MessageHandler/UpdateDomainHandler.php +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -96,6 +96,11 @@ final readonly class UpdateDomainHandler * We send messages that correspond to the sending of notifications that will not be processed here. */ $this->RDAPService->registerDomain($domain->getLdhName()); + + /** @var Watchlist $wl */ + foreach ($domain->getWatchlists()->getIterator() as $wl) { + $this->bus->dispatch(new DetectDomainChange($wl->getToken(), $domain->getLdhName(), $updatedAt)); + } } catch (DomainNotFoundException) { $newDomain = $this->domainRepository->findOneBy(['ldhName' => $domain->getLdhName()]); @@ -117,10 +122,5 @@ final readonly class UpdateDomainHandler * In this case, the domain name can no longer be updated. Unfortunately, there is nothing more that can be done. */ } - - /** @var Watchlist $wl */ - foreach ($domain->getWatchlists()->getIterator() as $wl) { - $this->bus->dispatch(new DetectDomainChange($wl->getToken(), $domain->getLdhName(), $updatedAt)); - } } } From 1cbf334c237c9e515fd57b469aa185f62b9f4777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Tue, 28 Oct 2025 13:54:07 +0100 Subject: [PATCH 005/131] fix: add expiresInDays in domain response --- src/State/AutoRegisterDomainProvider.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/State/AutoRegisterDomainProvider.php b/src/State/AutoRegisterDomainProvider.php index 6089563..5387160 100644 --- a/src/State/AutoRegisterDomainProvider.php +++ b/src/State/AutoRegisterDomainProvider.php @@ -88,7 +88,7 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface 'updatedAt' => $domain->getUpdatedAt()->format(\DateTimeInterface::ATOM), ]); - return $domain; + return $domain->setExpiresInDays($this->RDAPService->getExpiresInDays($domain)); } if (false === $this->kernel->isDebug() && true === $this->parameterBag->get('limited_features')) { @@ -111,7 +111,7 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface $domain = $this->domainRepository->findOneBy(['ldhName' => $idnDomain]); if (null !== $domain) { - return $domain; + return $domain->setExpiresInDays($this->RDAPService->getExpiresInDays($domain)); } $domain = (new Domain()) @@ -123,7 +123,7 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface $this->em->persist($domain); $this->em->flush(); - return $domain; + return $domain->setExpiresInDays($this->RDAPService->getExpiresInDays($domain)); } $randomizer = new Randomizer(); @@ -134,6 +134,6 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface $this->bus->dispatch(new DetectDomainChange($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); } - return $domain; + return $domain->setExpiresInDays($this->RDAPService->getExpiresInDays($domain)); } } From b123d720f03e5f28d5d3a75c94fdde09ceb66fe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 00:04:34 +0100 Subject: [PATCH 006/131] feat: add consumer name in messenger.yaml --- config/packages/messenger.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 15ccfa9..9d3b1ec 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -6,11 +6,15 @@ framework: # https://symfony.com/doc/current/messenger.html#transport-configuration async: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' + options: + consumer: '%env(MESSENGER_CONSUMER_NAME)%' retry_strategy: max_retries: 3 multiplier: 2 rdap_async: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' + options: + consumer: '%env(MESSENGER_CONSUMER_NAME)%' retry_strategy: delay: 1000 multiplier: 2 From fe162ff9634734c5712475247052e32686a854ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 00:17:45 +0100 Subject: [PATCH 007/131] fix: update messenger.yaml --- config/packages/messenger.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 9d3b1ec..8e1bea3 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -7,14 +7,16 @@ framework: async: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: - consumer: '%env(MESSENGER_CONSUMER_NAME)%' + queue_name: messages_async + group: messages_async retry_strategy: max_retries: 3 multiplier: 2 rdap_async: dsn: '%env(MESSENGER_TRANSPORT_DSN)%' options: - consumer: '%env(MESSENGER_CONSUMER_NAME)%' + queue_name: messages_rdap_async + group: messages_rdap_async retry_strategy: delay: 1000 multiplier: 2 From ea5ce96988b4d41de7c74427a89c284a98a3b084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 00:47:59 +0100 Subject: [PATCH 008/131] fix: update messenger.yaml --- .env | 3 ++- config/packages/messenger.yaml | 10 ++-------- docker-compose.yml | 6 ++++-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.env b/.env index 1ad33af..8eb8da3 100644 --- a/.env +++ b/.env @@ -53,7 +53,8 @@ MAILER_DSN=null://null # Choose one of the transports below # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages # MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 +MESSENGER_ASYNC_TRANSPORT_DSN=doctrine://default?auto_setup=0 +MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=doctrine://default?auto_setup=0 ###< symfony/messenger ### diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 8e1bea3..8a14fc0 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -5,18 +5,12 @@ framework: transports: # https://symfony.com/doc/current/messenger.html#transport-configuration async: - dsn: '%env(MESSENGER_TRANSPORT_DSN)%' - options: - queue_name: messages_async - group: messages_async + dsn: '%env(MESSENGER_ASYNC_TRANSPORT_DSN)%' retry_strategy: max_retries: 3 multiplier: 2 rdap_async: - dsn: '%env(MESSENGER_TRANSPORT_DSN)%' - options: - queue_name: messages_rdap_async - group: messages_rdap_async + dsn: '%env(MESSENGER_RDAP_ASYNC_TRANSPORT_DSN)%' retry_strategy: delay: 1000 multiplier: 2 diff --git a/docker-compose.yml b/docker-compose.yml index 56ccc03..c4a36ac 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,8 @@ services: APP_ENV: prod SERVER_NAME: ${SERVER_NAME:-:80} DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} - MESSENGER_TRANSPORT_DSN: redis://valkey:6379/messages + MESSENGER_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages + MESSENGER_RDAP_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages-rdap volumes: - caddy_data:/data - caddy_config:/config @@ -31,7 +32,8 @@ services: environment: APP_ENV: prod DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} - MESSENGER_TRANSPORT_DSN: redis://valkey:6379/messages + MESSENGER_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages + MESSENGER_RDAP_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages-rdap depends_on: - database healthcheck: From ee22b7af2fca1c5f51c6b4173b34d70dd70aa2b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 01:16:14 +0100 Subject: [PATCH 009/131] fix: typed property --- src/Entity/DomainStatus.php | 16 ++++++++-------- src/Service/RDAPService.php | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Entity/DomainStatus.php b/src/Entity/DomainStatus.php index 2e529f5..38deab9 100644 --- a/src/Entity/DomainStatus.php +++ b/src/Entity/DomainStatus.php @@ -21,19 +21,19 @@ class DomainStatus #[ORM\Column] #[Groups(['domain:item'])] - private \DateTimeImmutable $createdAt; + private ?\DateTimeImmutable $createdAt; #[ORM\Column] #[Groups(['domain:item'])] - private \DateTimeImmutable $date; + private ?\DateTimeImmutable $date; #[ORM\Column(type: Types::JSON, nullable: true)] #[Groups(['domain:item'])] - private array $addStatus = []; + private ?array $addStatus = []; #[ORM\Column(type: Types::JSON, nullable: true)] #[Groups(['domain:item'])] - private array $deleteStatus = []; + private ?array $deleteStatus = []; public function __construct() { @@ -82,24 +82,24 @@ class DomainStatus return $this; } - public function getAddStatus(): array + public function getAddStatus(): ?array { return $this->addStatus; } - public function setAddStatus(array $addStatus): static + public function setAddStatus(?array $addStatus): static { $this->addStatus = $addStatus; return $this; } - public function getDeleteStatus(): array + public function getDeleteStatus(): ?array { return $this->deleteStatus; } - public function setDeleteStatus(array $deleteStatus): static + public function setDeleteStatus(?array $deleteStatus): static { $this->deleteStatus = $deleteStatus; diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index 121363c..d77e1fe 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -728,8 +728,8 @@ class RDAPService } if ($domain->isPendingDelete() && ( - in_array('pending delete', $lastStatus->getAddStatus()) - || in_array('redemption period', $lastStatus->getDeleteStatus())) + in_array('pending delete', $lastStatus->getAddStatus() ?? []) + || in_array('redemption period', $lastStatus->getDeleteStatus() ?? [])) ) { return self::daysBetween($now, $lastStatus->getCreatedAt()->add(new \DateInterval('P'. 5 .'D'))); } From 033cd185ba67e038a6b5ab8a683bd8f57bc91dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 01:18:27 +0100 Subject: [PATCH 010/131] fix: typed property --- src/Service/RDAPService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index d77e1fe..3b6cdcd 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -735,7 +735,7 @@ class RDAPService } if ($domain->isRedemptionPeriod() - && in_array('redemption period', $lastStatus->getAddStatus()) + && in_array('redemption period', $lastStatus->getAddStatus() ?? []) ) { return self::daysBetween($now, $lastStatus->getCreatedAt()->add(new \DateInterval('P'.(30 + 5).'D'))); } From 4ea2afa5c3e574af9c1891070a226092b68e8a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 01:26:39 +0100 Subject: [PATCH 011/131] chore: revert changes --- src/Entity/DomainStatus.php | 16 ++++++++-------- src/Service/RDAPService.php | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Entity/DomainStatus.php b/src/Entity/DomainStatus.php index 38deab9..2e529f5 100644 --- a/src/Entity/DomainStatus.php +++ b/src/Entity/DomainStatus.php @@ -21,19 +21,19 @@ class DomainStatus #[ORM\Column] #[Groups(['domain:item'])] - private ?\DateTimeImmutable $createdAt; + private \DateTimeImmutable $createdAt; #[ORM\Column] #[Groups(['domain:item'])] - private ?\DateTimeImmutable $date; + private \DateTimeImmutable $date; #[ORM\Column(type: Types::JSON, nullable: true)] #[Groups(['domain:item'])] - private ?array $addStatus = []; + private array $addStatus = []; #[ORM\Column(type: Types::JSON, nullable: true)] #[Groups(['domain:item'])] - private ?array $deleteStatus = []; + private array $deleteStatus = []; public function __construct() { @@ -82,24 +82,24 @@ class DomainStatus return $this; } - public function getAddStatus(): ?array + public function getAddStatus(): array { return $this->addStatus; } - public function setAddStatus(?array $addStatus): static + public function setAddStatus(array $addStatus): static { $this->addStatus = $addStatus; return $this; } - public function getDeleteStatus(): ?array + public function getDeleteStatus(): array { return $this->deleteStatus; } - public function setDeleteStatus(?array $deleteStatus): static + public function setDeleteStatus(array $deleteStatus): static { $this->deleteStatus = $deleteStatus; diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index 3b6cdcd..121363c 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -728,14 +728,14 @@ class RDAPService } if ($domain->isPendingDelete() && ( - in_array('pending delete', $lastStatus->getAddStatus() ?? []) - || in_array('redemption period', $lastStatus->getDeleteStatus() ?? [])) + in_array('pending delete', $lastStatus->getAddStatus()) + || in_array('redemption period', $lastStatus->getDeleteStatus())) ) { return self::daysBetween($now, $lastStatus->getCreatedAt()->add(new \DateInterval('P'. 5 .'D'))); } if ($domain->isRedemptionPeriod() - && in_array('redemption period', $lastStatus->getAddStatus() ?? []) + && in_array('redemption period', $lastStatus->getAddStatus()) ) { return self::daysBetween($now, $lastStatus->getCreatedAt()->add(new \DateInterval('P'.(30 + 5).'D'))); } From f868f1ad19124ffb95a91fa5ce378b1aa563d9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 10:53:13 +0100 Subject: [PATCH 012/131] chore: change log levels --- src/Service/RDAPService.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index 121363c..a69f1a8 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -345,7 +345,7 @@ class RDAPService if (isset($rdapData['handle'])) { $domain->setHandle($rdapData['handle']); } else { - $this->logger->warning('Domain name has no handle key', [ + $this->logger->debug('Domain name has no handle key', [ 'ldhName' => $domain->getLdhName(), ]); } @@ -443,7 +443,7 @@ class RDAPService } } } else { - $this->logger->warning('Domain name has no nameservers', [ + $this->logger->debug('Domain name has no nameservers', [ 'ldhName' => $domain->getLdhName(), ]); } @@ -537,7 +537,7 @@ class RDAPService sort($roles); $rdapEntity['handle'] = 'DW-FAKEHANDLE-'.$domain.'-'.implode(',', $roles); - $this->logger->warning('Entity has no handle key', [ + $this->logger->debug('Entity has no handle key', [ 'handle' => $rdapEntity['handle'], 'ldhName' => $domain, ]); @@ -712,7 +712,7 @@ class RDAPService $this->em->persist($dsData); } } else { - $this->logger->warning('Domain name has no DS record', [ + $this->logger->info('Domain name has no DS record', [ 'ldhName' => $domain->getLdhName(), ]); } From 32e2d06cf64c00e16ad25358c7f08b8f9c35f320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 11:00:44 +0100 Subject: [PATCH 013/131] chore: change log levels --- src/Service/RDAPService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index a69f1a8..a987844 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -712,7 +712,7 @@ class RDAPService $this->em->persist($dsData); } } else { - $this->logger->info('Domain name has no DS record', [ + $this->logger->debug('Domain name has no DS record', [ 'ldhName' => $domain->getLdhName(), ]); } From 42805813ed49bc90e57aea9203cb8e8f4bacd9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 15:00:08 +0100 Subject: [PATCH 014/131] feat: add app:batch-register-domains command --- src/Command/BatchRegisterDomainCommand.php | 64 ++++++++++++++++++++++ src/Message/UpdateDomain.php | 2 +- src/MessageHandler/UpdateDomainHandler.php | 16 ++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/Command/BatchRegisterDomainCommand.php diff --git a/src/Command/BatchRegisterDomainCommand.php b/src/Command/BatchRegisterDomainCommand.php new file mode 100644 index 0000000..b86a8dd --- /dev/null +++ b/src/Command/BatchRegisterDomainCommand.php @@ -0,0 +1,64 @@ +addArgument('file', InputArgument::REQUIRED, 'Path to a file containing a list of domain names'); + } + + /** + * @throws ExceptionInterface + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $file = $input->getArgument('file'); + + if (!file_exists($file) || !is_readable($file)) { + $io->error(sprintf('File "%s" does not exist or is not readable.', $file)); + + return Command::FAILURE; + } + $domains = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + + if (empty($domains)) { + $io->warning('The list is empty.'); + + return Command::SUCCESS; + } + + $io->title('Registering domains'); + /** @var string $ldhName */ + foreach ($domains as $ldhName) { + $this->messageBus->dispatch(new UpdateDomain($ldhName, null)); + } + + $io->success(sprintf('Imported %d domain names.', count($domains))); + + return Command::SUCCESS; + } +} diff --git a/src/Message/UpdateDomain.php b/src/Message/UpdateDomain.php index 758b1ce..086ecd5 100644 --- a/src/Message/UpdateDomain.php +++ b/src/Message/UpdateDomain.php @@ -9,7 +9,7 @@ final class UpdateDomain { public function __construct( public string $ldhName, - public string $watchlistToken, + public ?string $watchlistToken, ) { } } diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php index 81a2eac..bb12cf1 100644 --- a/src/MessageHandler/UpdateDomainHandler.php +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -67,6 +67,13 @@ final readonly class UpdateDomainHandler public function __invoke(UpdateDomain $message): void { $domain = $this->domainRepository->findOneBy(['ldhName' => $message->ldhName]); + + if (null === $domain) { + $this->RDAPService->registerDomain($message->ldhName); + + return; + } + /** @var ?RdapServer $rdapServer */ $rdapServer = $domain->getTld()->getRdapServers()->first(); if (null === $rdapServer) { @@ -79,6 +86,15 @@ final readonly class UpdateDomainHandler $watchlist = $this->watchlistRepository->findOneBy(['token' => $message->watchlistToken]); + if (null === $watchlist) { + /** @var Watchlist $wl */ + foreach ($domain->getWatchlists()->getIterator() as $wl) { + $this->bus->dispatch(new UpdateDomain($message->ldhName, $wl->getToken())); + } + + return; + } + if (!$this->RDAPService->isToBeUpdated($domain, false, null !== $watchlist->getConnector())) { $this->logger->debug('The domain name is already present in the database and does not need to be updated at this time', [ 'ldhName' => $domain->getLdhName(), From 7595b137724deeefe5778b4913281e4fcfc4da96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 19:18:44 +0100 Subject: [PATCH 015/131] feat: no domain update if < 5 secs --- src/Service/RDAPService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index a987844..655f493 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -803,7 +803,7 @@ class RDAPService $expiresIn = $this->getExpiresInDays($domain); - if ($intensifyLastDay && (0 === $expiresIn || 1 === $expiresIn)) { + if ($updatedAtDiff->s >= 5 && $intensifyLastDay && (0 === $expiresIn || 1 === $expiresIn)) { return true; } From 5e23e5527e30a7522087e6f8a0d0f7299d7ec64f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Wed, 29 Oct 2025 20:11:18 +0100 Subject: [PATCH 016/131] feat: add consumer name --- .env | 2 ++ config/packages/messenger.yaml | 2 ++ docker-compose.yml | 1 + 3 files changed, 5 insertions(+) diff --git a/.env b/.env index 8eb8da3..8486bc4 100644 --- a/.env +++ b/.env @@ -49,6 +49,8 @@ LOCK_DSN=flock MAILER_DSN=null://null ###< symfony/mailer ### +MESSENGER_CONSUMER_NAME=worker + ###> symfony/messenger ### # Choose one of the transports below # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 8a14fc0..bff1748 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -11,6 +11,8 @@ framework: multiplier: 2 rdap_async: dsn: '%env(MESSENGER_RDAP_ASYNC_TRANSPORT_DSN)%' + options: + consumer: '%env(MESSENGER_CONSUMER_NAME)%' retry_strategy: delay: 1000 multiplier: 2 diff --git a/docker-compose.yml b/docker-compose.yml index c4a36ac..32ef3b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,6 +34,7 @@ services: DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} MESSENGER_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages MESSENGER_RDAP_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages-rdap + MESSENGER_CONSUMER_NAME: worker depends_on: - database healthcheck: From d04c1ea48a9884c2e4a2360db8182b9dc0d82577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 30 Oct 2025 11:36:43 +0100 Subject: [PATCH 017/131] feat: use redis as messenger transport --- .env | 4 ++-- .github/workflows/lint-and-tests.yml | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 8486bc4..7659ea7 100644 --- a/.env +++ b/.env @@ -55,8 +55,8 @@ MESSENGER_CONSUMER_NAME=worker # Choose one of the transports below # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages # MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -MESSENGER_ASYNC_TRANSPORT_DSN=doctrine://default?auto_setup=0 -MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=doctrine://default?auto_setup=0 +MESSENGER_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages?lazy=1 +MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages-rdap?lazy=1 ###< symfony/messenger ### diff --git a/.github/workflows/lint-and-tests.yml b/.github/workflows/lint-and-tests.yml index e43e9f4..3df37b2 100644 --- a/.github/workflows/lint-and-tests.yml +++ b/.github/workflows/lint-and-tests.yml @@ -120,6 +120,15 @@ jobs: --health-retries 5 ports: - 5432:5432 + valkey: + image: valkey/valkey:latest + options: >- + --health-cmd "valkey-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 steps: - name: Checkout code uses: actions/checkout@v3 From e0d8bf20ad5788a0c6392abbf4752db9c517eb61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 30 Oct 2025 11:39:36 +0100 Subject: [PATCH 018/131] feat: use redis as messenger transport --- .env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 7659ea7..a03e7b0 100644 --- a/.env +++ b/.env @@ -55,8 +55,8 @@ MESSENGER_CONSUMER_NAME=worker # Choose one of the transports below # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages # MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -MESSENGER_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages?lazy=1 -MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages-rdap?lazy=1 +MESSENGER_ASYNC_TRANSPORT_DSN=redis://valkey:6379/messages?lazy=1 +MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=redis://valkey:6379/messages-rdap?lazy=1 ###< symfony/messenger ### From d7e78a98080fa417854112a99c676043bf0b6e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 30 Oct 2025 11:41:06 +0100 Subject: [PATCH 019/131] Revert "feat: use redis as messenger transport" This reverts commit e0d8bf20ad5788a0c6392abbf4752db9c517eb61. --- .env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index a03e7b0..7659ea7 100644 --- a/.env +++ b/.env @@ -55,8 +55,8 @@ MESSENGER_CONSUMER_NAME=worker # Choose one of the transports below # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages # MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -MESSENGER_ASYNC_TRANSPORT_DSN=redis://valkey:6379/messages?lazy=1 -MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=redis://valkey:6379/messages-rdap?lazy=1 +MESSENGER_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages?lazy=1 +MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages-rdap?lazy=1 ###< symfony/messenger ### From cf1d524225e859544419317d723c555479a8a0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 30 Oct 2025 21:11:33 +0100 Subject: [PATCH 020/131] chore: remove redundant Close button --- .../tracking/watchlist/CreateWatchlistButton.tsx | 1 - .../tracking/watchlist/UpdateWatchlistButton.tsx | 3 +-- translations/translations.pot | 9 ++++----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/assets/components/tracking/watchlist/CreateWatchlistButton.tsx b/assets/components/tracking/watchlist/CreateWatchlistButton.tsx index 13e6863..312616d 100644 --- a/assets/components/tracking/watchlist/CreateWatchlistButton.tsx +++ b/assets/components/tracking/watchlist/CreateWatchlistButton.tsx @@ -42,7 +42,6 @@ export function CreateWatchlistButton({onUpdateWatchlist, connectors}: { paddingBottom: 80 } }} - extra={} > {t`Cancel`}} > Date: Thu, 30 Oct 2025 23:11:03 +0000 Subject: [PATCH 021/131] Update translation files Updated by "Update PO files to match POT (msgmerge)" add-on in Weblate. --- translations/de.po | 9 ++++----- translations/fr.po | 9 ++++----- translations/sv.po | 13 ++++++------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/translations/de.po b/translations/de.po index 467f45b..300c7ba 100644 --- a/translations/de.po +++ b/translations/de.po @@ -389,11 +389,6 @@ msgstr "Ereignisse in das iCalendar-Format exportieren" msgid "Create a Watchlist" msgstr "Erstellen Sie eine Watchlist" -#: assets/components/tracking/watchlist/CreateWatchlistButton.tsx:45 -#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 -msgid "Cancel" -msgstr "Abbrechen" - #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:13 #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:21 msgid "Delete the Watchlist" @@ -515,6 +510,10 @@ msgstr "Bearbeiten der Watchlist" msgid "Update a Watchlist" msgstr "Aktualisieren einer Watchlist" +#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 +msgid "Cancel" +msgstr "Abbrechen" + #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." msgstr "Diese Beobachtungsliste ist nicht mit einem Connector verknüpft." diff --git a/translations/fr.po b/translations/fr.po index c42acb2..3b7b9bd 100644 --- a/translations/fr.po +++ b/translations/fr.po @@ -392,11 +392,6 @@ msgstr "Exporter les événements au format iCalendar" msgid "Create a Watchlist" msgstr "Créer une Watchlist" -#: assets/components/tracking/watchlist/CreateWatchlistButton.tsx:45 -#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 -msgid "Cancel" -msgstr "Annuler" - #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:13 #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:21 msgid "Delete the Watchlist" @@ -518,6 +513,10 @@ msgstr "Modifier la Watchlist" msgid "Update a Watchlist" msgstr "Mise à jour d'une Watchlist" +#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 +msgid "Cancel" +msgstr "Annuler" + #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." msgstr "Cette Watchlist n'est pas liée à un connecteur." diff --git a/translations/sv.po b/translations/sv.po index f0a5e1a..f91fce8 100644 --- a/translations/sv.po +++ b/translations/sv.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "PO-Revision-Date: 2025-10-25 19:52+0000\n" "Last-Translator: Maël Gangloff \n" -"Language-Team: Swedish \n" +"Language-Team: Swedish \n" "Language: sv\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -385,11 +385,6 @@ msgstr "Exportera händelser till iCalendar-format" msgid "Create a Watchlist" msgstr "Skapa en Watchlist" -#: assets/components/tracking/watchlist/CreateWatchlistButton.tsx:45 -#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 -msgid "Cancel" -msgstr "Avboka" - #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:13 #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:21 msgid "Delete the Watchlist" @@ -506,6 +501,10 @@ msgstr "Redigera bevakningslistan" msgid "Update a Watchlist" msgstr "Uppdatera en bevakningslista" +#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 +msgid "Cancel" +msgstr "Avboka" + #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." msgstr "Denna Watchlist är inte kopplad till en Connector." From b420b4e633e8f67dfa2af81a3a0c17c59b327dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 31 Oct 2025 13:40:09 +0100 Subject: [PATCH 022/131] feat: add domain_purchase table --- migrations/Version20251031115210.php | 47 +++++++ src/Entity/Connector.php | 37 +++++ src/Entity/Domain.php | 43 ++++++ src/Entity/DomainPurchase.php | 132 ++++++++++++++++++ src/Entity/User.php | 37 +++++ src/Message/OrderDomain.php | 1 + src/MessageHandler/OrderDomainHandler.php | 24 +++- .../ProcessWatchlistHandler.php | 9 +- src/MessageHandler/UpdateDomainHandler.php | 2 +- src/Repository/DomainPurchaseRepository.php | 43 ++++++ .../Service/Provider/AbstractProviderTest.php | 2 +- 11 files changed, 371 insertions(+), 6 deletions(-) create mode 100644 migrations/Version20251031115210.php create mode 100644 src/Entity/DomainPurchase.php create mode 100644 src/Repository/DomainPurchaseRepository.php diff --git a/migrations/Version20251031115210.php b/migrations/Version20251031115210.php new file mode 100644 index 0000000..cfc0d8e --- /dev/null +++ b/migrations/Version20251031115210.php @@ -0,0 +1,47 @@ +addSql('CREATE TABLE domain_purchase (id UUID NOT NULL, domain_id VARCHAR(255) NOT NULL, connector_id UUID DEFAULT NULL, user_id INT DEFAULT NULL, domain_updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, domain_ordered_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, connector_provider VARCHAR(255) NOT NULL, domain_deleted_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_72999E74115F0EE5 ON domain_purchase (domain_id)'); + $this->addSql('CREATE INDEX IDX_72999E744D085745 ON domain_purchase (connector_id)'); + $this->addSql('CREATE INDEX IDX_72999E74A76ED395 ON domain_purchase (user_id)'); + $this->addSql('COMMENT ON COLUMN domain_purchase.id IS \'(DC2Type:uuid)\''); + $this->addSql('COMMENT ON COLUMN domain_purchase.connector_id IS \'(DC2Type:uuid)\''); + $this->addSql('COMMENT ON COLUMN domain_purchase.domain_updated_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN domain_purchase.domain_ordered_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN domain_purchase.domain_deleted_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT FK_72999E74115F0EE5 FOREIGN KEY (domain_id) REFERENCES domain (ldh_name) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT FK_72999E744D085745 FOREIGN KEY (connector_id) REFERENCES connector (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT FK_72999E74A76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE watchlist ALTER enabled DROP DEFAULT'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT FK_72999E74115F0EE5'); + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT FK_72999E744D085745'); + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT FK_72999E74A76ED395'); + $this->addSql('DROP TABLE domain_purchase'); + $this->addSql('ALTER TABLE watchlist ALTER enabled SET DEFAULT true'); + } +} diff --git a/src/Entity/Connector.php b/src/Entity/Connector.php index e4b1740..9aae2a1 100644 --- a/src/Entity/Connector.php +++ b/src/Entity/Connector.php @@ -73,10 +73,17 @@ class Connector #[Groups(['connector:list'])] protected int $watchlistCount; + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: DomainPurchase::class, mappedBy: 'connector')] + private Collection $domainPurchases; + public function __construct() { $this->id = Uuid::v4(); $this->watchlists = new ArrayCollection(); + $this->domainPurchases = new ArrayCollection(); } public function getId(): ?string @@ -166,4 +173,34 @@ class Connector { return $this->watchlists->count(); } + + /** + * @return Collection + */ + public function getDomainPurchases(): Collection + { + return $this->domainPurchases; + } + + public function addDomainPurchase(DomainPurchase $domainPurchase): static + { + if (!$this->domainPurchases->contains($domainPurchase)) { + $this->domainPurchases->add($domainPurchase); + $domainPurchase->setConnector($this); + } + + return $this; + } + + public function removeDomainPurchase(DomainPurchase $domainPurchase): static + { + if ($this->domainPurchases->removeElement($domainPurchase)) { + // set the owning side to null (unless already changed) + if ($domainPurchase->getConnector() === $this) { + $domainPurchase->setConnector(null); + } + } + + return $this; + } } diff --git a/src/Entity/Domain.php b/src/Entity/Domain.php index 819fe6c..8e616a8 100644 --- a/src/Entity/Domain.php +++ b/src/Entity/Domain.php @@ -156,6 +156,12 @@ class Domain private ?int $expiresInDays; + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: DomainPurchase::class, mappedBy: 'domain', orphanRemoval: true)] + private Collection $domainPurchases; + private const IMPORTANT_EVENTS = [EventAction::Deletion->value, EventAction::Expiration->value]; private const IMPORTANT_STATUS = [ 'redemption period', @@ -179,6 +185,7 @@ class Domain $this->deleted = false; $this->domainStatuses = new ArrayCollection(); $this->dnsKey = new ArrayCollection(); + $this->domainPurchases = new ArrayCollection(); } public function getLdhName(): ?string @@ -516,4 +523,40 @@ class Domain return $this; } + + /** + * @return Collection + */ + public function getDomainPurchases(): Collection + { + return $this->domainPurchases; + } + + public function addDomainPurchase(DomainPurchase $domainPurchase): static + { + if (!$this->domainPurchases->contains($domainPurchase)) { + $this->domainPurchases->add($domainPurchase); + $domainPurchase->setDomain($this); + } + + return $this; + } + + public function removeDomainPurchase(DomainPurchase $domainPurchase): static + { + if ($this->domainPurchases->removeElement($domainPurchase)) { + // set the owning side to null (unless already changed) + if ($domainPurchase->getDomain() === $this) { + $domainPurchase->setDomain(null); + } + } + + return $this; + } + + #[Groups(['domain:item', 'domain:list'])] + public function getPurchaseCount(): ?int + { + return $this->domainPurchases->count(); + } } diff --git a/src/Entity/DomainPurchase.php b/src/Entity/DomainPurchase.php new file mode 100644 index 0000000..3d6c1c6 --- /dev/null +++ b/src/Entity/DomainPurchase.php @@ -0,0 +1,132 @@ +id = Uuid::v4(); + } + + public function getId(): ?string + { + return $this->id; + } + + public function getDomain(): ?Domain + { + return $this->domain; + } + + public function setDomain(?Domain $domain): static + { + $this->domain = $domain; + + return $this; + } + + public function getDomainUpdatedAt(): ?\DateTimeImmutable + { + return $this->domainUpdatedAt; + } + + public function setDomainUpdatedAt(\DateTimeImmutable $domainUpdatedAt): static + { + $this->domainUpdatedAt = $domainUpdatedAt; + + return $this; + } + + public function getDomainOrderedAt(): ?\DateTimeImmutable + { + return $this->domainOrderedAt; + } + + public function setDomainOrderedAt(?\DateTimeImmutable $domainOrderedAt): static + { + $this->domainOrderedAt = $domainOrderedAt; + + return $this; + } + + public function getConnectorProvider(): ?ConnectorProvider + { + return $this->connectorProvider; + } + + public function setConnectorProvider(ConnectorProvider $connectorProvider): static + { + $this->connectorProvider = $connectorProvider; + + return $this; + } + + public function getConnector(): ?Connector + { + return $this->connector; + } + + public function setConnector(?Connector $connector): static + { + $this->connector = $connector; + + return $this; + } + + public function getUser(): ?User + { + return $this->user; + } + + public function setUser(?User $user): static + { + $this->user = $user; + + return $this; + } + + public function getDomainDeletedAt(): ?\DateTimeImmutable + { + return $this->domainDeletedAt; + } + + public function setDomainDeletedAt(\DateTimeImmutable $domainDeletedAt): static + { + $this->domainDeletedAt = $domainDeletedAt; + + return $this; + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 29fa9f5..e788ef9 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -89,10 +89,17 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[Groups(['user:register'])] private ?string $plainPassword = null; + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: DomainPurchase::class, mappedBy: 'user')] + private Collection $domainPurchases; + public function __construct() { $this->watchlists = new ArrayCollection(); $this->connectors = new ArrayCollection(); + $this->domainPurchases = new ArrayCollection(); } public function getId(): ?int @@ -262,4 +269,34 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface return $this; } + + /** + * @return Collection + */ + public function getDomainPurchases(): Collection + { + return $this->domainPurchases; + } + + public function addDomainPurchase(DomainPurchase $domainPurchase): static + { + if (!$this->domainPurchases->contains($domainPurchase)) { + $this->domainPurchases->add($domainPurchase); + $domainPurchase->setUser($this); + } + + return $this; + } + + public function removeDomainPurchase(DomainPurchase $domainPurchase): static + { + if ($this->domainPurchases->removeElement($domainPurchase)) { + // set the owning side to null (unless already changed) + if ($domainPurchase->getUser() === $this) { + $domainPurchase->setUser(null); + } + } + + return $this; + } } diff --git a/src/Message/OrderDomain.php b/src/Message/OrderDomain.php index 61ec9ad..6d51d05 100644 --- a/src/Message/OrderDomain.php +++ b/src/Message/OrderDomain.php @@ -7,6 +7,7 @@ final class OrderDomain public function __construct( public string $watchlistToken, public string $ldhName, + public \DateTimeImmutable $updatedAt, ) { } } diff --git a/src/MessageHandler/OrderDomainHandler.php b/src/MessageHandler/OrderDomainHandler.php index 72c6fd3..6f0c7c1 100644 --- a/src/MessageHandler/OrderDomainHandler.php +++ b/src/MessageHandler/OrderDomainHandler.php @@ -3,6 +3,7 @@ namespace App\MessageHandler; use App\Entity\Domain; +use App\Entity\DomainPurchase; use App\Entity\Watchlist; use App\Message\OrderDomain; use App\Notifier\DomainOrderErrorNotification; @@ -13,6 +14,7 @@ use App\Service\ChatNotificationService; use App\Service\InfluxdbService; use App\Service\Provider\AbstractProvider; use App\Service\StatService; +use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -42,7 +44,7 @@ final readonly class OrderDomainHandler #[Autowire(service: 'service_container')] private ContainerInterface $locator, #[Autowire(param: 'influxdb_enabled')] - private bool $influxdbEnabled, + private bool $influxdbEnabled, private EntityManagerInterface $em, ) { $this->sender = new Address($mailerSenderEmail, $mailerSenderName); } @@ -114,6 +116,16 @@ final readonly class OrderDomainHandler $notification = (new DomainOrderNotification($this->sender, $domain, $connector)); $this->mailer->send($notification->asEmailMessage(new Recipient($watchlist->getUser()->getEmail()))->getMessage()); $this->chatNotificationService->sendChatNotification($watchlist, $notification); + + $this->em->persist((new DomainPurchase()) + ->setDomain($domain) + ->setConnector($connector) + ->setConnectorProvider($connector->getProvider()) + ->setDomainOrderedAt(new \DateTimeImmutable()) + ->setUser($watchlist->getUser()) + ->setDomainDeletedAt($domain->getUpdatedAt()) + ->setDomainUpdatedAt($message->updatedAt)); + $this->em->flush(); } catch (\Throwable $exception) { /* * The purchase was not successful (for several possible reasons that we have not determined). @@ -134,6 +146,16 @@ final readonly class OrderDomainHandler $this->mailer->send($notification->asEmailMessage(new Recipient($watchlist->getUser()->getEmail()))->getMessage()); $this->chatNotificationService->sendChatNotification($watchlist, $notification); + $this->em->persist((new DomainPurchase()) + ->setDomain($domain) + ->setConnector($connector) + ->setConnectorProvider($connector->getProvider()) + ->setDomainOrderedAt(null) + ->setUser($watchlist->getUser()) + ->setDomainDeletedAt($domain->getUpdatedAt()) + ->setDomainUpdatedAt($message->updatedAt)); + $this->em->flush(); + throw $exception; } } diff --git a/src/MessageHandler/ProcessWatchlistHandler.php b/src/MessageHandler/ProcessWatchlistHandler.php index 0af5c26..c2ef749 100644 --- a/src/MessageHandler/ProcessWatchlistHandler.php +++ b/src/MessageHandler/ProcessWatchlistHandler.php @@ -7,6 +7,7 @@ use App\Entity\Watchlist; use App\Message\OrderDomain; use App\Message\ProcessWatchlist; use App\Message\UpdateDomain; +use App\Repository\DomainRepository; use App\Repository\WatchlistRepository; use App\Service\Provider\AbstractProvider; use App\Service\Provider\CheckDomainProviderInterface; @@ -26,7 +27,7 @@ final readonly class ProcessWatchlistHandler private WatchlistRepository $watchlistRepository, private LoggerInterface $logger, #[Autowire(service: 'service_container')] - private ContainerInterface $locator, + private ContainerInterface $locator, private DomainRepository $domainRepository, ) { } @@ -64,8 +65,10 @@ final readonly class ProcessWatchlistHandler throw $exception; } - foreach ($checkedDomains as $domain) { - $this->bus->dispatch(new OrderDomain($watchlist->getToken(), $domain)); + /** @var string $ldhName */ + foreach ($checkedDomains as $ldhName) { + $domain = $this->domainRepository->findOneBy(['ldhName' => $ldhName]); + $this->bus->dispatch(new OrderDomain($watchlist->getToken(), $domain->getLdhName(), $domain->getUpdatedAt())); } return; diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php index bb12cf1..232c3c2 100644 --- a/src/MessageHandler/UpdateDomainHandler.php +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -131,7 +131,7 @@ final readonly class UpdateDomainHandler * If the domain name no longer appears in the WHOIS AND a connector is associated with this Watchlist, * this connector is used to purchase the domain name. */ - $this->bus->dispatch(new OrderDomain($watchlist->getToken(), $domain->getLdhName())); + $this->bus->dispatch(new OrderDomain($watchlist->getToken(), $domain->getLdhName(), $updatedAt)); } } catch (TldNotSupportedException|UnknownRdapServerException) { /* diff --git a/src/Repository/DomainPurchaseRepository.php b/src/Repository/DomainPurchaseRepository.php new file mode 100644 index 0000000..3772893 --- /dev/null +++ b/src/Repository/DomainPurchaseRepository.php @@ -0,0 +1,43 @@ + + */ +class DomainPurchaseRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, DomainPurchase::class); + } + + // /** + // * @return DomainPurchase[] Returns an array of DomainPurchase objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('d') + // ->andWhere('d.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('d.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?DomainPurchase + // { + // return $this->createQueryBuilder('d') + // ->andWhere('d.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/tests/Service/Provider/AbstractProviderTest.php b/tests/Service/Provider/AbstractProviderTest.php index 713d7ac..05c2aef 100644 --- a/tests/Service/Provider/AbstractProviderTest.php +++ b/tests/Service/Provider/AbstractProviderTest.php @@ -109,7 +109,7 @@ class AbstractProviderTest extends ApiTestCase // Trigger the Order Domain message $orderDomainHandler = self::getContainer()->get(OrderDomainHandler::class); - $message = new OrderDomain($watchlist->getToken(), $domain->getLdhName()); + $message = new OrderDomain($watchlist->getToken(), $domain->getLdhName(), $domain->getUpdatedAt()); $orderDomainHandler($message); $this->assertResponseStatusCodeSame(200); From c0b5c6766ebdb4b3b514fa34756031a67dedda35 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 31 Oct 2025 13:46:17 +0100 Subject: [PATCH 023/131] fix: responsive login page --- assets/components/LoginForm.tsx | 13 ++++------ assets/pages/LoginPage.tsx | 42 ++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/assets/components/LoginForm.tsx b/assets/components/LoginForm.tsx index c0e1b4f..70efb4b 100644 --- a/assets/components/LoginForm.tsx +++ b/assets/components/LoginForm.tsx @@ -1,4 +1,4 @@ -import {Button, Form, Input, message, Space} from 'antd' +import {Button, Flex, Form, Input, message} from 'antd' import {t} from 'ttag' import React, {useContext, useEffect} from 'react' import {getUser, login} from '../utils/api' @@ -60,18 +60,15 @@ export function LoginForm({ssoLogin}: { ssoLogin?: boolean }) { - - + - - {ssoLogin && + {ssoLogin && - } - + } + ) diff --git a/assets/pages/LoginPage.tsx b/assets/pages/LoginPage.tsx index df50dd1..32b10e2 100644 --- a/assets/pages/LoginPage.tsx +++ b/assets/pages/LoginPage.tsx @@ -6,6 +6,7 @@ import {LoginForm} from '../components/LoginForm' import type { InstanceConfig} from '../utils/api' import {getConfiguration} from '../utils/api' import {RegisterForm} from '../components/RegisterForm' +import useBreakpoint from "../hooks/useBreakpoint"; export const AuthenticatedContext = createContext< { @@ -22,6 +23,7 @@ export const AuthenticatedContext = createContext< export default function LoginPage() { const [wantRegister, setWantRegister] = useState(false) const [configuration, setConfiguration] = useState() + const md = useBreakpoint('md') const toggleWantRegister = () => { setWantRegister(!wantRegister) @@ -31,24 +33,32 @@ export default function LoginPage() { getConfiguration().then(setConfiguration) }, []) + const grid = [ + + {wantRegister ? : } + { + configuration?.registerEnabled && + + } + , + + + + ]; + + if (md) { + grid.reverse(); + } + return ( - - {wantRegister ? : } - { - configuration?.registerEnabled && - - } - - - - + {grid} ) } From a6eec5cfee51b5b84e0547f9cfffbfef6d6508fa Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 31 Oct 2025 13:49:48 +0100 Subject: [PATCH 024/131] fix: flex footer links --- assets/App.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/App.tsx b/assets/App.tsx index 3a5fa32..81ce3cb 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -1,4 +1,4 @@ -import {Button, ConfigProvider, FloatButton, Layout, Space, theme, Tooltip, Typography} from 'antd' +import {Button, ConfigProvider, Flex, FloatButton, Layout, theme, Tooltip, Typography} from 'antd' import {Link, Navigate, Route, Routes, useLocation, useNavigate} from 'react-router-dom' import TextPage from './pages/TextPage' import DomainSearchPage from './pages/search/DomainSearchPage' @@ -116,7 +116,7 @@ export default function App(): React.ReactElement { - + @@ -129,7 +129,7 @@ export default function App(): React.ReactElement { >{t`Documentation`} - + {jt`${ProjectLink} is an open source project distributed under the ${LicenseLink} license.`} From 467a3281d09daadf4cfe865f54d1a817c7ed4958 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 31 Oct 2025 13:56:11 +0100 Subject: [PATCH 025/131] fix: login form loading --- assets/components/LoginForm.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/assets/components/LoginForm.tsx b/assets/components/LoginForm.tsx index 70efb4b..686b3ae 100644 --- a/assets/components/LoginForm.tsx +++ b/assets/components/LoginForm.tsx @@ -1,6 +1,6 @@ import {Button, Flex, Form, Input, message} from 'antd' import {t} from 'ttag' -import React, {useContext, useEffect} from 'react' +import React, {useContext, useEffect, useState} from 'react' import {getUser, login} from '../utils/api' import {AuthenticatedContext} from '../pages/LoginPage' import {useNavigate} from 'react-router-dom' @@ -16,6 +16,7 @@ export function LoginForm({ssoLogin}: { ssoLogin?: boolean }) { const navigate = useNavigate() const [messageApi, contextHolder] = message.useMessage() const {setIsAuthenticated} = useContext(AuthenticatedContext) + const [loading, setLoading] = useState(false); useEffect(() => { getUser().then(() => { @@ -25,12 +26,15 @@ export function LoginForm({ssoLogin}: { ssoLogin?: boolean }) { }, []) const onFinish = (data: FieldType) => { + setLoading(true); + login(data.username, data.password).then(() => { setIsAuthenticated(true) navigate('/home') }).catch((e) => { setIsAuthenticated(false) showErrorAPI(e, messageApi) + setLoading(true); }) } return ( @@ -43,6 +47,7 @@ export function LoginForm({ssoLogin}: { ssoLogin?: boolean }) { style={{maxWidth: 600}} onFinish={onFinish} autoComplete='off' + disabled={loading} > Date: Fri, 31 Oct 2025 14:01:48 +0100 Subject: [PATCH 026/131] fix: responsive main padding --- assets/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/App.tsx b/assets/App.tsx index 81ce3cb..60f21b7 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -83,7 +83,7 @@ export default function App(): React.ReactElement {
From fdff20f500ac26ac9038a045187f150b362f1402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 31 Oct 2025 15:13:29 +0100 Subject: [PATCH 027/131] fix: set null if relation is deleted on DominPurchase --- migrations/Version20251031141153.php | 43 ++++++++++++++++++++++++++++ src/Entity/DomainPurchase.php | 4 ++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 migrations/Version20251031141153.php diff --git a/migrations/Version20251031141153.php b/migrations/Version20251031141153.php new file mode 100644 index 0000000..d97f795 --- /dev/null +++ b/migrations/Version20251031141153.php @@ -0,0 +1,43 @@ +addSql('ALTER TABLE domain_purchase DROP CONSTRAINT FK_72999E74115F0EE5'); + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT FK_72999E744D085745'); + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT FK_72999E74A76ED395'); + $this->addSql('ALTER TABLE domain_purchase ALTER domain_id DROP NOT NULL'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT FK_72999E74115F0EE5 FOREIGN KEY (domain_id) REFERENCES domain (ldh_name) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT FK_72999E744D085745 FOREIGN KEY (connector_id) REFERENCES connector (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT FK_72999E74A76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT fk_72999e74115f0ee5'); + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT fk_72999e744d085745'); + $this->addSql('ALTER TABLE domain_purchase DROP CONSTRAINT fk_72999e74a76ed395'); + $this->addSql('ALTER TABLE domain_purchase ALTER domain_id SET NOT NULL'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT fk_72999e74115f0ee5 FOREIGN KEY (domain_id) REFERENCES domain (ldh_name) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT fk_72999e744d085745 FOREIGN KEY (connector_id) REFERENCES connector (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE domain_purchase ADD CONSTRAINT fk_72999e74a76ed395 FOREIGN KEY (user_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + } +} diff --git a/src/Entity/DomainPurchase.php b/src/Entity/DomainPurchase.php index 3d6c1c6..3ec0a5d 100644 --- a/src/Entity/DomainPurchase.php +++ b/src/Entity/DomainPurchase.php @@ -15,7 +15,7 @@ class DomainPurchase private ?string $id; #[ORM\ManyToOne(inversedBy: 'domainPurchases')] - #[ORM\JoinColumn(referencedColumnName: 'ldh_name', nullable: false)] + #[ORM\JoinColumn(referencedColumnName: 'ldh_name', onDelete: 'CASCADE')] private ?Domain $domain = null; #[ORM\Column] @@ -28,9 +28,11 @@ class DomainPurchase private ?ConnectorProvider $connectorProvider = null; #[ORM\ManyToOne(inversedBy: 'domainPurchases')] + #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')] private ?Connector $connector = null; #[ORM\ManyToOne(inversedBy: 'domainPurchases')] + #[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')] private ?User $user = null; #[ORM\Column] From cf0a5eaa69c1efbb83d2db757672bddf41e0cd4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 31 Oct 2025 15:47:12 +0100 Subject: [PATCH 028/131] fix: check if NS status exists --- src/Service/RDAPService.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index 655f493..3113d4b 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -491,10 +491,13 @@ class RDAPService $nameserverEntity = new NameserverEntity(); } + if (isset($rdapEntity['status']) && is_array($rdapEntity['status'])) { + $nameserverEntity->setStatus($rdapNameserver['status']); + } + $nameserver->addNameserverEntity($nameserverEntity ->setNameserver($nameserver) ->setEntity($entity) - ->setStatus(array_map(fn ($s) => strtolower($s), array_unique($rdapNameserver['status']))) ->setRoles($roles)); $this->em->persist($nameserverEntity); From 8556308290b00926369784d340ece1d008a78a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 31 Oct 2025 15:49:18 +0100 Subject: [PATCH 029/131] fix: check if NS status exists --- src/Service/RDAPService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index 3113d4b..fb5312c 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -491,8 +491,8 @@ class RDAPService $nameserverEntity = new NameserverEntity(); } - if (isset($rdapEntity['status']) && is_array($rdapEntity['status'])) { - $nameserverEntity->setStatus($rdapNameserver['status']); + if (isset($rdapNameserver['status']) && is_array($rdapNameserver['status'])) { + $nameserverEntity->setStatus(array_map(fn ($s) => strtolower($s), array_unique($rdapNameserver['status']))); } $nameserver->addNameserverEntity($nameserverEntity From d2a5059a65da154d0de9db8a0bff917bd2d881e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 31 Oct 2025 16:21:01 +0100 Subject: [PATCH 030/131] feat: add low priority RDAP message queue --- config/packages/messenger.yaml | 13 +++++++++++-- src/Command/BatchRegisterDomainCommand.php | 5 ++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index bff1748..a4843b2 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -9,7 +9,7 @@ framework: retry_strategy: max_retries: 3 multiplier: 2 - rdap_async: + rdap_high: dsn: '%env(MESSENGER_RDAP_ASYNC_TRANSPORT_DSN)%' options: consumer: '%env(MESSENGER_CONSUMER_NAME)%' @@ -18,6 +18,15 @@ framework: multiplier: 2 max_delay: 86400000 + rdap_low: + dsn: '%env(MESSENGER_RDAP_ASYNC_TRANSPORT_DSN)%' + options: + consumer: '%env(MESSENGER_CONSUMER_NAME)%' + retry_strategy: + delay: 2000 + multiplier: 2 + max_delay: 86400000 + failed: 'doctrine://default?queue_name=failed' # sync: 'sync://' @@ -37,4 +46,4 @@ framework: App\Message\ProcessWatchlist: async App\Message\UpdateRdapServers: async App\Message\ValidateConnectorCredentials: async - App\Message\UpdateDomain: rdap_async + App\Message\UpdateDomain: rdap_high diff --git a/src/Command/BatchRegisterDomainCommand.php b/src/Command/BatchRegisterDomainCommand.php index b86a8dd..9b4f03d 100644 --- a/src/Command/BatchRegisterDomainCommand.php +++ b/src/Command/BatchRegisterDomainCommand.php @@ -11,6 +11,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Messenger\Exception\ExceptionInterface; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Messenger\Stamp\TransportNamesStamp; #[AsCommand( name: 'app:batch-register-domains', @@ -54,7 +55,9 @@ class BatchRegisterDomainCommand extends Command $io->title('Registering domains'); /** @var string $ldhName */ foreach ($domains as $ldhName) { - $this->messageBus->dispatch(new UpdateDomain($ldhName, null)); + $this->messageBus->dispatch(new UpdateDomain($ldhName, null), [ + new TransportNamesStamp('rdap_low'), + ]); } $io->success(sprintf('Imported %d domain names.', count($domains))); From 0fa95cc95cae172f1dbdf4b64ee71f3028c60272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 31 Oct 2025 16:30:58 +0100 Subject: [PATCH 031/131] feat: add low priority RDAP message queue --- src/Message/UpdateDomain.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Message/UpdateDomain.php b/src/Message/UpdateDomain.php index 086ecd5..c992608 100644 --- a/src/Message/UpdateDomain.php +++ b/src/Message/UpdateDomain.php @@ -2,9 +2,6 @@ namespace App\Message; -use Symfony\Component\Messenger\Attribute\AsMessage; - -#[AsMessage('rdap_async')] final class UpdateDomain { public function __construct( From ff5a2d7d67d412602e53e61e02d224fb1d60ddd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 31 Oct 2025 16:40:42 +0100 Subject: [PATCH 032/131] feat: add low priority RDAP message queue --- .env | 3 ++- config/packages/messenger.yaml | 4 ++-- docker-compose.yml | 6 ++++-- src/MessageHandler/UpdateDomainHandler.php | 5 ++++- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.env b/.env index 7659ea7..c5f09f7 100644 --- a/.env +++ b/.env @@ -56,7 +56,8 @@ MESSENGER_CONSUMER_NAME=worker # MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages # MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages MESSENGER_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages?lazy=1 -MESSENGER_RDAP_ASYNC_TRANSPORT_DSN=redis://localhost:6379/messages-rdap?lazy=1 +MESSENGER_RDAP_LOW_TRANSPORT_DSN=redis://localhost:6379/messages-rdap-low?lazy=1 +MESSENGER_RDAP_HIGH_TRANSPORT_DSN=redis://localhost:6379/messages-rdap-high?lazy=1 ###< symfony/messenger ### diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index a4843b2..74a3a53 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -10,7 +10,7 @@ framework: max_retries: 3 multiplier: 2 rdap_high: - dsn: '%env(MESSENGER_RDAP_ASYNC_TRANSPORT_DSN)%' + dsn: '%env(MESSENGER_RDAP_HIGH_TRANSPORT_DSN)%' options: consumer: '%env(MESSENGER_CONSUMER_NAME)%' retry_strategy: @@ -19,7 +19,7 @@ framework: max_delay: 86400000 rdap_low: - dsn: '%env(MESSENGER_RDAP_ASYNC_TRANSPORT_DSN)%' + dsn: '%env(MESSENGER_RDAP_LOW_TRANSPORT_DSN)%' options: consumer: '%env(MESSENGER_CONSUMER_NAME)%' retry_strategy: diff --git a/docker-compose.yml b/docker-compose.yml index 32ef3b7..8c56298 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,8 @@ services: SERVER_NAME: ${SERVER_NAME:-:80} DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} MESSENGER_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages - MESSENGER_RDAP_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages-rdap + MESSENGER_RDAP_LOW_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-low + MESSENGER_RDAP_HIGH_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-high volumes: - caddy_data:/data - caddy_config:/config @@ -33,7 +34,8 @@ services: APP_ENV: prod DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} MESSENGER_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages - MESSENGER_RDAP_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages-rdap + MESSENGER_RDAP_LOW_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-low + MESSENGER_RDAP_HIGH_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-high MESSENGER_CONSUMER_NAME: worker depends_on: - database diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php index 232c3c2..66924dd 100644 --- a/src/MessageHandler/UpdateDomainHandler.php +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -24,6 +24,7 @@ use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\Exception\ExceptionInterface; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Messenger\Stamp\TransportNamesStamp; use Symfony\Component\Mime\Address; use Symfony\Component\Notifier\Recipient\Recipient; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; @@ -89,7 +90,9 @@ final readonly class UpdateDomainHandler if (null === $watchlist) { /** @var Watchlist $wl */ foreach ($domain->getWatchlists()->getIterator() as $wl) { - $this->bus->dispatch(new UpdateDomain($message->ldhName, $wl->getToken())); + $this->bus->dispatch(new UpdateDomain($message->ldhName, $wl->getToken()), [ + new TransportNamesStamp('rdap_low'), + ]); } return; From 6af52a70964d29635aef34d99796fdd926e34e8b Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 22:47:37 +0100 Subject: [PATCH 033/131] fix: loading state --- assets/components/LoginForm.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/components/LoginForm.tsx b/assets/components/LoginForm.tsx index 686b3ae..966353f 100644 --- a/assets/components/LoginForm.tsx +++ b/assets/components/LoginForm.tsx @@ -16,7 +16,7 @@ export function LoginForm({ssoLogin}: { ssoLogin?: boolean }) { const navigate = useNavigate() const [messageApi, contextHolder] = message.useMessage() const {setIsAuthenticated} = useContext(AuthenticatedContext) - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(false) useEffect(() => { getUser().then(() => { @@ -26,7 +26,7 @@ export function LoginForm({ssoLogin}: { ssoLogin?: boolean }) { }, []) const onFinish = (data: FieldType) => { - setLoading(true); + setLoading(true) login(data.username, data.password).then(() => { setIsAuthenticated(true) @@ -34,7 +34,7 @@ export function LoginForm({ssoLogin}: { ssoLogin?: boolean }) { }).catch((e) => { setIsAuthenticated(false) showErrorAPI(e, messageApi) - setLoading(true); + setLoading(false) }) } return ( From f38b84dc2915e1db531f17becadc3880ae29e95b Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 22:52:28 +0100 Subject: [PATCH 034/131] fix: interpolated elements missing keys --- assets/App.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/App.tsx b/assets/App.tsx index 60f21b7..8a40b58 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -22,8 +22,8 @@ import IcannRegistrarPage from "./pages/infrastructure/IcannRegistrarPage" const PROJECT_LINK = 'https://github.com/maelgangloff/domain-watchdog' const LICENSE_LINK = 'https://www.gnu.org/licenses/agpl-3.0.txt' -const ProjectLink = Domain Watchdog -const LicenseLink = AGPL-3.0-or-later +const ProjectLink = Domain Watchdog +const LicenseLink = AGPL-3.0-or-later export default function App(): React.ReactElement { const navigate = useNavigate() From 01e3a221899a9fd58fe19912adceb298ada30a0b Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 22:52:45 +0100 Subject: [PATCH 035/131] fix: login grid missing keys --- assets/pages/LoginPage.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/pages/LoginPage.tsx b/assets/pages/LoginPage.tsx index 32b10e2..41d223b 100644 --- a/assets/pages/LoginPage.tsx +++ b/assets/pages/LoginPage.tsx @@ -34,7 +34,7 @@ export default function LoginPage() { }, []) const grid = [ - + {wantRegister ? : } { configuration?.registerEnabled && @@ -47,13 +47,13 @@ export default function LoginPage() { } , - + - ]; + ] if (md) { - grid.reverse(); + grid.reverse() } return ( From ba53773f4316416aeefda0883b986bad9f019983 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 23:02:38 +0100 Subject: [PATCH 036/131] fix: TLD table sizes --- assets/pages/infrastructure/TldPage.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/assets/pages/infrastructure/TldPage.tsx b/assets/pages/infrastructure/TldPage.tsx index 68e9f0c..bcf004a 100644 --- a/assets/pages/infrastructure/TldPage.tsx +++ b/assets/pages/infrastructure/TldPage.tsx @@ -11,6 +11,7 @@ import {getCountryCode} from '../../utils/functions/getCountryCode' import {tldToEmoji} from '../../utils/functions/tldToEmoji' import {BankOutlined, FlagOutlined, GlobalOutlined, TrademarkOutlined} from "@ant-design/icons" import {Link} from "react-router-dom" +import useBreakpoint from "../../hooks/useBreakpoint"; const {Text, Paragraph} = Typography @@ -30,6 +31,7 @@ function TldTable(filters: FiltersType) { Country?: string } + const sm = useBreakpoint('sm') const [dataTable, setDataTable] = useState([]) const [total, setTotal] = useState(0) @@ -110,14 +112,15 @@ function TldTable(filters: FiltersType) { fetchData({...filters, page, itemsPerPage}) } }} - - scroll={{y: '50vh'}} + scroll={sm ? {} : {y: '50vh'}} + size={sm ? 'small' : 'large'} /> ) } export default function TldPage() { const [activeTabKey, setActiveTabKey] = useState('gTLD') + const sm = useBreakpoint("sm") const contentList: Record = { sTLD: <> @@ -185,6 +188,7 @@ export default function TldPage() { activeTabKey={activeTabKey} key={activeTabKey} onTabChange={(k: string) => setActiveTabKey(k)} + size={sm ? 'small' : 'default'} > {contentList[activeTabKey]} From bcef7ef29d0ae5c6eec103f634ec515634eb7db7 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 23:11:20 +0100 Subject: [PATCH 037/131] fix: ICANN registrar table size --- assets/pages/infrastructure/IcannRegistrarPage.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/assets/pages/infrastructure/IcannRegistrarPage.tsx b/assets/pages/infrastructure/IcannRegistrarPage.tsx index 3164be6..9b538c8 100644 --- a/assets/pages/infrastructure/IcannRegistrarPage.tsx +++ b/assets/pages/infrastructure/IcannRegistrarPage.tsx @@ -5,6 +5,7 @@ import {t} from 'ttag' import type {ColumnType} from 'antd/es/table' import {CheckCircleOutlined, SettingOutlined, CloseCircleOutlined} from "@ant-design/icons" import {getIcannAccreditations} from "../../utils/api/icann-accreditations" +import useBreakpoint from "../../hooks/useBreakpoint" const {Text, Paragraph} = Typography @@ -19,6 +20,7 @@ function RegistrarListTable(filters: FiltersType) { name: string } + const sm = useBreakpoint('sm') const [dataTable, setDataTable] = useState([]) const [total, setTotal] = useState(0) @@ -63,14 +65,15 @@ function RegistrarListTable(filters: FiltersType) { fetchData({...filters, page, itemsPerPage}) } }} - - scroll={{y: '50vh'}} + scroll={sm ? {} : {y: '50vh'}} + size={sm ? 'small' : 'large'} /> ) } export default function IcannRegistrarPage() { const [activeTabKey, setActiveTabKey] = useState('Accredited') + const sm = useBreakpoint('sm') const contentList: Record = { Accredited: <> @@ -125,6 +128,7 @@ export default function IcannRegistrarPage() { activeTabKey={activeTabKey} key={activeTabKey} onTabChange={(k: string) => setActiveTabKey(k)} + size={sm ? 'small' : 'default'} > {contentList[activeTabKey]} From 0e5c675f2cafe5dbb3e4551eb3588ba734242de1 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 23:13:45 +0100 Subject: [PATCH 038/131] style: lint --- assets/pages/LoginPage.tsx | 2 +- assets/pages/infrastructure/TldPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/pages/LoginPage.tsx b/assets/pages/LoginPage.tsx index 41d223b..8e709ca 100644 --- a/assets/pages/LoginPage.tsx +++ b/assets/pages/LoginPage.tsx @@ -6,7 +6,7 @@ import {LoginForm} from '../components/LoginForm' import type { InstanceConfig} from '../utils/api' import {getConfiguration} from '../utils/api' import {RegisterForm} from '../components/RegisterForm' -import useBreakpoint from "../hooks/useBreakpoint"; +import useBreakpoint from "../hooks/useBreakpoint" export const AuthenticatedContext = createContext< { diff --git a/assets/pages/infrastructure/TldPage.tsx b/assets/pages/infrastructure/TldPage.tsx index bcf004a..74ccf77 100644 --- a/assets/pages/infrastructure/TldPage.tsx +++ b/assets/pages/infrastructure/TldPage.tsx @@ -11,7 +11,7 @@ import {getCountryCode} from '../../utils/functions/getCountryCode' import {tldToEmoji} from '../../utils/functions/tldToEmoji' import {BankOutlined, FlagOutlined, GlobalOutlined, TrademarkOutlined} from "@ant-design/icons" import {Link} from "react-router-dom" -import useBreakpoint from "../../hooks/useBreakpoint"; +import useBreakpoint from "../../hooks/useBreakpoint" const {Text, Paragraph} = Typography From ec47a7a30f8901ed6fd84af4a84721fe70bab948 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 23:35:10 +0100 Subject: [PATCH 039/131] fix: tracked domain table size --- assets/components/tracking/watchlist/TrackedDomainTable.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/components/tracking/watchlist/TrackedDomainTable.tsx b/assets/components/tracking/watchlist/TrackedDomainTable.tsx index 89c1adb..cecceac 100644 --- a/assets/components/tracking/watchlist/TrackedDomainTable.tsx +++ b/assets/components/tracking/watchlist/TrackedDomainTable.tsx @@ -22,6 +22,7 @@ import { } from '@ant-design/icons' import {DomainToTag} from '../../../utils/functions/DomainToTag' import {isDomainLocked} from "../../../utils/functions/isDomainLocked" +import useBreakpoint from "../../../hooks/useBreakpoint" export function TrackedDomainTable() { const REDEMPTION_NOTICE = ( @@ -53,6 +54,7 @@ export function TrackedDomainTable() { const [dataTable, setDataTable] = useState([]) const [total, setTotal] = useState() const [specialNotice, setSpecialNotice] = useState([]) + const sm = useBreakpoint('sm') const rdapStatusCodeDetailTranslated = rdapStatusCodeDetailTranslation() @@ -268,7 +270,8 @@ export function TrackedDomainTable() { fetchData({page, itemsPerPage}) } }} - scroll={{y: '50vh'}} + scroll={sm ? {} : {y: '50vh'}} + size={sm ? 'small' : 'large'} /> } From 44277931a87915bd918330f52cd87f25c9d254f9 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 23:39:08 +0100 Subject: [PATCH 040/131] fix: TLD statistics wrapping --- assets/pages/StatisticsPage.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/assets/pages/StatisticsPage.tsx b/assets/pages/StatisticsPage.tsx index 0cf1881..b9bfd92 100644 --- a/assets/pages/StatisticsPage.tsx +++ b/assets/pages/StatisticsPage.tsx @@ -1,7 +1,7 @@ import React, {useEffect, useState} from 'react' import type { Statistics} from '../utils/api' import {getStatistics} from '../utils/api' -import {Card, Col, Divider, Row, Statistic, Tooltip} from 'antd' +import {Card, Col, Divider, Flex, Row, Statistic, Tooltip} from 'antd' import {t} from 'ttag' import { AimOutlined, @@ -104,20 +104,19 @@ export default function StatisticsPage() { - + {stats?.domainCount .sort((a, b) => b.domain - a.domain) - .map(({domain, tld}) => - + .map(({domain, tld}) => + - - )} - + )} + ) } From b3121a3914a7afb718f7e14b423ba8b6513ce0f1 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Fri, 31 Oct 2025 23:57:12 +0100 Subject: [PATCH 041/131] fix: sider button in header --- assets/App.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/assets/App.tsx b/assets/App.tsx index 8a40b58..0e181a4 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -15,7 +15,7 @@ import NotFoundPage from './pages/NotFoundPage' import useBreakpoint from './hooks/useBreakpoint' import {Sider} from './components/Sider' import {jt, t} from 'ttag' -import {BugOutlined, InfoCircleOutlined, MergeOutlined} from '@ant-design/icons' +import {BugOutlined, InfoCircleOutlined, MergeOutlined, MenuOutlined} from '@ant-design/icons' import TrackedDomainPage from './pages/tracking/TrackedDomainPage' import IcannRegistrarPage from "./pages/infrastructure/IcannRegistrarPage" @@ -30,6 +30,7 @@ export default function App(): React.ReactElement { const location = useLocation() const sm = useBreakpoint('sm') + const [sidebarCollapsed, setSidebarCollapsed] = useState(false) const [isAuthenticated, setIsAuthenticated] = useState(false) const authenticated = useCallback((authenticated: boolean) => { @@ -75,12 +76,17 @@ export default function App(): React.ReactElement { > - {/* Ant will use a break-off tab to toggle the collapse of the sider when collapseWidth = 0 */} - + - + + {sm && + + } +
Date: Fri, 31 Oct 2025 23:58:36 +0100 Subject: [PATCH 042/131] fix: avoid impossible state on width changes --- assets/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/App.tsx b/assets/App.tsx index 0e181a4..5c682ca 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -76,7 +76,7 @@ export default function App(): React.ReactElement { > - + From 6267461ed9dec55410c1205197cca0821fbf3b5d Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 00:39:10 +0100 Subject: [PATCH 043/131] feat: menu in drawer on sm --- assets/App.tsx | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/assets/App.tsx b/assets/App.tsx index 5c682ca..f2f7239 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -1,4 +1,4 @@ -import {Button, ConfigProvider, Flex, FloatButton, Layout, theme, Tooltip, Typography} from 'antd' +import {Button, ConfigProvider, Drawer, Flex, FloatButton, Layout, theme, Tooltip, Typography} from 'antd' import {Link, Navigate, Route, Routes, useLocation, useNavigate} from 'react-router-dom' import TextPage from './pages/TextPage' import DomainSearchPage from './pages/search/DomainSearchPage' @@ -7,7 +7,7 @@ import TldPage from './pages/infrastructure/TldPage' import StatisticsPage from './pages/StatisticsPage' import WatchlistPage from './pages/tracking/WatchlistPage' import UserPage from './pages/UserPage' -import React, {useCallback, useEffect, useMemo, useState} from 'react' +import React, {PropsWithChildren, useCallback, useEffect, useMemo, useState} from 'react' import {getUser} from './utils/api' import LoginPage, {AuthenticatedContext} from './pages/LoginPage' import ConnectorPage from './pages/tracking/ConnectorPage' @@ -25,6 +25,40 @@ const LICENSE_LINK = 'https://www.gnu.org/licenses/agpl-3.0.txt' const ProjectLink = Domain Watchdog const LicenseLink = AGPL-3.0-or-later +function SiderWrapper(props: PropsWithChildren<{sidebarCollapsed: boolean, setSidebarCollapsed: (collapsed: boolean) => void}>): React.ReactElement { + const {sidebarCollapsed, setSidebarCollapsed, children} = props + const sm = useBreakpoint('sm') + const location = useLocation() + + useEffect(() => { + if (sm) { + setSidebarCollapsed(false) + } + }, [location]) + + if (sm) { + return setSidebarCollapsed(false)} + closeIcon={null} + styles={{body: {padding: 0, height: '100%', background: '#001529'}}} + width='200px'> + {children} + + } else { + return + {children} + + } +} + export default function App(): React.ReactElement { const navigate = useNavigate() const location = useLocation() @@ -76,9 +110,9 @@ export default function App(): React.ReactElement { > - + - + {sm && From f2a6f9108c184342fa61f25070adb5f13baf654f Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 00:43:43 +0100 Subject: [PATCH 044/131] fix: black body on dark theme --- assets/index.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/index.css b/assets/index.css index cf93289..d6983d7 100644 --- a/assets/index.css +++ b/assets/index.css @@ -10,4 +10,8 @@ body { margin: 0; font-family: "Noto Color Emoji", sans-serif; + + @media (prefers-color-scheme: dark) { + background: #000000; + } } From e96358b9caaef816a92c7c108bc440378c1da95e Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 01:00:04 +0100 Subject: [PATCH 045/131] fix: various missing component array keys --- .../components/tracking/connector/ConnectorsList.tsx | 12 ++++++------ .../tracking/watchlist/TrackedDomainTable.tsx | 3 +++ assets/utils/functions/StatusToTag.tsx | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/assets/components/tracking/connector/ConnectorsList.tsx b/assets/components/tracking/connector/ConnectorsList.tsx index 0df8af5..a874d4c 100644 --- a/assets/components/tracking/connector/ConnectorsList.tsx +++ b/assets/components/tracking/connector/ConnectorsList.tsx @@ -22,16 +22,16 @@ export function ConnectorsList({connectors, onDelete}: { connectors: ConnectorEl <> {connectors.map(connector => { - const createdAt = + const createdAt = {new Date(connector.createdAt).toLocaleString()} const {watchlistCount} = connector const connectorName = Object.keys(ConnectorProvider).find(p => ConnectorProvider[p as keyof typeof ConnectorProvider] === connector.provider) - return <> - {contextHolder} - + return {t`Connector ${connectorName}`}{connector.id} } size='small' @@ -45,6 +45,7 @@ export function ConnectorsList({connectors, onDelete}: { connectors: ConnectorEl > } > + {contextHolder} {jt`Creation date: ${createdAt}`} {t`Used in: ${watchlistCount} Watchlist`} }/> - } )} diff --git a/assets/components/tracking/watchlist/TrackedDomainTable.tsx b/assets/components/tracking/watchlist/TrackedDomainTable.tsx index cecceac..ef14923 100644 --- a/assets/components/tracking/watchlist/TrackedDomainTable.tsx +++ b/assets/components/tracking/watchlist/TrackedDomainTable.tsx @@ -28,6 +28,7 @@ export function TrackedDomainTable() { const REDEMPTION_NOTICE = ( redemption period @@ -36,6 +37,7 @@ export function TrackedDomainTable() { const PENDING_DELETE_NOTICE = ( pending delete @@ -222,6 +224,7 @@ export function TrackedDomainTable() { text: {s} , diff --git a/assets/utils/functions/StatusToTag.tsx b/assets/utils/functions/StatusToTag.tsx index bf46bb2..7ae1164 100644 --- a/assets/utils/functions/StatusToTag.tsx +++ b/assets/utils/functions/StatusToTag.tsx @@ -10,6 +10,7 @@ export function statusToTag(s: string) { {s} From 9ae7ab7f7a08368768ceda16207f22b034682032 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 01:00:31 +0100 Subject: [PATCH 046/131] chore: type import --- assets/App.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/App.tsx b/assets/App.tsx index f2f7239..529d87f 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -7,7 +7,8 @@ import TldPage from './pages/infrastructure/TldPage' import StatisticsPage from './pages/StatisticsPage' import WatchlistPage from './pages/tracking/WatchlistPage' import UserPage from './pages/UserPage' -import React, {PropsWithChildren, useCallback, useEffect, useMemo, useState} from 'react' +import type {PropsWithChildren} from 'react' +import React, { useCallback, useEffect, useMemo, useState} from 'react' import {getUser} from './utils/api' import LoginPage, {AuthenticatedContext} from './pages/LoginPage' import ConnectorPage from './pages/tracking/ConnectorPage' From ccfd7e0e89812d2f7522daa7535fd7aa7e105cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 1 Nov 2025 13:59:52 +0100 Subject: [PATCH 047/131] feat: add only-new command option --- src/Command/BatchRegisterDomainCommand.php | 8 ++++++-- src/Message/UpdateDomain.php | 1 + src/MessageHandler/UpdateDomainHandler.php | 8 ++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Command/BatchRegisterDomainCommand.php b/src/Command/BatchRegisterDomainCommand.php index 9b4f03d..51d2e34 100644 --- a/src/Command/BatchRegisterDomainCommand.php +++ b/src/Command/BatchRegisterDomainCommand.php @@ -7,6 +7,7 @@ use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Messenger\Exception\ExceptionInterface; @@ -28,7 +29,9 @@ class BatchRegisterDomainCommand extends Command protected function configure(): void { $this - ->addArgument('file', InputArgument::REQUIRED, 'Path to a file containing a list of domain names'); + ->addArgument('file', InputArgument::REQUIRED, 'Path to a file containing a list of domain names') + ->addOption('only-new', 'on', InputOption::VALUE_NEGATABLE, 'Do not update domain names if they are already in the database', false) + ; } /** @@ -38,6 +41,7 @@ class BatchRegisterDomainCommand extends Command { $io = new SymfonyStyle($input, $output); $file = $input->getArgument('file'); + $onlyNew = (bool) $input->getOption('only-new'); if (!file_exists($file) || !is_readable($file)) { $io->error(sprintf('File "%s" does not exist or is not readable.', $file)); @@ -55,7 +59,7 @@ class BatchRegisterDomainCommand extends Command $io->title('Registering domains'); /** @var string $ldhName */ foreach ($domains as $ldhName) { - $this->messageBus->dispatch(new UpdateDomain($ldhName, null), [ + $this->messageBus->dispatch(new UpdateDomain($ldhName, null, $onlyNew), [ new TransportNamesStamp('rdap_low'), ]); } diff --git a/src/Message/UpdateDomain.php b/src/Message/UpdateDomain.php index c992608..873c526 100644 --- a/src/Message/UpdateDomain.php +++ b/src/Message/UpdateDomain.php @@ -7,6 +7,7 @@ final class UpdateDomain public function __construct( public string $ldhName, public ?string $watchlistToken, + public bool $onlyNew = false, ) { } } diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php index 66924dd..10d611b 100644 --- a/src/MessageHandler/UpdateDomainHandler.php +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -69,6 +69,14 @@ final readonly class UpdateDomainHandler { $domain = $this->domainRepository->findOneBy(['ldhName' => $message->ldhName]); + if (null !== $domain && $message->onlyNew) { + $this->logger->debug('The domain name is already present in the database', [ + 'ldhName' => $domain->getLdhName(), + ]); + + return; + } + if (null === $domain) { $this->RDAPService->registerDomain($message->ldhName); From e96786406894f2d0ca5464a2c6057b267a3a118d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 1 Nov 2025 14:29:30 +0100 Subject: [PATCH 048/131] fix: set value for property onlyNew --- src/MessageHandler/ProcessWatchlistHandler.php | 2 +- src/MessageHandler/UpdateDomainHandler.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MessageHandler/ProcessWatchlistHandler.php b/src/MessageHandler/ProcessWatchlistHandler.php index c2ef749..0ae95f5 100644 --- a/src/MessageHandler/ProcessWatchlistHandler.php +++ b/src/MessageHandler/ProcessWatchlistHandler.php @@ -83,7 +83,7 @@ final readonly class ProcessWatchlistHandler /** @var Domain $domain */ foreach ($watchlist->getDomains()->filter(fn ($domain) => $this->RDAPService->isToBeUpdated($domain, false, null !== $watchlist->getConnector())) as $domain) { - $this->bus->dispatch(new UpdateDomain($domain->getLdhName(), $watchlist->getToken())); + $this->bus->dispatch(new UpdateDomain($domain->getLdhName(), $watchlist->getToken(), false)); } } diff --git a/src/MessageHandler/UpdateDomainHandler.php b/src/MessageHandler/UpdateDomainHandler.php index 10d611b..277afe5 100644 --- a/src/MessageHandler/UpdateDomainHandler.php +++ b/src/MessageHandler/UpdateDomainHandler.php @@ -98,7 +98,7 @@ final readonly class UpdateDomainHandler if (null === $watchlist) { /** @var Watchlist $wl */ foreach ($domain->getWatchlists()->getIterator() as $wl) { - $this->bus->dispatch(new UpdateDomain($message->ldhName, $wl->getToken()), [ + $this->bus->dispatch(new UpdateDomain($message->ldhName, $wl->getToken(), false), [ new TransportNamesStamp('rdap_low'), ]); } From 43901616fdab1e5007d670c4e5554c1036a39dc5 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 17:47:41 +0100 Subject: [PATCH 049/131] fix: center footer links --- assets/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/App.tsx b/assets/App.tsx index 529d87f..75559a9 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -157,7 +157,7 @@ export default function App(): React.ReactElement {
- + From e7240ed491396c2c72eb4925d46489984bafff12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 1 Nov 2025 17:54:43 +0100 Subject: [PATCH 050/131] chore: ttag extract --- translations/translations.pot | 140 +++++++++++++++++----------------- 1 file changed, 68 insertions(+), 72 deletions(-) diff --git a/translations/translations.pot b/translations/translations.pot index 12af7de..fba7bae 100644 --- a/translations/translations.pot +++ b/translations/translations.pot @@ -3,44 +3,44 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" -#: assets/App.tsx:120 +#: assets/App.tsx:161 msgid "TOS" msgstr "" -#: assets/App.tsx:121 +#: assets/App.tsx:162 msgid "Privacy Policy" msgstr "" -#: assets/App.tsx:122 +#: assets/App.tsx:163 msgid "FAQ" msgstr "" -#: assets/App.tsx:129 +#: assets/App.tsx:170 msgid "Documentation" msgstr "" -#: assets/App.tsx:134 +#: assets/App.tsx:175 #, javascript-format msgid "" "${ ProjectLink } is an open source project distributed under the ${ " "LicenseLink } license." msgstr "" -#: assets/App.tsx:147 +#: assets/App.tsx:188 msgid "Official git repository" msgstr "" -#: assets/App.tsx:150 +#: assets/App.tsx:191 msgid "Submit an issue" msgstr "" -#: assets/components/LoginForm.tsx:48 +#: assets/components/LoginForm.tsx:53 #: assets/components/RegisterForm.tsx:37 msgid "Email address" msgstr "" -#: assets/components/LoginForm.tsx:50 -#: assets/components/LoginForm.tsx:58 +#: assets/components/LoginForm.tsx:55 +#: assets/components/LoginForm.tsx:63 #: assets/components/RegisterForm.tsx:39 #: assets/components/RegisterForm.tsx:47 #: assets/components/search/DomainSearchBar.tsx:28 @@ -72,22 +72,22 @@ msgstr "" msgid "Required" msgstr "" -#: assets/components/LoginForm.tsx:56 +#: assets/components/LoginForm.tsx:61 #: assets/components/RegisterForm.tsx:45 #: assets/utils/providers/forms/EppConnectorForm.tsx:138 msgid "Password" msgstr "" -#: assets/components/LoginForm.tsx:66 +#: assets/components/LoginForm.tsx:70 msgid "Submit" msgstr "" -#: assets/components/LoginForm.tsx:71 +#: assets/components/LoginForm.tsx:74 msgid "Log in with SSO" msgstr "" #: assets/components/RegisterForm.tsx:54 -#: assets/pages/LoginPage.tsx:35 +#: assets/pages/LoginPage.tsx:60 msgid "Register" msgstr "" @@ -97,22 +97,22 @@ msgid "Registration" msgstr "" #: assets/components/search/DomainLifecycleSteps.tsx:24 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:133 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:137 msgid "Active" msgstr "" #: assets/components/search/DomainLifecycleSteps.tsx:29 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:111 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:115 msgid "Auto-Renew Grace Period" msgstr "" #: assets/components/search/DomainLifecycleSteps.tsx:35 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:119 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:123 msgid "Redemption Grace Period" msgstr "" #: assets/components/search/DomainLifecycleSteps.tsx:40 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:127 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:131 msgid "Pending Delete" msgstr "" @@ -124,7 +124,7 @@ msgid "" msgstr "" #: assets/components/search/DomainResult.tsx:64 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:89 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:93 msgid "Registry Lock" msgstr "" @@ -135,7 +135,7 @@ msgid "" msgstr "" #: assets/components/search/DomainResult.tsx:75 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:95 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:99 msgid "Registrar Lock" msgstr "" @@ -146,12 +146,12 @@ msgid "" msgstr "" #: assets/components/search/DomainResult.tsx:84 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:101 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:105 msgid "DNSSEC" msgstr "" #: assets/components/search/DomainResult.tsx:90 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:215 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:219 msgid "EPP Status Codes" msgstr "" @@ -177,7 +177,7 @@ msgid "Search" msgstr "" #: assets/components/Sider.tsx:43 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:175 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:179 msgid "Domain" msgstr "" @@ -192,7 +192,7 @@ msgstr "" #: assets/components/Sider.tsx:70 #: assets/pages/StatisticsPage.tsx:114 -#: assets/pages/infrastructure/TldPage.tsx:79 +#: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "" @@ -250,13 +250,13 @@ msgid "Log out" msgstr "" #: assets/components/Sider.tsx:154 -#: assets/pages/LoginPage.tsx:35 -#: assets/pages/LoginPage.tsx:45 +#: assets/pages/LoginPage.tsx:46 +#: assets/pages/LoginPage.tsx:60 msgid "Log in" msgstr "" #: assets/components/tracking/connector/ConnectorForm.tsx:36 -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:49 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:51 #: assets/utils/functions/rdapTranslation.ts:12 msgid "Registrar" msgstr "" @@ -328,17 +328,17 @@ msgstr "" msgid "No" msgstr "" -#: assets/components/tracking/connector/ConnectorsList.tsx:48 +#: assets/components/tracking/connector/ConnectorsList.tsx:49 #, javascript-format msgid "Creation date: ${ createdAt }" msgstr "" -#: assets/components/tracking/connector/ConnectorsList.tsx:49 +#: assets/components/tracking/connector/ConnectorsList.tsx:50 #, javascript-format msgid "Used in: ${ watchlistCount } Watchlist" msgstr "" -#: assets/components/tracking/connector/ConnectorsList.tsx:52 +#: assets/components/tracking/connector/ConnectorsList.tsx:53 msgid "" "You can stop using a connector at any time. To delete a connector, you must " "remove it from each linked Watchlist.\n" @@ -348,7 +348,7 @@ msgid "" "withdrawal and were of the minimum age to consent to these conditions." msgstr "" -#: assets/components/tracking/connector/ConnectorsList.tsx:56 +#: assets/components/tracking/connector/ConnectorsList.tsx:57 msgid "The Provider’s conditions are accessible by following this hyperlink." msgstr "" @@ -404,66 +404,66 @@ msgstr "" msgid "Enable the Watchlist" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:29 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:30 msgid "" "At least one domain name is in redemption period and will potentially be " "deleted soon" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:37 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:39 msgid "" "At least one domain name is pending deletion and will soon become available " "for registration again" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:143 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:147 msgid "Estimated number of days until WHOIS removal" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:146 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:150 #, javascript-format msgid "J ${ expiresInDays }" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:152 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:156 msgid "Deletion is imminent" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:181 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:185 msgid "Status" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:187 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:191 msgid "Options" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:193 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:197 msgid "Expiration date" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:207 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:211 msgid "Updated at" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:235 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:240 msgid "No tracked domain names were found, please create your first Watchlist" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:238 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:243 msgid "Create now" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:244 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 msgid "" "Please note that this table does not include domain names marked as expired " "or those with an unknown expiration date" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:254 msgid "At least one domain name you are tracking requires special attention" msgstr "" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:255 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:260 msgid "The domain names below are subject to special monitoring" msgstr "" @@ -475,10 +475,6 @@ msgstr "" msgid "Update a Watchlist" msgstr "" -#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 -msgid "Cancel" -msgstr "" - #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." msgstr "" @@ -568,31 +564,31 @@ msgstr "" msgid "Reset" msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:43 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:45 msgid "ID" msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:77 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:80 msgid "" "An accredited number means that ICANN's contract with the registrar is " "ongoing." msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:82 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:85 msgid "A reserved number can be used by TLD registries for specific operations." msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:87 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:90 msgid "" "A terminated number means that ICANN's contract with the registrar has been " "terminated." msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:96 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 msgid "This page lists ICANN-accredited registrars." msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:102 msgid "" "The list is officially published and maintained by the Internet Assigned " "Numbers Authority (IANA), the organization responsible for managing the " @@ -600,63 +596,63 @@ msgid "" "name extensions)." msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:111 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:114 #: assets/utils/functions/rdapTranslation.ts:125 msgid "Accredited" msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:116 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:119 #: assets/utils/functions/rdapTranslation.ts:126 msgid "Reserved" msgstr "" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:121 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:124 #: assets/utils/functions/rdapTranslation.ts:124 msgid "Terminated" msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:86 +#: assets/pages/infrastructure/TldPage.tsx:88 msgid "Flag" msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:89 +#: assets/pages/infrastructure/TldPage.tsx:91 msgid "Country" msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:96 +#: assets/pages/infrastructure/TldPage.tsx:98 msgid "Registry Operator" msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:124 +#: assets/pages/infrastructure/TldPage.tsx:127 msgid "" "Top-level domains sponsored by specific organizations that set rules for " "registration and use, often related to particular interest groups or " "industries." msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:129 +#: assets/pages/infrastructure/TldPage.tsx:132 msgid "" "Generic top-level domains open to everyone, not restricted by specific " "criteria, representing various themes or industries." msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:134 +#: assets/pages/infrastructure/TldPage.tsx:137 msgid "" "Generic top-level domains associated with specific brands, allowing " "companies to use their own brand names as domains." msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:139 +#: assets/pages/infrastructure/TldPage.tsx:142 msgid "" "Top-level domains based on country codes, identifying websites according to " "their country of origin." msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:148 +#: assets/pages/infrastructure/TldPage.tsx:151 msgid "This page presents all active TLDs in the root zone database." msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:151 +#: assets/pages/infrastructure/TldPage.tsx:154 msgid "" "IANA provides the list of currently active TLDs, regardless of their type, " "and ICANN provides the list of gTLDs.\n" @@ -668,23 +664,23 @@ msgid "" "At the same time, the list of root RDAP servers is updated." msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:166 +#: assets/pages/infrastructure/TldPage.tsx:169 msgid "Generic Top-Level-Domains" msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:171 +#: assets/pages/infrastructure/TldPage.tsx:174 msgid "Country-Code Top-Level-Domains" msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:176 +#: assets/pages/infrastructure/TldPage.tsx:179 msgid "Brand Generic Top-Level-Domains" msgstr "" -#: assets/pages/infrastructure/TldPage.tsx:181 +#: assets/pages/infrastructure/TldPage.tsx:184 msgid "Sponsored Top-Level-Domains" msgstr "" -#: assets/pages/LoginPage.tsx:45 +#: assets/pages/LoginPage.tsx:46 msgid "Create an account" msgstr "" From 4f6b8d5b9768015b494e64b4689e9ba732c37997 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 1 Nov 2025 16:56:00 +0000 Subject: [PATCH 051/131] Update translation files Updated by "Update PO files to match POT (msgmerge)" add-on in Weblate. --- translations/de.po | 141 ++++++++++++++++++++++----------------------- translations/fr.po | 141 ++++++++++++++++++++++----------------------- translations/sv.po | 141 ++++++++++++++++++++++----------------------- 3 files changed, 210 insertions(+), 213 deletions(-) diff --git a/translations/de.po b/translations/de.po index 300c7ba..8aa49d4 100644 --- a/translations/de.po +++ b/translations/de.po @@ -10,23 +10,23 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.13.2\n" -#: assets/App.tsx:120 +#: assets/App.tsx:161 msgid "TOS" msgstr "Nutzungsbedingungen" -#: assets/App.tsx:121 +#: assets/App.tsx:162 msgid "Privacy Policy" msgstr "Datenschutzrichtlinie" -#: assets/App.tsx:122 +#: assets/App.tsx:163 msgid "FAQ" msgstr "Häufig gestellte Fragen" -#: assets/App.tsx:129 +#: assets/App.tsx:170 msgid "Documentation" msgstr "Dokumentation" -#: assets/App.tsx:134 +#: assets/App.tsx:175 #, javascript-format msgid "" "${ ProjectLink } is an open source project distributed under the $" @@ -35,19 +35,19 @@ msgstr "" "${ ProjectLink } ist ein Open-Source-Projekt, das unter der ${ LicenseLink }-" "Lizenz vertrieben wird." -#: assets/App.tsx:147 +#: assets/App.tsx:188 msgid "Official git repository" msgstr "Offizielles Git-Repository" -#: assets/App.tsx:150 +#: assets/App.tsx:191 msgid "Submit an issue" msgstr "Ein Problem melden" -#: assets/components/LoginForm.tsx:48 assets/components/RegisterForm.tsx:37 +#: assets/components/LoginForm.tsx:53 assets/components/RegisterForm.tsx:37 msgid "Email address" msgstr "E-Mail-Adresse" -#: assets/components/LoginForm.tsx:50 assets/components/LoginForm.tsx:58 +#: assets/components/LoginForm.tsx:55 assets/components/LoginForm.tsx:63 #: assets/components/RegisterForm.tsx:39 assets/components/RegisterForm.tsx:47 #: assets/components/search/DomainSearchBar.tsx:28 #: assets/components/tracking/watchlist/WatchlistForm.tsx:155 @@ -78,20 +78,20 @@ msgstr "E-Mail-Adresse" msgid "Required" msgstr "Erforderlich" -#: assets/components/LoginForm.tsx:56 assets/components/RegisterForm.tsx:45 +#: assets/components/LoginForm.tsx:61 assets/components/RegisterForm.tsx:45 #: assets/utils/providers/forms/EppConnectorForm.tsx:138 msgid "Password" msgstr "Passwort" -#: assets/components/LoginForm.tsx:66 +#: assets/components/LoginForm.tsx:70 msgid "Submit" msgstr "Senden" -#: assets/components/LoginForm.tsx:71 +#: assets/components/LoginForm.tsx:74 msgid "Log in with SSO" msgstr "Mit SSO anmelden" -#: assets/components/RegisterForm.tsx:54 assets/pages/LoginPage.tsx:35 +#: assets/components/RegisterForm.tsx:54 assets/pages/LoginPage.tsx:60 msgid "Register" msgstr "Registrieren" @@ -101,22 +101,22 @@ msgid "Registration" msgstr "Registrierung" #: assets/components/search/DomainLifecycleSteps.tsx:24 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:133 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:137 msgid "Active" msgstr "Aktiv" #: assets/components/search/DomainLifecycleSteps.tsx:29 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:111 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:115 msgid "Auto-Renew Grace Period" msgstr "Nachfrist für automatische Verlängerung" #: assets/components/search/DomainLifecycleSteps.tsx:35 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:119 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:123 msgid "Redemption Grace Period" msgstr "Einlösezeitraum" #: assets/components/search/DomainLifecycleSteps.tsx:40 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:127 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:131 msgid "Pending Delete" msgstr "Ausstehende Löschung" @@ -131,7 +131,7 @@ msgstr "" "Registrierungsebene" #: assets/components/search/DomainResult.tsx:64 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:89 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:93 msgid "Registry Lock" msgstr "Registrierungssperre" @@ -144,7 +144,7 @@ msgstr "" "Änderungen durch Kontrollen auf Registrar-Ebene" #: assets/components/search/DomainResult.tsx:75 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:95 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:99 msgid "Registrar Lock" msgstr "Registrarsperre" @@ -157,12 +157,12 @@ msgstr "" "Einträgen und stellt so die Authentizität und Integrität der Antworten sicher" #: assets/components/search/DomainResult.tsx:84 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:101 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:105 msgid "DNSSEC" msgstr "DNSSEC" #: assets/components/search/DomainResult.tsx:90 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:215 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:219 msgid "EPP Status Codes" msgstr "EPP-Statuscodes" @@ -188,7 +188,7 @@ msgid "Search" msgstr "Suchen" #: assets/components/Sider.tsx:43 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:175 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:179 msgid "Domain" msgstr "Domain" @@ -201,7 +201,7 @@ msgid "Infrastructure" msgstr "Infrastruktur" #: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:114 -#: assets/pages/infrastructure/TldPage.tsx:79 +#: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "TLD" @@ -256,13 +256,13 @@ msgstr "Mein Konto" msgid "Log out" msgstr "Abmelden" -#: assets/components/Sider.tsx:154 assets/pages/LoginPage.tsx:35 -#: assets/pages/LoginPage.tsx:45 +#: assets/components/Sider.tsx:154 assets/pages/LoginPage.tsx:46 +#: assets/pages/LoginPage.tsx:60 msgid "Log in" msgstr "Anmelden" #: assets/components/tracking/connector/ConnectorForm.tsx:36 -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:49 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:51 #: assets/utils/functions/rdapTranslation.ts:12 msgid "Registrar" msgstr "Registrierungsstelle" @@ -344,17 +344,17 @@ msgstr "Ja" msgid "No" msgstr "Nein" -#: assets/components/tracking/connector/ConnectorsList.tsx:48 +#: assets/components/tracking/connector/ConnectorsList.tsx:49 #, javascript-format msgid "Creation date: ${ createdAt }" msgstr "Erstellungsdatum: ${ createdAt }" -#: assets/components/tracking/connector/ConnectorsList.tsx:49 +#: assets/components/tracking/connector/ConnectorsList.tsx:50 #, javascript-format msgid "Used in: ${ watchlistCount } Watchlist" msgstr "Verwendet in: ${ watchlistCount } Watchlist" -#: assets/components/tracking/connector/ConnectorsList.tsx:52 +#: assets/components/tracking/connector/ConnectorsList.tsx:53 msgid "" "You can stop using a connector at any time. To delete a connector, you must " "remove it from each linked Watchlist.\n" @@ -372,7 +372,7 @@ msgstr "" "Widerrufsrecht verzichten und das Mindestalter für die Zustimmung zu diesen " "Bedingungen erreicht haben." -#: assets/components/tracking/connector/ConnectorsList.tsx:56 +#: assets/components/tracking/connector/ConnectorsList.tsx:57 msgid "The Provider’s conditions are accessible by following this hyperlink." msgstr "Die Bedingungen des Providers sind über diesen Hyperlink zugänglich." @@ -428,7 +428,7 @@ msgstr "Möchten Sie diese Watchlist wirklich deaktivieren?" msgid "Enable the Watchlist" msgstr "Aktivieren Sie die Beobachtungsliste" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:29 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:30 msgid "" "At least one domain name is in redemption period and will potentially be " "deleted soon" @@ -436,7 +436,7 @@ msgstr "" "Mindestens ein Domainname befindet sich im Einlösezeitraum und könnte bald " "gelöscht werden" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:37 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:39 msgid "" "At least one domain name is pending deletion and will soon become available " "for registration again" @@ -444,46 +444,46 @@ msgstr "" "Mindestens ein Domänenname steht zur Löschung an und wird bald wieder zur " "Registrierung verfügbar sein" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:143 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:147 msgid "Estimated number of days until WHOIS removal" msgstr "Geschätzte Anzahl von Tagen bis zur WHOIS-Entfernung" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:146 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:150 #, javascript-format msgid "J ${ expiresInDays }" msgstr "J ${ expiresInDays }" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:152 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:156 msgid "Deletion is imminent" msgstr "Löschung steht unmittelbar bevor" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:181 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:185 msgid "Status" msgstr "Status" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:187 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:191 msgid "Options" msgstr "Optionen" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:193 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:197 msgid "Expiration date" msgstr "Verfallsdatum" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:207 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:211 msgid "Updated at" msgstr "Aktualisiert am" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:235 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:240 msgid "No tracked domain names were found, please create your first Watchlist" msgstr "" "Es wurden keine getrackten Domainnamen gefunden, bitte erstellen Sie Ihre " "erste Watchlist" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:238 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:243 msgid "Create now" msgstr "Jetzt erstellen" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:244 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 msgid "" "Please note that this table does not include domain names marked as expired " "or those with an unknown expiration date" @@ -491,13 +491,13 @@ msgstr "" "Bitte beachten Sie, dass diese Tabelle keine Domänennamen enthält, die als " "abgelaufen markiert sind oder deren Ablaufdatum unbekannt ist" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:254 msgid "At least one domain name you are tracking requires special attention" msgstr "" "Mindestens ein Domänenname, den Sie verfolgen, erfordert besondere " "Aufmerksamkeit" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:255 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:260 msgid "The domain names below are subject to special monitoring" msgstr "" "Die unten aufgeführten Domänennamen unterliegen einer besonderen Überwachung" @@ -510,10 +510,6 @@ msgstr "Bearbeiten der Watchlist" msgid "Update a Watchlist" msgstr "Aktualisieren einer Watchlist" -#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 -msgid "Cancel" -msgstr "Abbrechen" - #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." msgstr "Diese Beobachtungsliste ist nicht mit einem Connector verknüpft." @@ -610,11 +606,11 @@ msgstr "Aktualisieren" msgid "Reset" msgstr "Zurücksetzen" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:43 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:45 msgid "ID" msgstr "ID" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:77 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:80 msgid "" "An accredited number means that ICANN's contract with the registrar is " "ongoing." @@ -622,14 +618,14 @@ msgstr "" "Eine akkreditierte Nummer bedeutet, dass der Vertrag zwischen ICANN und dem " "Registrar weiterhin besteht." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:82 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:85 msgid "" "A reserved number can be used by TLD registries for specific operations." msgstr "" "Eine reservierte Nummer kann von TLD-Registrierungen für bestimmte Vorgänge " "verwendet werden." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:87 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:90 msgid "" "A terminated number means that ICANN's contract with the registrar has been " "terminated." @@ -637,12 +633,12 @@ msgstr "" "Eine gekündigte Nummer bedeutet, dass der Vertrag zwischen ICANN und dem " "Registrar gekündigt wurde." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:96 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 msgid "This page lists ICANN-accredited registrars." msgstr "" "Auf dieser Seite sind die von der ICANN akkreditierten Registrare aufgeführt." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:102 msgid "" "The list is officially published and maintained by the Internet Assigned " "Numbers Authority (IANA), the organization responsible for managing the " @@ -654,34 +650,34 @@ msgstr "" "eindeutigen Kennungen des Internets (einschließlich Nummern, IP-Adressen und " "Domänennamenerweiterungen) verantwortlich ist." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:111 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:114 #: assets/utils/functions/rdapTranslation.ts:125 msgid "Accredited" msgstr "Akkreditiert" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:116 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:119 #: assets/utils/functions/rdapTranslation.ts:126 msgid "Reserved" msgstr "Reserviert" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:121 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:124 #: assets/utils/functions/rdapTranslation.ts:124 msgid "Terminated" msgstr "Beendet" -#: assets/pages/infrastructure/TldPage.tsx:86 +#: assets/pages/infrastructure/TldPage.tsx:88 msgid "Flag" msgstr "Landesflagge" -#: assets/pages/infrastructure/TldPage.tsx:89 +#: assets/pages/infrastructure/TldPage.tsx:91 msgid "Country" msgstr "Land" -#: assets/pages/infrastructure/TldPage.tsx:96 +#: assets/pages/infrastructure/TldPage.tsx:98 msgid "Registry Operator" msgstr "Registrierungsbetreiber" -#: assets/pages/infrastructure/TldPage.tsx:124 +#: assets/pages/infrastructure/TldPage.tsx:127 msgid "" "Top-level domains sponsored by specific organizations that set rules for " "registration and use, often related to particular interest groups or " @@ -691,7 +687,7 @@ msgstr "" "Regeln für die Registrierung und Nutzung festlegen und oft mit bestimmten " "Interessengruppen oder Branchen in Zusammenhang stehen." -#: assets/pages/infrastructure/TldPage.tsx:129 +#: assets/pages/infrastructure/TldPage.tsx:132 msgid "" "Generic top-level domains open to everyone, not restricted by specific " "criteria, representing various themes or industries." @@ -700,7 +696,7 @@ msgstr "" "bestimmte Kriterien eingeschränkt sind und verschiedene Themen oder Branchen " "repräsentieren." -#: assets/pages/infrastructure/TldPage.tsx:134 +#: assets/pages/infrastructure/TldPage.tsx:137 msgid "" "Generic top-level domains associated with specific brands, allowing " "companies to use their own brand names as domains." @@ -708,7 +704,7 @@ msgstr "" "Generische Top-Level-Domains sind mit bestimmten Marken verknüpft und " "ermöglichen Unternehmen die Verwendung ihrer eigenen Markennamen als Domains." -#: assets/pages/infrastructure/TldPage.tsx:139 +#: assets/pages/infrastructure/TldPage.tsx:142 msgid "" "Top-level domains based on country codes, identifying websites according to " "their country of origin." @@ -716,13 +712,13 @@ msgstr "" "Top-Level-Domains basieren auf Ländercodes und identifizieren Websites " "entsprechend ihrem Herkunftsland." -#: assets/pages/infrastructure/TldPage.tsx:148 +#: assets/pages/infrastructure/TldPage.tsx:151 msgid "This page presents all active TLDs in the root zone database." msgstr "" "Auf dieser Seite werden alle aktiven TLDs in der Root-Zone-Datenbank " "angezeigt." -#: assets/pages/infrastructure/TldPage.tsx:151 +#: assets/pages/infrastructure/TldPage.tsx:154 msgid "" "IANA provides the list of currently active TLDs, regardless of their type, " "and ICANN provides the list of gTLDs.\n" @@ -742,23 +738,23 @@ msgstr "" "erforderlich (zwei Anfragen an IANA und eine an ICANN).\n" " Gleichzeitig wird die Liste der Root-RDAP-Server aktualisiert." -#: assets/pages/infrastructure/TldPage.tsx:166 +#: assets/pages/infrastructure/TldPage.tsx:169 msgid "Generic Top-Level-Domains" msgstr "Generische Top-Level-Domains" -#: assets/pages/infrastructure/TldPage.tsx:171 +#: assets/pages/infrastructure/TldPage.tsx:174 msgid "Country-Code Top-Level-Domains" msgstr "Länderspezifische Top-Level-Domains" -#: assets/pages/infrastructure/TldPage.tsx:176 +#: assets/pages/infrastructure/TldPage.tsx:179 msgid "Brand Generic Top-Level-Domains" msgstr "Markengenerische Top-Level-Domains" -#: assets/pages/infrastructure/TldPage.tsx:181 +#: assets/pages/infrastructure/TldPage.tsx:184 msgid "Sponsored Top-Level-Domains" msgstr "Gesponserte Top-Level-Domains" -#: assets/pages/LoginPage.tsx:45 +#: assets/pages/LoginPage.tsx:46 msgid "Create an account" msgstr "Ein Konto erstellen" @@ -1744,6 +1740,9 @@ msgstr "" "Sind Sie sich bei dieser Einstellung sicher? Dies kann zu zusätzlichen " "Gebühren durch den API-Anbieter führen" +#~ msgid "Cancel" +#~ msgstr "Abbrechen" + #~ msgid "Entity" #~ msgstr "Entität" diff --git a/translations/fr.po b/translations/fr.po index 3b7b9bd..ab39731 100644 --- a/translations/fr.po +++ b/translations/fr.po @@ -11,23 +11,23 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.13.2\n" -#: assets/App.tsx:120 +#: assets/App.tsx:161 msgid "TOS" msgstr "CGU" -#: assets/App.tsx:121 +#: assets/App.tsx:162 msgid "Privacy Policy" msgstr "Politique de confidentialité" -#: assets/App.tsx:122 +#: assets/App.tsx:163 msgid "FAQ" msgstr "FAQ" -#: assets/App.tsx:129 +#: assets/App.tsx:170 msgid "Documentation" msgstr "Documentation" -#: assets/App.tsx:134 +#: assets/App.tsx:175 #, javascript-format msgid "" "${ ProjectLink } is an open source project distributed under the $" @@ -36,19 +36,19 @@ msgstr "" "${ ProjectLink } est un projet open source distribué sous licence $" "{ LicenseLink }." -#: assets/App.tsx:147 +#: assets/App.tsx:188 msgid "Official git repository" msgstr "Dépôt git officiel" -#: assets/App.tsx:150 +#: assets/App.tsx:191 msgid "Submit an issue" msgstr "Signaler un bug" -#: assets/components/LoginForm.tsx:48 assets/components/RegisterForm.tsx:37 +#: assets/components/LoginForm.tsx:53 assets/components/RegisterForm.tsx:37 msgid "Email address" msgstr "Adresse e-mail" -#: assets/components/LoginForm.tsx:50 assets/components/LoginForm.tsx:58 +#: assets/components/LoginForm.tsx:55 assets/components/LoginForm.tsx:63 #: assets/components/RegisterForm.tsx:39 assets/components/RegisterForm.tsx:47 #: assets/components/search/DomainSearchBar.tsx:28 #: assets/components/tracking/watchlist/WatchlistForm.tsx:155 @@ -79,20 +79,20 @@ msgstr "Adresse e-mail" msgid "Required" msgstr "Requis" -#: assets/components/LoginForm.tsx:56 assets/components/RegisterForm.tsx:45 +#: assets/components/LoginForm.tsx:61 assets/components/RegisterForm.tsx:45 #: assets/utils/providers/forms/EppConnectorForm.tsx:138 msgid "Password" msgstr "Mot de passe" -#: assets/components/LoginForm.tsx:66 +#: assets/components/LoginForm.tsx:70 msgid "Submit" msgstr "Se connecter" -#: assets/components/LoginForm.tsx:71 +#: assets/components/LoginForm.tsx:74 msgid "Log in with SSO" msgstr "Se connecter par SSO" -#: assets/components/RegisterForm.tsx:54 assets/pages/LoginPage.tsx:35 +#: assets/components/RegisterForm.tsx:54 assets/pages/LoginPage.tsx:60 msgid "Register" msgstr "S'enregistrer" @@ -102,22 +102,22 @@ msgid "Registration" msgstr "Enregistrement" #: assets/components/search/DomainLifecycleSteps.tsx:24 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:133 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:137 msgid "Active" msgstr "Actif" #: assets/components/search/DomainLifecycleSteps.tsx:29 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:111 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:115 msgid "Auto-Renew Grace Period" msgstr "Période de grâce" #: assets/components/search/DomainLifecycleSteps.tsx:35 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:119 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:123 msgid "Redemption Grace Period" msgstr "Période de rédemption" #: assets/components/search/DomainLifecycleSteps.tsx:40 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:127 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:131 msgid "Pending Delete" msgstr "En attente de suppression" @@ -132,7 +132,7 @@ msgstr "" "registre" #: assets/components/search/DomainResult.tsx:64 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:89 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:93 msgid "Registry Lock" msgstr "Verrouillage du registre" @@ -145,7 +145,7 @@ msgstr "" "ou accidentelles grâce aux contrôles du bureau d'enregistrement" #: assets/components/search/DomainResult.tsx:75 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:95 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:99 msgid "Registrar Lock" msgstr "Verrouillage du bureau d'enregistrement" @@ -159,12 +159,12 @@ msgstr "" "réponses" #: assets/components/search/DomainResult.tsx:84 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:101 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:105 msgid "DNSSEC" msgstr "DNSSEC" #: assets/components/search/DomainResult.tsx:90 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:215 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:219 msgid "EPP Status Codes" msgstr "Codes de statut EPP" @@ -190,7 +190,7 @@ msgid "Search" msgstr "Rechercher" #: assets/components/Sider.tsx:43 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:175 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:179 msgid "Domain" msgstr "Domaine" @@ -203,7 +203,7 @@ msgid "Infrastructure" msgstr "Infrastructure" #: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:114 -#: assets/pages/infrastructure/TldPage.tsx:79 +#: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "TLD" @@ -258,13 +258,13 @@ msgstr "Mon compte" msgid "Log out" msgstr "Se déconnecter" -#: assets/components/Sider.tsx:154 assets/pages/LoginPage.tsx:35 -#: assets/pages/LoginPage.tsx:45 +#: assets/components/Sider.tsx:154 assets/pages/LoginPage.tsx:46 +#: assets/pages/LoginPage.tsx:60 msgid "Log in" msgstr "Se connecter" #: assets/components/tracking/connector/ConnectorForm.tsx:36 -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:49 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:51 #: assets/utils/functions/rdapTranslation.ts:12 msgid "Registrar" msgstr "Bureau d'enregistrement" @@ -346,17 +346,17 @@ msgstr "Oui" msgid "No" msgstr "Non" -#: assets/components/tracking/connector/ConnectorsList.tsx:48 +#: assets/components/tracking/connector/ConnectorsList.tsx:49 #, javascript-format msgid "Creation date: ${ createdAt }" msgstr "Date de création : ${ createdAt }" -#: assets/components/tracking/connector/ConnectorsList.tsx:49 +#: assets/components/tracking/connector/ConnectorsList.tsx:50 #, javascript-format msgid "Used in: ${ watchlistCount } Watchlist" msgstr "Utilisé dans : ${ watchlistCount } Watchlist" -#: assets/components/tracking/connector/ConnectorsList.tsx:52 +#: assets/components/tracking/connector/ConnectorsList.tsx:53 msgid "" "You can stop using a connector at any time. To delete a connector, you must " "remove it from each linked Watchlist.\n" @@ -373,7 +373,7 @@ msgstr "" "droit de rétractation et que vous aviez l'âge minimum pour consentir à ces " "conditions." -#: assets/components/tracking/connector/ConnectorsList.tsx:56 +#: assets/components/tracking/connector/ConnectorsList.tsx:57 msgid "The Provider’s conditions are accessible by following this hyperlink." msgstr "" "Les conditions du fournisseur d'API sont accessibles en suivant ce lien " @@ -431,7 +431,7 @@ msgstr "Êtes-vous sûr de vouloir désactiver cette Watchlist ?" msgid "Enable the Watchlist" msgstr "Activer la Watchlist" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:29 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:30 msgid "" "At least one domain name is in redemption period and will potentially be " "deleted soon" @@ -439,7 +439,7 @@ msgstr "" "Au moins un nom de domaine est en période de rédemption et sera " "potentiellement supprimé prochainement" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:37 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:39 msgid "" "At least one domain name is pending deletion and will soon become available " "for registration again" @@ -447,46 +447,46 @@ msgstr "" "Au moins un nom de domaine est en attente de suppression et sera bientôt à " "nouveau disponible pour l'enregistrement" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:143 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:147 msgid "Estimated number of days until WHOIS removal" msgstr "Estimation du nombre de jours avant la suppression du WHOIS" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:146 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:150 #, javascript-format msgid "J ${ expiresInDays }" msgstr "J ${ expiresInDays }" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:152 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:156 msgid "Deletion is imminent" msgstr "La suppression est imminente" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:181 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:185 msgid "Status" msgstr "Statut" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:187 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:191 msgid "Options" msgstr "Options" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:193 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:197 msgid "Expiration date" msgstr "Date d'expiration" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:207 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:211 msgid "Updated at" msgstr "Mis à jour le" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:235 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:240 msgid "No tracked domain names were found, please create your first Watchlist" msgstr "" "Aucun nom de domaine suivi n'a été trouvé, veuillez créer votre première " "Watchlist" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:238 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:243 msgid "Create now" msgstr "Créer maintenant" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:244 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 msgid "" "Please note that this table does not include domain names marked as expired " "or those with an unknown expiration date" @@ -494,13 +494,13 @@ msgstr "" "Veuillez noter que ce tableau n'inclut pas les noms de domaine marqués comme " "expirés ou ceux dont la date d'expiration est inconnue" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:254 msgid "At least one domain name you are tracking requires special attention" msgstr "" "Au moins un nom de domaine que vous suivez nécessite une attention " "particulière" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:255 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:260 msgid "The domain names below are subject to special monitoring" msgstr "" "Les noms de domaine ci-dessous font l'objet d'une surveillance particulière" @@ -513,10 +513,6 @@ msgstr "Modifier la Watchlist" msgid "Update a Watchlist" msgstr "Mise à jour d'une Watchlist" -#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 -msgid "Cancel" -msgstr "Annuler" - #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." msgstr "Cette Watchlist n'est pas liée à un connecteur." @@ -613,11 +609,11 @@ msgstr "Mettre à jour" msgid "Reset" msgstr "Réinitialiser" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:43 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:45 msgid "ID" msgstr "ID" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:77 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:80 msgid "" "An accredited number means that ICANN's contract with the registrar is " "ongoing." @@ -625,14 +621,14 @@ msgstr "" "Un numéro accrédité signifie que le contrat de l'ICANN avec le bureau " "d'enregistrement est en cours." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:82 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:85 msgid "" "A reserved number can be used by TLD registries for specific operations." msgstr "" "Un numéro réservé peut être utilisé par les registres des TLD pour des " "opérations spécifiques." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:87 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:90 msgid "" "A terminated number means that ICANN's contract with the registrar has been " "terminated." @@ -640,12 +636,12 @@ msgstr "" "Un numéro résilié signifie que le contrat de l'ICANN avec le bureau " "d'enregistrement est terminé." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:96 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 msgid "This page lists ICANN-accredited registrars." msgstr "" "Cette page répertorie les bureaux d'enregistrement accrédités par l'ICANN." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:102 msgid "" "The list is officially published and maintained by the Internet Assigned " "Numbers Authority (IANA), the organization responsible for managing the " @@ -657,34 +653,34 @@ msgstr "" "identifiants uniques d'Internet (y compris les numéros, les adresses IP et " "les extensions de noms de domaine)." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:111 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:114 #: assets/utils/functions/rdapTranslation.ts:125 msgid "Accredited" msgstr "Accrédité" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:116 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:119 #: assets/utils/functions/rdapTranslation.ts:126 msgid "Reserved" msgstr "Réservé" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:121 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:124 #: assets/utils/functions/rdapTranslation.ts:124 msgid "Terminated" msgstr "Terminé" -#: assets/pages/infrastructure/TldPage.tsx:86 +#: assets/pages/infrastructure/TldPage.tsx:88 msgid "Flag" msgstr "Drapeau" -#: assets/pages/infrastructure/TldPage.tsx:89 +#: assets/pages/infrastructure/TldPage.tsx:91 msgid "Country" msgstr "Pays" -#: assets/pages/infrastructure/TldPage.tsx:96 +#: assets/pages/infrastructure/TldPage.tsx:98 msgid "Registry Operator" msgstr "Opérateur de registre" -#: assets/pages/infrastructure/TldPage.tsx:124 +#: assets/pages/infrastructure/TldPage.tsx:127 msgid "" "Top-level domains sponsored by specific organizations that set rules for " "registration and use, often related to particular interest groups or " @@ -694,7 +690,7 @@ msgstr "" "établissent des règles d'enregistrement et d'utilisation, souvent liées à " "des groupes d'intérêt ou à des secteurs particuliers." -#: assets/pages/infrastructure/TldPage.tsx:129 +#: assets/pages/infrastructure/TldPage.tsx:132 msgid "" "Generic top-level domains open to everyone, not restricted by specific " "criteria, representing various themes or industries." @@ -703,7 +699,7 @@ msgstr "" "critères spécifiques, représentant des thèmes ou des secteurs d'activité " "variés." -#: assets/pages/infrastructure/TldPage.tsx:134 +#: assets/pages/infrastructure/TldPage.tsx:137 msgid "" "Generic top-level domains associated with specific brands, allowing " "companies to use their own brand names as domains." @@ -712,7 +708,7 @@ msgstr "" "permettant aux entreprises d'utiliser leurs propres noms de marque comme " "domaines." -#: assets/pages/infrastructure/TldPage.tsx:139 +#: assets/pages/infrastructure/TldPage.tsx:142 msgid "" "Top-level domains based on country codes, identifying websites according to " "their country of origin." @@ -720,11 +716,11 @@ msgstr "" "Domaines de premier niveau basés sur les codes de pays, identifiant les " "sites web en fonction de leur pays d'origine." -#: assets/pages/infrastructure/TldPage.tsx:148 +#: assets/pages/infrastructure/TldPage.tsx:151 msgid "This page presents all active TLDs in the root zone database." msgstr "Cette page présente tous les TLD actifs dans la zone racine." -#: assets/pages/infrastructure/TldPage.tsx:151 +#: assets/pages/infrastructure/TldPage.tsx:154 msgid "" "IANA provides the list of currently active TLDs, regardless of their type, " "and ICANN provides the list of gTLDs.\n" @@ -744,23 +740,23 @@ msgstr "" "requêtes à l'IANA et une à l'ICANN).\n" "Parallèlement, la liste des serveurs RDAP racine est mise à jour." -#: assets/pages/infrastructure/TldPage.tsx:166 +#: assets/pages/infrastructure/TldPage.tsx:169 msgid "Generic Top-Level-Domains" msgstr "Domaines de premier niveau générique" -#: assets/pages/infrastructure/TldPage.tsx:171 +#: assets/pages/infrastructure/TldPage.tsx:174 msgid "Country-Code Top-Level-Domains" msgstr "Domaines de premier niveau national" -#: assets/pages/infrastructure/TldPage.tsx:176 +#: assets/pages/infrastructure/TldPage.tsx:179 msgid "Brand Generic Top-Level-Domains" msgstr "Domaines de premier niveau générique de marque" -#: assets/pages/infrastructure/TldPage.tsx:181 +#: assets/pages/infrastructure/TldPage.tsx:184 msgid "Sponsored Top-Level-Domains" msgstr "Domaines de premier niveau parrainés" -#: assets/pages/LoginPage.tsx:45 +#: assets/pages/LoginPage.tsx:46 msgid "Create an account" msgstr "Créer un compte" @@ -1743,6 +1739,9 @@ msgstr "" "Êtes-vous sûr de ce paramètre ? Cela peut entraîner des frais " "supplémentaires de la part du fournisseur d'API" +#~ msgid "Cancel" +#~ msgstr "Annuler" + #~ msgid "Entity" #~ msgstr "Entité" diff --git a/translations/sv.po b/translations/sv.po index f91fce8..861d4a2 100644 --- a/translations/sv.po +++ b/translations/sv.po @@ -10,23 +10,23 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.13.2\n" -#: assets/App.tsx:120 +#: assets/App.tsx:161 msgid "TOS" msgstr "Användarvillkor" -#: assets/App.tsx:121 +#: assets/App.tsx:162 msgid "Privacy Policy" msgstr "Integritetspolicy" -#: assets/App.tsx:122 +#: assets/App.tsx:163 msgid "FAQ" msgstr "Vanliga frågor" -#: assets/App.tsx:129 +#: assets/App.tsx:170 msgid "Documentation" msgstr "Dokumentation" -#: assets/App.tsx:134 +#: assets/App.tsx:175 #, javascript-format msgid "" "${ ProjectLink } is an open source project distributed under the $" @@ -35,19 +35,19 @@ msgstr "" "${ ProjectLink } är ett projekt med öppen källkod som distribueras under " "licensen ${ LicenseLink }." -#: assets/App.tsx:147 +#: assets/App.tsx:188 msgid "Official git repository" msgstr "Officiellt git-arkiv" -#: assets/App.tsx:150 +#: assets/App.tsx:191 msgid "Submit an issue" msgstr "Skicka in ett ärende" -#: assets/components/LoginForm.tsx:48 assets/components/RegisterForm.tsx:37 +#: assets/components/LoginForm.tsx:53 assets/components/RegisterForm.tsx:37 msgid "Email address" msgstr "E-postadress" -#: assets/components/LoginForm.tsx:50 assets/components/LoginForm.tsx:58 +#: assets/components/LoginForm.tsx:55 assets/components/LoginForm.tsx:63 #: assets/components/RegisterForm.tsx:39 assets/components/RegisterForm.tsx:47 #: assets/components/search/DomainSearchBar.tsx:28 #: assets/components/tracking/watchlist/WatchlistForm.tsx:155 @@ -78,20 +78,20 @@ msgstr "E-postadress" msgid "Required" msgstr "Nödvändig" -#: assets/components/LoginForm.tsx:56 assets/components/RegisterForm.tsx:45 +#: assets/components/LoginForm.tsx:61 assets/components/RegisterForm.tsx:45 #: assets/utils/providers/forms/EppConnectorForm.tsx:138 msgid "Password" msgstr "Lösenord" -#: assets/components/LoginForm.tsx:66 +#: assets/components/LoginForm.tsx:70 msgid "Submit" msgstr "Skicka in" -#: assets/components/LoginForm.tsx:71 +#: assets/components/LoginForm.tsx:74 msgid "Log in with SSO" msgstr "Logga in med SSO" -#: assets/components/RegisterForm.tsx:54 assets/pages/LoginPage.tsx:35 +#: assets/components/RegisterForm.tsx:54 assets/pages/LoginPage.tsx:60 msgid "Register" msgstr "Register" @@ -101,22 +101,22 @@ msgid "Registration" msgstr "Registrering" #: assets/components/search/DomainLifecycleSteps.tsx:24 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:133 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:137 msgid "Active" msgstr "Aktiv" #: assets/components/search/DomainLifecycleSteps.tsx:29 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:111 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:115 msgid "Auto-Renew Grace Period" msgstr "Automatisk förnyelse under respitperioden" #: assets/components/search/DomainLifecycleSteps.tsx:35 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:119 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:123 msgid "Redemption Grace Period" msgstr "Period av nådens återlösning" #: assets/components/search/DomainLifecycleSteps.tsx:40 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:127 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:131 msgid "Pending Delete" msgstr "Väntar på radering" @@ -131,7 +131,7 @@ msgstr "" "registernivå" #: assets/components/search/DomainResult.tsx:64 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:89 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:93 msgid "Registry Lock" msgstr "Registry Lock" @@ -144,7 +144,7 @@ msgstr "" "oavsiktliga ändringar genom registrarens kontrollfunktioner" #: assets/components/search/DomainResult.tsx:75 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:95 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:99 msgid "Registrar Lock" msgstr "Registrar Lock" @@ -157,12 +157,12 @@ msgstr "" "poster, vilket säkerställer äkthet och integritet hos svaren" #: assets/components/search/DomainResult.tsx:84 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:101 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:105 msgid "DNSSEC" msgstr "DNSSEC" #: assets/components/search/DomainResult.tsx:90 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:215 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:219 msgid "EPP Status Codes" msgstr "EPP-statuskoder" @@ -188,7 +188,7 @@ msgid "Search" msgstr "Sök" #: assets/components/Sider.tsx:43 -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:175 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:179 msgid "Domain" msgstr "Domännamn" @@ -201,7 +201,7 @@ msgid "Infrastructure" msgstr "Infrastruktur" #: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:114 -#: assets/pages/infrastructure/TldPage.tsx:79 +#: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "TLD" @@ -256,13 +256,13 @@ msgstr "Mitt konto" msgid "Log out" msgstr "Logga ut" -#: assets/components/Sider.tsx:154 assets/pages/LoginPage.tsx:35 -#: assets/pages/LoginPage.tsx:45 +#: assets/components/Sider.tsx:154 assets/pages/LoginPage.tsx:46 +#: assets/pages/LoginPage.tsx:60 msgid "Log in" msgstr "Logga in" #: assets/components/tracking/connector/ConnectorForm.tsx:36 -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:49 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:51 #: assets/utils/functions/rdapTranslation.ts:12 msgid "Registrar" msgstr "Registrar" @@ -342,17 +342,17 @@ msgstr "Ja" msgid "No" msgstr "Nej" -#: assets/components/tracking/connector/ConnectorsList.tsx:48 +#: assets/components/tracking/connector/ConnectorsList.tsx:49 #, javascript-format msgid "Creation date: ${ createdAt }" msgstr "Skapandedatum: ${ createdAt }" -#: assets/components/tracking/connector/ConnectorsList.tsx:49 +#: assets/components/tracking/connector/ConnectorsList.tsx:50 #, javascript-format msgid "Used in: ${ watchlistCount } Watchlist" msgstr "Används i: ${ watchlistCount } Watchlist" -#: assets/components/tracking/connector/ConnectorsList.tsx:52 +#: assets/components/tracking/connector/ConnectorsList.tsx:53 msgid "" "You can stop using a connector at any time. To delete a connector, you must " "remove it from each linked Watchlist.\n" @@ -368,7 +368,7 @@ msgstr "" "användning av leverantörens API, avstod från ångerrätten och var i den " "lägsta åldern för att samtycka till dessa villkor." -#: assets/components/tracking/connector/ConnectorsList.tsx:56 +#: assets/components/tracking/connector/ConnectorsList.tsx:57 msgid "The Provider’s conditions are accessible by following this hyperlink." msgstr "Leverantörens villkor är tillgängliga genom att följa denna hyperlänk." @@ -424,7 +424,7 @@ msgstr "Är du säker på att inaktivera den här Watchlist?" msgid "Enable the Watchlist" msgstr "Aktivera bevakningslistan" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:29 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:30 msgid "" "At least one domain name is in redemption period and will potentially be " "deleted soon" @@ -432,7 +432,7 @@ msgstr "" "Minst ett domännamn är under inlösenperiod och kommer eventuellt att raderas " "inom kort" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:37 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:39 msgid "" "At least one domain name is pending deletion and will soon become available " "for registration again" @@ -440,44 +440,44 @@ msgstr "" "Minst ett domännamn väntar på radering och kommer snart att bli tillgängligt " "för registrering igen" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:143 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:147 msgid "Estimated number of days until WHOIS removal" msgstr "Uppskattat antal dagar till borttagning av WHOIS" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:146 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:150 #, javascript-format msgid "J ${ expiresInDays }" msgstr "J ${ expiresInDays }" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:152 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:156 msgid "Deletion is imminent" msgstr "Radering är nära förestående" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:181 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:185 msgid "Status" msgstr "Status" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:187 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:191 msgid "Options" msgstr "Alternativ" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:193 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:197 msgid "Expiration date" msgstr "Utgångsdatum" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:207 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:211 msgid "Updated at" msgstr "Uppdaterad på" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:235 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:240 msgid "No tracked domain names were found, please create your first Watchlist" msgstr "Inga spårade domännamn hittades, vänligen skapa din första Watchlist" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:238 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:243 msgid "Create now" msgstr "Skapa nu" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:244 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 msgid "" "Please note that this table does not include domain names marked as expired " "or those with an unknown expiration date" @@ -485,11 +485,11 @@ msgstr "" "Observera att den här tabellen inte inkluderar domännamn markerade som " "utgångna eller de med okänt utgångsdatum" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:254 msgid "At least one domain name you are tracking requires special attention" msgstr "Minst ett domännamn som du spårar kräver särskild uppmärksamhet" -#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:255 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:260 msgid "The domain names below are subject to special monitoring" msgstr "Domännamnen nedan är föremål för särskild övervakning" @@ -501,10 +501,6 @@ msgstr "Redigera bevakningslistan" msgid "Update a Watchlist" msgstr "Uppdatera en bevakningslista" -#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:56 -msgid "Cancel" -msgstr "Avboka" - #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." msgstr "Denna Watchlist är inte kopplad till en Connector." @@ -599,35 +595,35 @@ msgstr "Uppdatera" msgid "Reset" msgstr "Återställa" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:43 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:45 msgid "ID" msgstr "ID" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:77 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:80 msgid "" "An accredited number means that ICANN's contract with the registrar is " "ongoing." msgstr "" "Ett ackrediterat nummer innebär att ICANNs avtal med registraren löper." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:82 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:85 msgid "" "A reserved number can be used by TLD registries for specific operations." msgstr "" "Ett reserverat nummer kan användas av TLD-registren för specifika åtgärder." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:87 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:90 msgid "" "A terminated number means that ICANN's contract with the registrar has been " "terminated." msgstr "" "Ett uppsagt nummer innebär att ICANNs avtal med registraren har sagts upp." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:96 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 msgid "This page lists ICANN-accredited registrars." msgstr "Den här sidan listar ICANN-ackrediterade registrarer." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:102 msgid "" "The list is officially published and maintained by the Internet Assigned " "Numbers Authority (IANA), the organization responsible for managing the " @@ -638,34 +634,34 @@ msgstr "" "Authority (IANA), den organisation som ansvarar för att hantera internets " "unika identifierare (inklusive nummer, IP-adresser och domännamnstillägg)." -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:111 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:114 #: assets/utils/functions/rdapTranslation.ts:125 msgid "Accredited" msgstr "Ackrediterad" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:116 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:119 #: assets/utils/functions/rdapTranslation.ts:126 msgid "Reserved" msgstr "Reserverad" -#: assets/pages/infrastructure/IcannRegistrarPage.tsx:121 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:124 #: assets/utils/functions/rdapTranslation.ts:124 msgid "Terminated" msgstr "Avslutad" -#: assets/pages/infrastructure/TldPage.tsx:86 +#: assets/pages/infrastructure/TldPage.tsx:88 msgid "Flag" msgstr "Flagga" -#: assets/pages/infrastructure/TldPage.tsx:89 +#: assets/pages/infrastructure/TldPage.tsx:91 msgid "Country" msgstr "Land" -#: assets/pages/infrastructure/TldPage.tsx:96 +#: assets/pages/infrastructure/TldPage.tsx:98 msgid "Registry Operator" msgstr "Registeroperatör" -#: assets/pages/infrastructure/TldPage.tsx:124 +#: assets/pages/infrastructure/TldPage.tsx:127 msgid "" "Top-level domains sponsored by specific organizations that set rules for " "registration and use, often related to particular interest groups or " @@ -675,7 +671,7 @@ msgstr "" "för registrering och användning, ofta relaterade till särskilda " "intressegrupper eller branscher." -#: assets/pages/infrastructure/TldPage.tsx:129 +#: assets/pages/infrastructure/TldPage.tsx:132 msgid "" "Generic top-level domains open to everyone, not restricted by specific " "criteria, representing various themes or industries." @@ -683,7 +679,7 @@ msgstr "" "Generiska toppdomäner som är öppna för alla, inte begränsade av specifika " "kriterier, och som representerar olika teman eller branscher." -#: assets/pages/infrastructure/TldPage.tsx:134 +#: assets/pages/infrastructure/TldPage.tsx:137 msgid "" "Generic top-level domains associated with specific brands, allowing " "companies to use their own brand names as domains." @@ -691,7 +687,7 @@ msgstr "" "Generiska toppdomäner associerade med specifika varumärken, vilket gör det " "möjligt för företag att använda sina egna varumärken som domäner." -#: assets/pages/infrastructure/TldPage.tsx:139 +#: assets/pages/infrastructure/TldPage.tsx:142 msgid "" "Top-level domains based on country codes, identifying websites according to " "their country of origin." @@ -699,11 +695,11 @@ msgstr "" "Toppdomäner baserade på landskoder, som identifierar webbplatser enligt " "deras ursprungsland." -#: assets/pages/infrastructure/TldPage.tsx:148 +#: assets/pages/infrastructure/TldPage.tsx:151 msgid "This page presents all active TLDs in the root zone database." msgstr "Den här sidan presenterar alla aktiva toppdomäner i rotzondatabasen." -#: assets/pages/infrastructure/TldPage.tsx:151 +#: assets/pages/infrastructure/TldPage.tsx:154 msgid "" "IANA provides the list of currently active TLDs, regardless of their type, " "and ICANN provides the list of gTLDs.\n" @@ -723,23 +719,23 @@ msgstr "" "till IANA och en till ICANN).\n" " Samtidigt uppdateras listan över RDAP-rootservrar." -#: assets/pages/infrastructure/TldPage.tsx:166 +#: assets/pages/infrastructure/TldPage.tsx:169 msgid "Generic Top-Level-Domains" msgstr "Generiska toppdomäner" -#: assets/pages/infrastructure/TldPage.tsx:171 +#: assets/pages/infrastructure/TldPage.tsx:174 msgid "Country-Code Top-Level-Domains" msgstr "Landskod Toppdomäner" -#: assets/pages/infrastructure/TldPage.tsx:176 +#: assets/pages/infrastructure/TldPage.tsx:179 msgid "Brand Generic Top-Level-Domains" msgstr "Generiska toppdomäner för varumärken" -#: assets/pages/infrastructure/TldPage.tsx:181 +#: assets/pages/infrastructure/TldPage.tsx:184 msgid "Sponsored Top-Level-Domains" msgstr "Sponsrade toppdomäner" -#: assets/pages/LoginPage.tsx:45 +#: assets/pages/LoginPage.tsx:46 msgid "Create an account" msgstr "Skapa ett konto" @@ -1696,6 +1692,9 @@ msgstr "" "Är du säker på den här inställningen? Detta kan resultera i ytterligare " "avgifter från API-leverantören" +#~ msgid "Cancel" +#~ msgstr "Avboka" + #~ msgid "Entity" #~ msgstr "Enhet" From c3832f06c3d548a6ff01db6e8c3b218d17fcbc23 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 18:31:00 +0100 Subject: [PATCH 052/131] feat: move floating buttons to footer --- assets/App.tsx | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/assets/App.tsx b/assets/App.tsx index 75559a9..9e6c203 100644 --- a/assets/App.tsx +++ b/assets/App.tsx @@ -1,4 +1,4 @@ -import {Button, ConfigProvider, Drawer, Flex, FloatButton, Layout, theme, Tooltip, Typography} from 'antd' +import {Button, ConfigProvider, Drawer, Flex, Layout, theme, Typography} from 'antd' import {Link, Navigate, Route, Routes, useLocation, useNavigate} from 'react-router-dom' import TextPage from './pages/TextPage' import DomainSearchPage from './pages/search/DomainSearchPage' @@ -16,7 +16,7 @@ import NotFoundPage from './pages/NotFoundPage' import useBreakpoint from './hooks/useBreakpoint' import {Sider} from './components/Sider' import {jt, t} from 'ttag' -import {BugOutlined, InfoCircleOutlined, MergeOutlined, MenuOutlined} from '@ant-design/icons' +import {MenuOutlined} from '@ant-design/icons' import TrackedDomainPage from './pages/tracking/TrackedDomainPage' import IcannRegistrarPage from "./pages/infrastructure/IcannRegistrarPage" @@ -165,9 +165,24 @@ export default function App(): React.ReactElement { target='_blank' href='https://github.com/maelgangloff/domain-watchdog/wiki' > - + + + + + + @@ -176,22 +191,6 @@ export default function App(): React.ReactElement {
- } - > - - } target='_blank' href={PROJECT_LINK}/> - - - } target='_blank' href={PROJECT_LINK + '/issues'}/> - -
From 29db54ad179929b3ba31f8b268e72756ac2e68d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 1 Nov 2025 18:52:41 +0100 Subject: [PATCH 053/131] feat: use domainPurchase to get stats --- assets/pages/StatisticsPage.tsx | 2 +- src/Controller/StatisticsController.php | 10 ++++-- src/MessageHandler/OrderDomainHandler.php | 2 -- src/Repository/DomainPurchaseRepository.php | 37 ++++++++------------- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/assets/pages/StatisticsPage.tsx b/assets/pages/StatisticsPage.tsx index b9bfd92..2ff7a96 100644 --- a/assets/pages/StatisticsPage.tsx +++ b/assets/pages/StatisticsPage.tsx @@ -95,7 +95,7 @@ export default function StatisticsPage() { = 0.5 ? 'darkgreen' : 'orange'}} /> diff --git a/src/Controller/StatisticsController.php b/src/Controller/StatisticsController.php index a1685ae..7fda1ff 100644 --- a/src/Controller/StatisticsController.php +++ b/src/Controller/StatisticsController.php @@ -3,6 +3,7 @@ namespace App\Controller; use App\Entity\Statistics; +use App\Repository\DomainPurchaseRepository; use App\Repository\DomainRepository; use App\Repository\WatchlistRepository; use Psr\Cache\CacheItemPoolInterface; @@ -16,6 +17,7 @@ class StatisticsController extends AbstractController private readonly CacheItemPoolInterface $pool, private readonly DomainRepository $domainRepository, private readonly WatchlistRepository $watchlistRepository, + private readonly DomainPurchaseRepository $domainPurchaseRepository, private readonly KernelInterface $kernel, ) { } @@ -29,8 +31,12 @@ class StatisticsController extends AbstractController $stats ->setRdapQueries($this->pool->getItem('stats.rdap_queries.count')->get() ?? 0) - ->setDomainPurchased($this->pool->getItem('stats.domain.purchased')->get() ?? 0) - ->setDomainPurchaseFailed($this->pool->getItem('stats.domain.purchase.failed')->get() ?? 0) + ->setDomainPurchased( + $this->getCachedItem('stats.domain.purchase', fn () => $this->domainPurchaseRepository->count()) + ) + ->setDomainPurchaseFailed( + $this->getCachedItem('stats.domain.purchase.failed', fn () => $this->domainPurchaseRepository->countFailDomainPurchase()) + ) ->setAlertSent($this->pool->getItem('stats.alert.sent')->get() ?? 0) ->setDomainTracked( diff --git a/src/MessageHandler/OrderDomainHandler.php b/src/MessageHandler/OrderDomainHandler.php index 6f0c7c1..a52ac94 100644 --- a/src/MessageHandler/OrderDomainHandler.php +++ b/src/MessageHandler/OrderDomainHandler.php @@ -109,7 +109,6 @@ final readonly class OrderDomainHandler 'provider' => $connector->getProvider()->value, ]); - $this->statService->incrementStat('stats.domain.purchased'); if ($this->influxdbEnabled) { $this->influxdbService->addDomainOrderPoint($connector, $domain, true); } @@ -138,7 +137,6 @@ final readonly class OrderDomainHandler 'provider' => $connector->getProvider()->value, ]); - $this->statService->incrementStat('stats.domain.purchase.failed'); if ($this->influxdbEnabled) { $this->influxdbService->addDomainOrderPoint($connector, $domain, false); } diff --git a/src/Repository/DomainPurchaseRepository.php b/src/Repository/DomainPurchaseRepository.php index 3772893..fc8143e 100644 --- a/src/Repository/DomainPurchaseRepository.php +++ b/src/Repository/DomainPurchaseRepository.php @@ -16,28 +16,19 @@ class DomainPurchaseRepository extends ServiceEntityRepository parent::__construct($registry, DomainPurchase::class); } - // /** - // * @return DomainPurchase[] Returns an array of DomainPurchase objects - // */ - // public function findByExampleField($value): array - // { - // return $this->createQueryBuilder('d') - // ->andWhere('d.exampleField = :val') - // ->setParameter('val', $value) - // ->orderBy('d.id', 'ASC') - // ->setMaxResults(10) - // ->getQuery() - // ->getResult() - // ; - // } + public function countSuccessDomainPurchase(): int + { + return $this->createQueryBuilder('dp') + ->select('COUNT(*)') + ->where('dp.domainOrderedAt != NULL') + ->getQuery()->getSingleScalarResult(); + } - // public function findOneBySomeField($value): ?DomainPurchase - // { - // return $this->createQueryBuilder('d') - // ->andWhere('d.exampleField = :val') - // ->setParameter('val', $value) - // ->getQuery() - // ->getOneOrNullResult() - // ; - // } + public function countFailDomainPurchase(): int + { + return $this->createQueryBuilder('dp') + ->select('COUNT(*)') + ->where('dp.domainOrderedAt == NULL') + ->getQuery()->getSingleScalarResult(); + } } From 2292057c73f9336b4b226763a7d66d336651bddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 1 Nov 2025 19:02:18 +0100 Subject: [PATCH 054/131] chore: remove unused service --- src/MessageHandler/OrderDomainHandler.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MessageHandler/OrderDomainHandler.php b/src/MessageHandler/OrderDomainHandler.php index a52ac94..2cc6bc2 100644 --- a/src/MessageHandler/OrderDomainHandler.php +++ b/src/MessageHandler/OrderDomainHandler.php @@ -13,7 +13,6 @@ use App\Repository\WatchlistRepository; use App\Service\ChatNotificationService; use App\Service\InfluxdbService; use App\Service\Provider\AbstractProvider; -use App\Service\StatService; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; @@ -38,7 +37,6 @@ final readonly class OrderDomainHandler private KernelInterface $kernel, private MailerInterface $mailer, private LoggerInterface $logger, - private StatService $statService, private ChatNotificationService $chatNotificationService, private InfluxdbService $influxdbService, #[Autowire(service: 'service_container')] From aca4c9f23df4569e24563d555fbecf20d85e5643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 1 Nov 2025 19:11:59 +0100 Subject: [PATCH 055/131] fix: correct count in DQL --- src/Repository/DomainPurchaseRepository.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Repository/DomainPurchaseRepository.php b/src/Repository/DomainPurchaseRepository.php index fc8143e..7ca1b92 100644 --- a/src/Repository/DomainPurchaseRepository.php +++ b/src/Repository/DomainPurchaseRepository.php @@ -19,16 +19,16 @@ class DomainPurchaseRepository extends ServiceEntityRepository public function countSuccessDomainPurchase(): int { return $this->createQueryBuilder('dp') - ->select('COUNT(*)') - ->where('dp.domainOrderedAt != NULL') + ->select('COUNT(dp)') + ->where('dp.domainOrderedAt not NULL') ->getQuery()->getSingleScalarResult(); } public function countFailDomainPurchase(): int { return $this->createQueryBuilder('dp') - ->select('COUNT(*)') - ->where('dp.domainOrderedAt == NULL') + ->select('COUNT(dp)') + ->where('dp.domainOrderedAt is NULL') ->getQuery()->getSingleScalarResult(); } } From 841e8dcba6fc2227e0c3d6f9eb6fdf08b232ef0f Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 22:59:49 +0100 Subject: [PATCH 056/131] feat: add domain to watchlist FAB --- .../watchlist/WatchlistSelectionModal.tsx | 78 +++++++++++++++++++ assets/pages/search/DomainSearchPage.tsx | 51 ++++++++++-- assets/utils/api/watchlist.ts | 7 ++ assets/utils/functions/DomainToTag.tsx | 62 ++++++++------- 4 files changed, 162 insertions(+), 36 deletions(-) create mode 100644 assets/components/tracking/watchlist/WatchlistSelectionModal.tsx diff --git a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx new file mode 100644 index 0000000..f8bd5cf --- /dev/null +++ b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx @@ -0,0 +1,78 @@ +import React, {useEffect, useState} from "react" +import {Flex, Modal, ModalProps, Select, Tag, Typography} from "antd" +import {getWatchlists, Watchlist} from "../../../utils/api" +import {t} from 'ttag' +import {DomainToTag} from "../../../utils/functions/DomainToTag" + +function WatchlistOption({watchlist}: {watchlist: Watchlist}) { + return + {watchlist.name} + + {watchlist.domains.map(d => )} + + +} + +interface WatchlistSelectionModalProps { + onFinish: (watchlist: Watchlist) => Promise|void + description?: string + open?: boolean + modalProps?: Partial +} + +export default function WatchlistSelectionModal(props: WatchlistSelectionModalProps) { + const [watchlists, setWatchlists] = useState() + const [selectedWatchlist, setSelectedWatchlist] = useState() + const [validationLoading, setValidationLoading] = useState(false) + + useEffect(() => { + getWatchlists().then(list => setWatchlists(list["hydra:member"])) + }, []) + + const onFinish = () => { + const promise = props.onFinish(selectedWatchlist as Watchlist) + + if (promise) { + setValidationLoading(true) + promise.finally(() => { + setSelectedWatchlist(undefined) + setValidationLoading(false) + }) + } else { + setSelectedWatchlist(undefined) + } + } + + return + + + { + props.description + || t`Select one of your available watchlists` + } + + { await addDomainToWatchlist(watchlist, domain!.ldhName).then(() => { setAddToWatchlistModal(false) + messageApi.success(t`${domain?.ldhName} added to ${watchlist.name}`) }).catch((e: AxiosError) => { showErrorAPI(e, messageApi) }) From 615842725d975fa4fb570a129fb41d1f4bbb0bf9 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 23:21:54 +0100 Subject: [PATCH 059/131] chore: lint --- .../tracking/watchlist/WatchlistSelectionModal.tsx | 6 ++++-- assets/pages/search/DomainSearchPage.tsx | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx index c7a7dd0..5bd7834 100644 --- a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx +++ b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx @@ -1,6 +1,8 @@ import React, {useEffect, useState} from "react" -import {Flex, Modal, ModalProps, Select, Tag, Typography} from "antd" -import {getWatchlists, Watchlist} from "../../../utils/api" +import type { ModalProps} from "antd" +import {Flex, Modal, Select, Typography} from "antd" +import type { Watchlist} from "../../../utils/api" +import {getWatchlists} from "../../../utils/api" import {t} from 'ttag' import {DomainToTag} from "../../../utils/functions/DomainToTag" diff --git a/assets/pages/search/DomainSearchPage.tsx b/assets/pages/search/DomainSearchPage.tsx index 86a72d2..9384ddd 100644 --- a/assets/pages/search/DomainSearchPage.tsx +++ b/assets/pages/search/DomainSearchPage.tsx @@ -1,9 +1,9 @@ import React, {useEffect, useState} from 'react' import type {FormProps} from 'antd' -import {Tooltip} from 'antd' import {FloatButton} from 'antd' import {Empty, Flex, message, Skeleton} from 'antd' -import {addDomainToWatchlist, Domain, Watchlist} from '../../utils/api' +import type { Domain, Watchlist} from '../../utils/api' +import {addDomainToWatchlist} from '../../utils/api' import {getDomain} from '../../utils/api' import type {AxiosError} from 'axios' import {t} from 'ttag' @@ -12,8 +12,8 @@ import {DomainSearchBar} from '../../components/search/DomainSearchBar' import {DomainResult} from '../../components/search/DomainResult' import {showErrorAPI} from '../../utils/functions/showErrorAPI' import {useNavigate, useParams} from 'react-router-dom' -import {CaretUpOutlined, PlusOutlined} from '@ant-design/icons' -import WatchlistSelectionModal from "../../components/tracking/watchlist/WatchlistSelectionModal"; +import {PlusOutlined} from '@ant-design/icons' +import WatchlistSelectionModal from '../../components/tracking/watchlist/WatchlistSelectionModal' export default function DomainSearchPage() { const {query} = useParams() From 56b6db9277343c50d4ad45b1171b7a8d65afd511 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 23:27:58 +0100 Subject: [PATCH 060/131] fix: ttag doesn't support typescript expressions --- assets/pages/search/DomainSearchPage.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/pages/search/DomainSearchPage.tsx b/assets/pages/search/DomainSearchPage.tsx index 9384ddd..0c8d1e5 100644 --- a/assets/pages/search/DomainSearchPage.tsx +++ b/assets/pages/search/DomainSearchPage.tsx @@ -18,6 +18,7 @@ import WatchlistSelectionModal from '../../components/tracking/watchlist/Watchli export default function DomainSearchPage() { const {query} = useParams() const [domain, setDomain] = useState() + const domainLdhName = domain?.ldhName const [loading, setLoading] = useState(false) const [addToWatchlistModal, setAddToWatchlistModal] = useState(false) @@ -47,7 +48,9 @@ export default function DomainSearchPage() { const addToWatchlist = async (watchlist: Watchlist) => { await addDomainToWatchlist(watchlist, domain!.ldhName).then(() => { setAddToWatchlistModal(false) - messageApi.success(t`${domain?.ldhName} added to ${watchlist.name}`) + + const ldhName = domain?.ldhName + messageApi.success(t`${ldhName} added to ${watchlist.name}`) }).catch((e: AxiosError) => { showErrorAPI(e, messageApi) }) @@ -86,7 +89,7 @@ export default function DomainSearchPage() { open={addToWatchlistModal} onFinish={addToWatchlist} modalProps={{ - title: t`Add ${domain?.ldhName} to a watchlist`, + title: t`Add ${domainLdhName} to a watchlist`, onCancel: () => setAddToWatchlistModal(false), onClose: () => setAddToWatchlistModal(false), }} From 8d8c13fc48fd157d74c65e2a4014a4e2dc9de07b Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sat, 1 Nov 2025 23:28:08 +0100 Subject: [PATCH 061/131] i18n: update source strings --- translations/translations.pot | 45 +++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/translations/translations.pot b/translations/translations.pot index fba7bae..48526fa 100644 --- a/translations/translations.pot +++ b/translations/translations.pot @@ -15,25 +15,25 @@ msgstr "" msgid "FAQ" msgstr "" -#: assets/App.tsx:170 +#: assets/App.tsx:169 msgid "Documentation" msgstr "" -#: assets/App.tsx:175 +#: assets/App.tsx:177 +msgid "Source code" +msgstr "" + +#: assets/App.tsx:185 +msgid "Submit an issue" +msgstr "" + +#: assets/App.tsx:190 #, javascript-format msgid "" "${ ProjectLink } is an open source project distributed under the ${ " "LicenseLink } license." msgstr "" -#: assets/App.tsx:188 -msgid "Official git repository" -msgstr "" - -#: assets/App.tsx:191 -msgid "Submit an issue" -msgstr "" - #: assets/components/LoginForm.tsx:53 #: assets/components/RegisterForm.tsx:37 msgid "Email address" @@ -480,6 +480,7 @@ msgid "This Watchlist is not linked to a Connector." msgstr "" #: assets/components/tracking/watchlist/WatchlistCard.tsx:59 +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:65 msgid "Watchlist" msgstr "" @@ -564,6 +565,10 @@ msgstr "" msgid "Reset" msgstr "" +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:61 +msgid "Select one of your available watchlists" +msgstr "" + #: assets/pages/infrastructure/IcannRegistrarPage.tsx:45 msgid "ID" msgstr "" @@ -688,16 +693,30 @@ msgstr "" msgid "Sorry, the page you visited does not exist." msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:32 +#: assets/pages/search/DomainSearchPage.tsx:36 msgid "Found !" msgstr "" -#: assets/pages/search/DomainSearchPage.tsx:55 +#: assets/pages/search/DomainSearchPage.tsx:53 +#, javascript-format +msgid "${ ldhName } added to ${ watchlist.name }" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:70 msgid "" "Although the domain exists in my database, it has been deleted from the " "WHOIS by its registrar." msgstr "" +#: assets/pages/search/DomainSearchPage.tsx:82 +msgid "Add to watchlist" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:92 +#, javascript-format +msgid "Add ${ domainLdhName } to a watchlist" +msgstr "" + #: assets/pages/StatisticsPage.tsx:35 msgid "RDAP queries" msgstr "" @@ -760,7 +779,7 @@ msgstr "" msgid "Roles" msgstr "" -#: assets/utils/functions/DomainToTag.tsx:16 +#: assets/utils/functions/DomainToTag.tsx:14 msgid "The domain name was updated less than a week ago." msgstr "" From 8c754d3e87a5215f9fce89ff3a4461ed42457e5a Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sun, 2 Nov 2025 01:53:08 +0100 Subject: [PATCH 062/131] perf: fetch watchlists on modal open only --- .../tracking/watchlist/WatchlistSelectionModal.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx index 5bd7834..da8c8ed 100644 --- a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx +++ b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx @@ -28,8 +28,10 @@ export default function WatchlistSelectionModal(props: WatchlistSelectionModalPr const [validationLoading, setValidationLoading] = useState(false) useEffect(() => { - getWatchlists().then(list => setWatchlists(list["hydra:member"])) - }, []) + if (props.open && !watchlists) { + getWatchlists().then(list => setWatchlists(list["hydra:member"])) + } + }, [props.open]) const onFinish = () => { const promise = props.onFinish(selectedWatchlist as Watchlist) From a1aec6b463809775f24d482526cfb08355320909 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sun, 2 Nov 2025 02:48:43 +0100 Subject: [PATCH 063/131] feat: ellipsize domain tags --- .../watchlist/WatchlistSelectionModal.tsx | 27 ++++++++++++++++--- assets/pages/search/DomainSearchPage.tsx | 2 +- translations/translations.pot | 9 +++++-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx index da8c8ed..a1a6ff7 100644 --- a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx +++ b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx @@ -1,16 +1,35 @@ import React, {useEffect, useState} from "react" -import type { ModalProps} from "antd" +import type {ModalProps} from "antd" +import {Tag, Tooltip} from "antd" import {Flex, Modal, Select, Typography} from "antd" -import type { Watchlist} from "../../../utils/api" +import type {Domain, Watchlist} from "../../../utils/api" import {getWatchlists} from "../../../utils/api" import {t} from 'ttag' import {DomainToTag} from "../../../utils/functions/DomainToTag" +import {EllipsisOutlined} from '@ant-design/icons' + +const MAX_DOMAIN_TAGS = 25 function WatchlistOption({watchlist}: {watchlist: Watchlist}) { + let domains = watchlist.domains + let rest: Domain[]|undefined = undefined + + if (domains.length > MAX_DOMAIN_TAGS) { + rest = domains.slice(MAX_DOMAIN_TAGS) + domains = domains.slice(0, MAX_DOMAIN_TAGS) + } + return {watchlist.name} - - {watchlist.domains.map(d => )} + + {domains.map(d => )} + {rest + && )}> + } color='processing'> + {t`${rest.length} more`} + + + } } diff --git a/assets/pages/search/DomainSearchPage.tsx b/assets/pages/search/DomainSearchPage.tsx index 0c8d1e5..bc8f261 100644 --- a/assets/pages/search/DomainSearchPage.tsx +++ b/assets/pages/search/DomainSearchPage.tsx @@ -2,7 +2,7 @@ import React, {useEffect, useState} from 'react' import type {FormProps} from 'antd' import {FloatButton} from 'antd' import {Empty, Flex, message, Skeleton} from 'antd' -import type { Domain, Watchlist} from '../../utils/api' +import type {Domain, Watchlist} from '../../utils/api' import {addDomainToWatchlist} from '../../utils/api' import {getDomain} from '../../utils/api' import type {AxiosError} from 'axios' diff --git a/translations/translations.pot b/translations/translations.pot index 48526fa..e198532 100644 --- a/translations/translations.pot +++ b/translations/translations.pot @@ -480,7 +480,7 @@ msgid "This Watchlist is not linked to a Connector." msgstr "" #: assets/components/tracking/watchlist/WatchlistCard.tsx:59 -#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:65 +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:86 msgid "Watchlist" msgstr "" @@ -565,7 +565,12 @@ msgstr "" msgid "Reset" msgstr "" -#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:61 +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:29 +#, javascript-format +msgid "${ rest.length } more" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:82 msgid "Select one of your available watchlists" msgstr "" From 0739ef5ca9c87dd5953bbdcefae76e067a275974 Mon Sep 17 00:00:00 2001 From: vinceh121 Date: Sun, 2 Nov 2025 03:12:46 +0100 Subject: [PATCH 064/131] perf: prevent N+1 on watchlist fetch --- src/Controller/WatchlistController.php | 18 ------------------ src/Entity/Watchlist.php | 3 ++- src/Repository/WatchlistRepository.php | 19 +++++++++++++++++++ src/State/MyWatchlistsProvider.php | 24 ++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 src/State/MyWatchlistsProvider.php diff --git a/src/Controller/WatchlistController.php b/src/Controller/WatchlistController.php index 16b59a9..556f9b9 100644 --- a/src/Controller/WatchlistController.php +++ b/src/Controller/WatchlistController.php @@ -11,7 +11,6 @@ use App\Repository\DomainRepository; use App\Repository\WatchlistRepository; use App\Service\CalendarService; use App\Service\RDAPService; -use Doctrine\Common\Collections\Collection; use Eluceo\iCal\Domain\Entity\Calendar; use Eluceo\iCal\Presentation\Component\Property; use Eluceo\iCal\Presentation\Component\Property\Value\TextValue; @@ -36,23 +35,6 @@ class WatchlistController extends AbstractController ) { } - #[Route( - path: '/api/watchlists', - name: 'watchlist_get_all_mine', - defaults: [ - '_api_resource_class' => Watchlist::class, - '_api_operation_name' => 'get_all_mine', - ], - methods: ['GET'] - )] - public function getWatchlists(): Collection - { - /** @var User $user */ - $user = $this->getUser(); - - return $user->getWatchlists(); - } - /** * @throws ParseException * @throws EofException diff --git a/src/Entity/Watchlist.php b/src/Entity/Watchlist.php index f083fde..5f46d08 100644 --- a/src/Entity/Watchlist.php +++ b/src/Entity/Watchlist.php @@ -10,6 +10,7 @@ use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Put; use App\Repository\WatchlistRepository; +use App\State\MyWatchlistsProvider; use App\State\WatchlistUpdateProcessor; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -25,7 +26,6 @@ use Symfony\Component\Validator\Constraints as Assert; shortName: 'Watchlist', operations: [ new GetCollection( - routeName: 'watchlist_get_all_mine', normalizationContext: [ 'groups' => [ 'watchlist:list', @@ -34,6 +34,7 @@ use Symfony\Component\Validator\Constraints as Assert; ], ], name: 'get_all_mine', + provider: MyWatchlistsProvider::class, ), new GetCollection( uriTemplate: '/tracked', diff --git a/src/Repository/WatchlistRepository.php b/src/Repository/WatchlistRepository.php index b2cb5f6..632a76a 100644 --- a/src/Repository/WatchlistRepository.php +++ b/src/Repository/WatchlistRepository.php @@ -2,6 +2,7 @@ namespace App\Repository; +use App\Entity\User; use App\Entity\Watchlist; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -33,6 +34,24 @@ class WatchlistRepository extends ServiceEntityRepository ->getQuery()->execute(); } + /** + * @return Watchlist[] + */ + public function fetchWatchlistsForUser(User $user): array + { + return $this->createQueryBuilder('w') + ->addSelect('d') + ->addSelect('e') + ->addSelect('p') + ->leftJoin('w.domains', 'd') + ->leftJoin('d.events', 'e') + ->leftJoin('d.domainPurchases', 'p') + ->where('w.user = :user') + ->setParameter('user', $user) + ->getQuery() + ->getResult(); + } + // /** // * @return Watchlist[] Returns an array of Watchlist objects // */ diff --git a/src/State/MyWatchlistsProvider.php b/src/State/MyWatchlistsProvider.php new file mode 100644 index 0000000..c92b3d8 --- /dev/null +++ b/src/State/MyWatchlistsProvider.php @@ -0,0 +1,24 @@ +security->getUser(); + + return $this->watchlistRepository->fetchWatchlistsForUser($user); + } +} From bf492e96cfe0679bb5d07a61b1ea25e207f1093c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 2 Nov 2025 11:54:25 +0100 Subject: [PATCH 065/131] fix: use base.html.twig --- templates/emails/errors/domain_deleted.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/emails/errors/domain_deleted.html.twig b/templates/emails/errors/domain_deleted.html.twig index a946c6a..d5bf2cf 100644 --- a/templates/emails/errors/domain_deleted.html.twig +++ b/templates/emails/errors/domain_deleted.html.twig @@ -1,4 +1,4 @@ -{% extends "base.html.twig" %} +{% extends "emails/base.html.twig" %} {% set email_color = '#0056b3' %} {% set title = 'Domain Watchdog Alert' %} From 39f607e95da631fcf835955b1af2d845df0736bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 2 Nov 2025 12:05:32 +0100 Subject: [PATCH 066/131] fix: prevent domainPurchase duplicates --- src/MessageHandler/OrderDomainHandler.php | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/MessageHandler/OrderDomainHandler.php b/src/MessageHandler/OrderDomainHandler.php index 2cc6bc2..05bf2ed 100644 --- a/src/MessageHandler/OrderDomainHandler.php +++ b/src/MessageHandler/OrderDomainHandler.php @@ -8,6 +8,7 @@ use App\Entity\Watchlist; use App\Message\OrderDomain; use App\Notifier\DomainOrderErrorNotification; use App\Notifier\DomainOrderNotification; +use App\Repository\DomainPurchaseRepository; use App\Repository\DomainRepository; use App\Repository\WatchlistRepository; use App\Service\ChatNotificationService; @@ -42,7 +43,7 @@ final readonly class OrderDomainHandler #[Autowire(service: 'service_container')] private ContainerInterface $locator, #[Autowire(param: 'influxdb_enabled')] - private bool $influxdbEnabled, private EntityManagerInterface $em, + private bool $influxdbEnabled, private EntityManagerInterface $em, private DomainPurchaseRepository $domainPurchaseRepository, ) { $this->sender = new Address($mailerSenderEmail, $mailerSenderName); } @@ -142,15 +143,24 @@ final readonly class OrderDomainHandler $this->mailer->send($notification->asEmailMessage(new Recipient($watchlist->getUser()->getEmail()))->getMessage()); $this->chatNotificationService->sendChatNotification($watchlist, $notification); - $this->em->persist((new DomainPurchase()) - ->setDomain($domain) - ->setConnector($connector) - ->setConnectorProvider($connector->getProvider()) - ->setDomainOrderedAt(null) - ->setUser($watchlist->getUser()) - ->setDomainDeletedAt($domain->getUpdatedAt()) - ->setDomainUpdatedAt($message->updatedAt)); - $this->em->flush(); + $domainPurchase = $this->domainPurchaseRepository->findOneBy([ + 'domain' => $domain, + 'connector' => $connector, + 'domainOrderedAt' => null, + 'domainUpdatedAt' => $message->updatedAt, + 'user' => $watchlist->getUser(), + ]); + if (null === $domainPurchase) { + $this->em->persist((new DomainPurchase()) + ->setDomain($domain) + ->setConnector($connector) + ->setConnectorProvider($connector->getProvider()) + ->setDomainOrderedAt(null) + ->setUser($watchlist->getUser()) + ->setDomainDeletedAt($domain->getUpdatedAt()) + ->setDomainUpdatedAt($message->updatedAt)); + $this->em->flush(); + } throw $exception; } From ba7bd33ba164f919e2dc5503c8d89ef7eb2b7ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 2 Nov 2025 12:10:33 +0100 Subject: [PATCH 067/131] fix: success rate in the stats page --- assets/pages/StatisticsPage.tsx | 4 +--- translations/translations.pot | 16 ++++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/assets/pages/StatisticsPage.tsx b/assets/pages/StatisticsPage.tsx index 2ff7a96..c1c9f4a 100644 --- a/assets/pages/StatisticsPage.tsx +++ b/assets/pages/StatisticsPage.tsx @@ -18,10 +18,8 @@ export default function StatisticsPage() { getStatistics().then(setStats) }, []) - const totalDomainPurchase = (stats?.domainPurchased ?? 0) + (stats?.domainPurchaseFailed ?? 0) - const successRate = stats !== undefined - ? (totalDomainPurchase === 0 ? undefined : stats.domainPurchased / totalDomainPurchase) + ? (stats?.domainPurchased === 0 ? undefined : ((stats?.domainPurchased ?? 0) - (stats?.domainPurchaseFailed ?? 0)) / stats?.domainPurchased) : undefined return ( diff --git a/translations/translations.pot b/translations/translations.pot index fba7bae..3eae18f 100644 --- a/translations/translations.pot +++ b/translations/translations.pot @@ -191,7 +191,7 @@ msgid "Infrastructure" msgstr "" #: assets/components/Sider.tsx:70 -#: assets/pages/StatisticsPage.tsx:114 +#: assets/pages/StatisticsPage.tsx:112 #: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "" @@ -698,33 +698,33 @@ msgid "" "WHOIS by its registrar." msgstr "" -#: assets/pages/StatisticsPage.tsx:35 +#: assets/pages/StatisticsPage.tsx:33 msgid "RDAP queries" msgstr "" -#: assets/pages/StatisticsPage.tsx:44 +#: assets/pages/StatisticsPage.tsx:42 msgid "Alerts sent" msgstr "" -#: assets/pages/StatisticsPage.tsx:58 +#: assets/pages/StatisticsPage.tsx:56 msgid "Domain names in database" msgstr "" -#: assets/pages/StatisticsPage.tsx:69 +#: assets/pages/StatisticsPage.tsx:67 msgid "Tracked domain names" msgstr "" -#: assets/pages/StatisticsPage.tsx:83 +#: assets/pages/StatisticsPage.tsx:81 msgid "Purchased domain names" msgstr "" -#: assets/pages/StatisticsPage.tsx:93 +#: assets/pages/StatisticsPage.tsx:91 msgid "" "This value is based on the status code of the HTTP response from the " "providers following the domain order." msgstr "" -#: assets/pages/StatisticsPage.tsx:97 +#: assets/pages/StatisticsPage.tsx:95 msgid "Success rate" msgstr "" From fe46555d1ed4a82a757707ffb3be985c05f801a3 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 2 Nov 2025 11:10:44 +0000 Subject: [PATCH 068/131] Update translation files Updated by "Update PO files to match POT (msgmerge)" add-on in Weblate. --- translations/de.po | 16 ++++++++-------- translations/fr.po | 16 ++++++++-------- translations/sv.po | 16 ++++++++-------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/translations/de.po b/translations/de.po index 8aa49d4..09b3cb8 100644 --- a/translations/de.po +++ b/translations/de.po @@ -200,7 +200,7 @@ msgstr "Domänenfinder" msgid "Infrastructure" msgstr "Infrastruktur" -#: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:114 +#: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:112 #: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "TLD" @@ -774,27 +774,27 @@ msgstr "" "Obwohl die Domain in meiner Datenbank vorhanden ist, wurde sie von ihrem " "Registrar aus dem WHOIS gelöscht." -#: assets/pages/StatisticsPage.tsx:35 +#: assets/pages/StatisticsPage.tsx:33 msgid "RDAP queries" msgstr "RDAP-Abfragen" -#: assets/pages/StatisticsPage.tsx:44 +#: assets/pages/StatisticsPage.tsx:42 msgid "Alerts sent" msgstr "Gesendete Warnungen" -#: assets/pages/StatisticsPage.tsx:58 +#: assets/pages/StatisticsPage.tsx:56 msgid "Domain names in database" msgstr "Domänennamen in der Datenbank" -#: assets/pages/StatisticsPage.tsx:69 +#: assets/pages/StatisticsPage.tsx:67 msgid "Tracked domain names" msgstr "Verfolgte Domänennamen" -#: assets/pages/StatisticsPage.tsx:83 +#: assets/pages/StatisticsPage.tsx:81 msgid "Purchased domain names" msgstr "Gekaufte Domänennamen" -#: assets/pages/StatisticsPage.tsx:93 +#: assets/pages/StatisticsPage.tsx:91 msgid "" "This value is based on the status code of the HTTP response from the " "providers following the domain order." @@ -802,7 +802,7 @@ msgstr "" "Dieser Wert basiert auf dem Statuscode der HTTP-Antwort der Anbieter nach " "dem Domainkauf." -#: assets/pages/StatisticsPage.tsx:97 +#: assets/pages/StatisticsPage.tsx:95 msgid "Success rate" msgstr "Erfolgsrate" diff --git a/translations/fr.po b/translations/fr.po index ab39731..293f0c6 100644 --- a/translations/fr.po +++ b/translations/fr.po @@ -202,7 +202,7 @@ msgstr "Rechercher un domaine" msgid "Infrastructure" msgstr "Infrastructure" -#: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:114 +#: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:112 #: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "TLD" @@ -776,27 +776,27 @@ msgstr "" "Bien que le domaine existe dans ma base de données, il a été supprimé du " "WHOIS par son bureau d'enregistrement." -#: assets/pages/StatisticsPage.tsx:35 +#: assets/pages/StatisticsPage.tsx:33 msgid "RDAP queries" msgstr "Requêtes RDAP" -#: assets/pages/StatisticsPage.tsx:44 +#: assets/pages/StatisticsPage.tsx:42 msgid "Alerts sent" msgstr "Alertes envoyées" -#: assets/pages/StatisticsPage.tsx:58 +#: assets/pages/StatisticsPage.tsx:56 msgid "Domain names in database" msgstr "Noms de domaine dans la base de données" -#: assets/pages/StatisticsPage.tsx:69 +#: assets/pages/StatisticsPage.tsx:67 msgid "Tracked domain names" msgstr "Noms de domaine suivis" -#: assets/pages/StatisticsPage.tsx:83 +#: assets/pages/StatisticsPage.tsx:81 msgid "Purchased domain names" msgstr "Noms de domaine achetés" -#: assets/pages/StatisticsPage.tsx:93 +#: assets/pages/StatisticsPage.tsx:91 msgid "" "This value is based on the status code of the HTTP response from the " "providers following the domain order." @@ -804,7 +804,7 @@ msgstr "" "Cette valeur est basée sur le code d'état de la réponse HTTP des Providers " "suivant l'achat du domaine." -#: assets/pages/StatisticsPage.tsx:97 +#: assets/pages/StatisticsPage.tsx:95 msgid "Success rate" msgstr "Taux de succès" diff --git a/translations/sv.po b/translations/sv.po index 861d4a2..099f4ec 100644 --- a/translations/sv.po +++ b/translations/sv.po @@ -200,7 +200,7 @@ msgstr "Domännamnssökare" msgid "Infrastructure" msgstr "Infrastruktur" -#: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:114 +#: assets/components/Sider.tsx:70 assets/pages/StatisticsPage.tsx:112 #: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" msgstr "TLD" @@ -755,27 +755,27 @@ msgstr "" "Även om domänen finns i min databas har den tagits bort från WHOIS av dess " "registrar." -#: assets/pages/StatisticsPage.tsx:35 +#: assets/pages/StatisticsPage.tsx:33 msgid "RDAP queries" msgstr "RDAP-frågor" -#: assets/pages/StatisticsPage.tsx:44 +#: assets/pages/StatisticsPage.tsx:42 msgid "Alerts sent" msgstr "Aviseringar skickade" -#: assets/pages/StatisticsPage.tsx:58 +#: assets/pages/StatisticsPage.tsx:56 msgid "Domain names in database" msgstr "Domännamn i databasen" -#: assets/pages/StatisticsPage.tsx:69 +#: assets/pages/StatisticsPage.tsx:67 msgid "Tracked domain names" msgstr "Spårade domännamn" -#: assets/pages/StatisticsPage.tsx:83 +#: assets/pages/StatisticsPage.tsx:81 msgid "Purchased domain names" msgstr "Köpta domännamn" -#: assets/pages/StatisticsPage.tsx:93 +#: assets/pages/StatisticsPage.tsx:91 msgid "" "This value is based on the status code of the HTTP response from the " "providers following the domain order." @@ -783,7 +783,7 @@ msgstr "" "Detta värde baseras på statuskoden för HTTP-svaret från leverantörerna efter " "domänordningen." -#: assets/pages/StatisticsPage.tsx:97 +#: assets/pages/StatisticsPage.tsx:95 msgid "Success rate" msgstr "Framgångsgrad" From 604a445839cb4b1130ea2ec6c03c627e090eb77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 2 Nov 2025 13:44:28 +0100 Subject: [PATCH 069/131] feat: translate button text --- .../tracking/watchlist/WatchlistSelectionModal.tsx | 2 +- assets/pages/search/DomainSearchPage.tsx | 10 ++++++---- translations/translations.pot | 14 +++++++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx index a1a6ff7..4604461 100644 --- a/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx +++ b/assets/components/tracking/watchlist/WatchlistSelectionModal.tsx @@ -79,7 +79,7 @@ export default function WatchlistSelectionModal(props: WatchlistSelectionModalPr { props.description - || t`Select one of your available watchlists` + || t`Select one of your available Watchlists` } } autoComplete='off'/> diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 03f8d37..11e2241 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -37,7 +37,6 @@ export default defineConfig({ { label: 'Developing', items: [ - {label: 'Getting started', slug: 'developing/getting-started'}, {slug: 'developing/technical-stack'}, {slug: 'developing/translation'}, {label: 'Contributing', autogenerate: {directory: 'developing/contributing'}} diff --git a/docs/src/assets/images/dw-stack-diagram.png b/docs/src/assets/images/dw-stack-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..14937bd3de05d3126edaedd4a9759f1c19218561 GIT binary patch literal 117132 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 ../public/locales/$i.json; done; cd ..", - "ttag:extract": "ttag extract $(find assets -name 'assets/*.ts' -or -name 'assets/*.tsx' | sort) -o translations/translations.pot" + "ttag:extract": "ttag extract $(find assets -name '*.ts' -or -name '*.tsx' | sort) -o translations/translations.pot" } } diff --git a/translations/translations.pot b/translations/translations.pot index d2ed413..d7e97ec 100644 --- a/translations/translations.pot +++ b/translations/translations.pot @@ -1452,7 +1452,7 @@ msgstr "" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 msgid "" -"Retreive an API key and whitelist this instance's IP address on Namecheap's " +"Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" msgstr "" From 22568c0e31bae83ca003045212a5118919343e39 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 13 Nov 2025 15:26:56 +0000 Subject: [PATCH 103/131] Update translation files Updated by "Update PO files to match POT (msgmerge)" add-on in Weblate. --- translations/de.po | 6 +++++- translations/fr.po | 6 +++++- translations/sv.po | 10 +++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/translations/de.po b/translations/de.po index e35a5ed..3ffadc7 100644 --- a/translations/de.po +++ b/translations/de.po @@ -1688,8 +1688,12 @@ msgid "It indicates the organization that will pay for the ordered product" msgstr "Es gibt die Organisation an, die für das bestellte Produkt bezahlt" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 +#, fuzzy +#| msgid "" +#| "Retreive an API key and whitelist this instance's IP address on " +#| "Namecheap's website" msgid "" -"Retreive an API key and whitelist this instance's IP address on Namecheap's " +"Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" msgstr "" "Rufen Sie einen API-Schlüssel ab und setzen Sie die IP-Adresse dieser " diff --git a/translations/fr.po b/translations/fr.po index 21be9fc..806af7a 100644 --- a/translations/fr.po +++ b/translations/fr.po @@ -1687,8 +1687,12 @@ msgid "It indicates the organization that will pay for the ordered product" msgstr "Il indique l'organisation qui paiera le produit commandé" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 +#, fuzzy +#| msgid "" +#| "Retreive an API key and whitelist this instance's IP address on " +#| "Namecheap's website" msgid "" -"Retreive an API key and whitelist this instance's IP address on Namecheap's " +"Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" msgstr "" "Récupérez une clé API et ajoutez l'adresse IP de cette instance à la liste " diff --git a/translations/sv.po b/translations/sv.po index 88b52a7..60db79e 100644 --- a/translations/sv.po +++ b/translations/sv.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "PO-Revision-Date: 2025-11-02 12:54+0000\n" "Last-Translator: Maël Gangloff \n" -"Language-Team: Swedish \n" +"Language-Team: Swedish \n" "Language: sv\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -1642,8 +1642,12 @@ msgid "It indicates the organization that will pay for the ordered product" msgstr "Den anger vilken organisation som betalar för den beställda produkten" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 +#, fuzzy +#| msgid "" +#| "Retreive an API key and whitelist this instance's IP address on " +#| "Namecheap's website" msgid "" -"Retreive an API key and whitelist this instance's IP address on Namecheap's " +"Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" msgstr "" "Hämta en API-nyckel och vitlista den här instansens IP-adress på Namecheaps " From d0f03570b8661e130dd179051d7c9c0f6e894c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 13 Nov 2025 18:19:27 +0100 Subject: [PATCH 104/131] docs: update documentation --- .../docs/en/developing/technical-stack.md | 12 +++--- .../docs/en/self-hosting/configuration.mdx | 43 +++++++++++++++++++ .../docs/en/self-hosting/docker-install.md | 18 ++++++++ .../docs/en/self-hosting/getting-started.md | 10 ----- 4 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 docs/src/content/docs/en/self-hosting/configuration.mdx delete mode 100644 docs/src/content/docs/en/self-hosting/getting-started.md diff --git a/docs/src/content/docs/en/developing/technical-stack.md b/docs/src/content/docs/en/developing/technical-stack.md index 0927f0a..72a9676 100644 --- a/docs/src/content/docs/en/developing/technical-stack.md +++ b/docs/src/content/docs/en/developing/technical-stack.md @@ -2,7 +2,7 @@ title: Technical stack --- -This page lists the main technologies used in the project, with links to their reference documentation. Specific version +This page lists the main technologies used in the project, with links to their documentation. Specific version information can be found in the project’s dependency files (`composer.lock`, `package.json`, etc.). The architecture diagram below summarizes how these services interact. @@ -14,14 +14,14 @@ diagram below summarizes how these services interact. The programming language is **PHP**. -The backend is developed using the **Symfony** framework ([reference documentation](https://symfony.com/doc)). +The backend is developed using the **Symfony** framework ([documentation](https://symfony.com/doc)). The API is made possible by the **API Platform** -project ([reference documentation](https://api-platform.com/docs/symfony/)). +project ([documentation](https://api-platform.com/docs/symfony/)). ### SQL database -This project requires a **PostgreSQL** database ([reference documentation](https://www.postgresql.org/docs/current/)). +This project requires a **PostgreSQL** database ([documentation](https://www.postgresql.org/docs/current/)). Other database types cannot be used because some migrations were specifically written to leverage the performance of this database management system. @@ -59,8 +59,8 @@ ___ The language for frontend development is **TypeScript**. -The framework used for the frontend is **React** ([reference documentation](https://react.dev/reference/react)). +The framework used for the frontend is **React** ([documentation](https://react.dev/reference/react)). ### Component Library -The component library used is **Ant Design** ([reference documentation](https://ant.design/components/overview/)). +The component library used is **Ant Design** ([documentation](https://ant.design/components/overview/)). diff --git a/docs/src/content/docs/en/self-hosting/configuration.mdx b/docs/src/content/docs/en/self-hosting/configuration.mdx new file mode 100644 index 0000000..6202f1e --- /dev/null +++ b/docs/src/content/docs/en/self-hosting/configuration.mdx @@ -0,0 +1,43 @@ +--- +title: Configuration +--- + +import {LinkCard} from '@astrojs/starlight/components'; + +## Docker + + +## Environment variables + +| Variable | Description | Default | +|--------------------------------|----------------------------------------------|:---------------------------:| +| `DATABASE_URL` | Please check Symfony config | | +| `OUTGOING_IP` | Outgoing IPv4, needed for some providers | | +| `INFLUXDB_ENABLED` | Enable the connection with InfluxDB | `false` | +| `INFLUXDB_URL` | InfluxDB URL | `http://localhost:8086` | +| `INFLUXDB_TOKEN` | InfluxDB token | | +| `INFLUXDB_BUCKET` | InfluxDB bucket name | `domainwatchdog` | +| `INFLUXDB_ORG` | InfluxDB organization | `domainwatchdog` | +| `LIMITED_FEATURES` | Limit certain features for users | `false` | +| `LIMIT_MAX_WATCHLIST` | Maximum number of Watchlists per user | `0` | +| `LIMIT_MAX_WATCHLIST_DOMAINS` | Maximum number of domains per Watchlist | `0` | +| `LIMIT_MAX_WATCHLIST_WEBHOOKS` | Maximum number of webhooks per Watchlist | `0` | +| `MAILER_SENDER_NAME` | Name of the sender of emails | `Domain Watchdog` | +| `MAILER_SENDER_EMAIL` | Sender's email address | `notifications@example.com` | +| `REGISTRATION_ENABLED` | Enable user registration | `true` | +| `REGISTRATION_VERIFY_EMAIL` | Verify email addresses during registration | `false` | +| `MAILER_DSN` | Please check Symfony config | `null://null` | +| `OAUTH_CLIENT_ID` | Client ID (OAuth 2.0) for using external SSO | | +| `OAUTH_CLIENT_SECRET` | Client secret (OAuth 2.0) | | +| `OAUTH_AUTHORIZATION_URL` | Authorization URL (OAuth 2.0) | | +| `OAUTH_TOKEN_URL` | Token URL (OAuth 2.0) | | +| `OAUTH_USERINFO_URL` | User Info URL (OAuth 2.0) | | +| `OAUTH_SCOPE` | Scope (OAuth 2.0) | | + + +## Authentication + +Currently, there is no way to delete your account, reset your password, or enable multifactor authentication. + +Registering users directly in the interface is recommended for individual instances. For multi-user environments, the +recommended method is to use external SSO via the OAuth 2.0 protocol. diff --git a/docs/src/content/docs/en/self-hosting/docker-install.md b/docs/src/content/docs/en/self-hosting/docker-install.md index 95238a4..ea770cc 100644 --- a/docs/src/content/docs/en/self-hosting/docker-install.md +++ b/docs/src/content/docs/en/self-hosting/docker-install.md @@ -1,3 +1,21 @@ --- title: Install with Docker --- + +1. Download the [docker-compose.yml](https://github.com/maelgangloff/domain-watchdog/blob/develop/docker-compose.yml) + and modify it as needed +2. Download the [.env](https://github.com/maelgangloff/domain-watchdog/blob/develop/.env) and modify it as needed +3. Add static files to customize your instance (under `public/content`) +4. Pull the latest version of the Domain Watchdog image from Docker Hub + +```shell +docker compose pull +``` + +5. Start the project in production environment + +```shell +docker compose up +``` + +By default, the container listens on http://localhost:8080, but you can configure this in environment variables. diff --git a/docs/src/content/docs/en/self-hosting/getting-started.md b/docs/src/content/docs/en/self-hosting/getting-started.md deleted file mode 100644 index 8e941b6..0000000 --- a/docs/src/content/docs/en/self-hosting/getting-started.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Getting started ---- - -## Authentication - -Currently, there is no way to delete your account, reset your password, or enable multifactor authentication. - -Registering users directly in the interface is recommended for individual instances. For multi-user environments, the -recommended method is to use external SSO via the OAuth 2.0 protocol. From aaf0016fce65cd2c0ecbc0af989fb9f2eea13553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 13 Nov 2025 18:26:56 +0100 Subject: [PATCH 105/131] docs: update README.md --- INSTALL.md | 2 +- README.md | 30 +++-- .../docs/en/self-hosting/manual-install.md | 123 ++++++++++++++++++ 3 files changed, 141 insertions(+), 14 deletions(-) create mode 100644 docs/src/content/docs/en/self-hosting/manual-install.md diff --git a/INSTALL.md b/INSTALL.md index c6926e6..740e8b4 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -7,7 +7,7 @@ on [How to deploy a Symfony application](https://symfony.com/doc/current/deploym ### Prerequisites -- PHP 8.2 or higher +- PHP 8.4 or higher - PostgreSQL 16 or higher In order to retrieve information about domain names, Domain Watchdog will query the RDAP server responsible for the TLD. diff --git a/README.md b/README.md index ae76943..576f20c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
Domain Watchdog is an app that uses RDAP to collect publicly available info about domains, track their history, and purchase them. -For more information please check [the wiki](https://github.com/maelgangloff/domain-watchdog/wiki) ! +For more information please check out [the documentation](https://domainwatchdog.eu) ! ## Why use it? @@ -20,23 +20,27 @@ detailed history of events (ownership changes, renewals, etc.) is not feasible w ## Install > [!TIP] -> For more details on the installation procedure, please refer to [INSTALL.md](/INSTALL.md). +> For more details on the installation procedure, please refer to the documentation. ### Docker Deployment -1. Clone the repository -2. Modify environment variables (.env) and add static files to customize your instance (see [INSTALL.md](/INSTALL.md)) -3. Pull the latest version of the Domain Watchdog image from Docker Hub. - ```shell - docker compose pull - ``` -4. Start the project in production environment. If you want, you can also build the Docker image to use yourself. - ```shell - docker compose up - ``` +1. Download the [docker-compose.yml](https://github.com/maelgangloff/domain-watchdog/blob/develop/docker-compose.yml) + and modify it as needed +2. Download the [.env](https://github.com/maelgangloff/domain-watchdog/blob/develop/.env) and modify it as needed +3. Add static files to customize your instance (under `public/content`) +4. Pull the latest version of the Domain Watchdog image from Docker Hub + +```shell +docker compose pull +``` + +5. Start the project in production environment + +```shell +docker compose up +``` By default, the container listens on http://localhost:8080, but you can configure this in environment variables. -See the [Docker Compose file](./docker-compose.yml). ## Features diff --git a/docs/src/content/docs/en/self-hosting/manual-install.md b/docs/src/content/docs/en/self-hosting/manual-install.md new file mode 100644 index 0000000..3a802b2 --- /dev/null +++ b/docs/src/content/docs/en/self-hosting/manual-install.md @@ -0,0 +1,123 @@ +--- +title: Manual Install +--- + +## Installation + +To deploy a Domain Watchdog instance, please refer to the Symfony documentation +on [How to deploy a Symfony application](https://symfony.com/doc/current/deployment.html). + +### Prerequisites + +- PHP 8.4 or higher +- PostgreSQL 16 or higher + +In order to retrieve information about domain names, Domain Watchdog will query the RDAP server responsible for the TLD. +It is crucial that the Domain Watchdog instance is placed in a clean environment from which these servers can be +queried. +In particular, the DNS servers and root certificates of the system must be trusted. + +### Steps + +Clone the repository: + +```shell +git clone https://github.com/maelgangloff/domain-watchdog.git + ``` + +#### Backend + +1. Install dependencies: + ```shell + composer install + ``` +2. Set up your environment variables: + ```shell + cp .env .env.local + ``` +3. Generate the cryptographic key pair for the JWT signature + ```shell + php bin/console lexik:jwt:generate-keypair + ``` +4. Run database migrations: + ```shell + php bin/console doctrine:migrations:migrate + ``` +5. Start the Symfony server: + ```shell + symfony server:start + ``` +6. Build assets: + ```shell + php bin/console assets:install + ``` +7. Don't forget to set up workers to process the [message queue](https://symfony.com/doc/current/messenger.html) + +#### Frontend + +1. Install dependencies: + ```shell + yarn install + ``` +2. Generate language files: + ```shell + yarn run ttag:po2json + ``` +3. Make the final build: + ```shell + yarn build + ``` +4. Add and modify the following files as you wish: + ~~~ + public/content/home.md + public/content/privacy.md + public/content/tos.md + public/content/faq.md + public/images/icons-512.png + public/images/banner.png + public/favicon.ico + ~~~ + +## Update + +**Any updates are your responsibility. Make a backup of the data if necessary.** + +Fetch updates from the remote repository: + +```shell +git pull origin master + ``` + +### Backend + +1. Install dependencies: + ```shell + composer install + ``` +2. Run database migrations: + ```shell + php bin/console doctrine:migrations:migrate + ``` +3. Clearing the Symfony cache: + ```shell + php bin/console cache:clear + ``` +4. Build assets: + ```shell + php bin/console assets:install + ``` + +### Frontend + +1. Install dependencies: + ```shell + yarn install + ``` +2. Generate language files: + ```shell + yarn run ttag:po2json + ``` +3. Make the final build: + ```shell + yarn build + ``` From 50959434619639ccfdad4dac6e6240fe101d4df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 13 Nov 2025 20:51:51 +0100 Subject: [PATCH 106/131] docs: update documentation --- docs/astro.config.mjs | 2 +- docs/public/logo.png | Bin 0 -> 72255 bytes docs/src/assets/logo.png | Bin 72255 -> 21 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/public/logo.png mode change 100644 => 120000 docs/src/assets/logo.png diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 11e2241..6e6803b 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -12,7 +12,7 @@ export default defineConfig({ logo: { src: './src/assets/logo.png' }, - favicon: './src/assets/logo.png', + favicon: 'logo.png', description: 'An app that uses RDAP to collect publicly available info about domains, track their history, and purchase then when they are delete', editLink: { baseUrl: 'https://github.com/maelgangloff/domain-watchdog/edit/develop/docs/' diff --git a/docs/public/logo.png b/docs/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0cdf623fb958e4d4e792c3a1e28c2ea12056be7d GIT binary patch literal 72255 zcmeFYbyQYc7e4yZjg)lrN=SEiO9&zeN;iUZiF7vtN=c)j2nr&K(yamlqJ)5y2uKKm zlER&vbG{n)H^v>`829(zca-DHyZ2su?YZWf^O?_lc7lPvCJ7-uAqs^e(biJCghFBB zBR}}K@D0%swH^F3pN)M*hP;{i6k+ zkdgoKuco%10jr3Bu#kYL6kIPPA|@jwB_k}wDk35yEF>c;0cT?r|7%9bNM%B_q%ca9 zi>j)DwyG+tr?-cri<<)q6__8AF0a+8#Mo_Rq?2?Rdw_NRc8N@VQlix8d8!hXhi9+) z39bYrG`+au4>T%R#R{YR#DOo9=*IEfDI)wbTa#9<;jknSo15jg? zJb9n8vBjn(>Q?UD7OWziyP_t9&CJ$yu3O}rnlRSPmR}m`+7Al8zLTjUJ0InzG~_{zrf#fwYtQ2Um+pm=>Y`vJ@hge^Q)+p{xR~zT$?PQelupEgg<~edbcy zq-*%lcpOBO^9S8L@yS-RZC1k5Yx>hy`B`r~+M6P1Bku>SdQUE6ei>Z8N7%N>Kh*l| z*XTs=3fAqiCnAz&WwJx^5!XBVv? zZwI3w{mXViu6EM)?1~D6a)B~1zzqjq8`i)ZZtgxZf%5F9_-hO`2Om3c7f)Xo4|i5%OdDGdKVNxv zb~w)ZkNMs3)YJRt@a{f;TLJ7L7--`uC@df(c;klPzhB|wtL_hj{5_%n;}t%aZ+bci zUUKm9@bk8FQ1^Fm_vQHaA?)q`dA+Bfx7+FC*xLy@xH;T_Q+?pB!vAqgWW)XQ3d96X zE;l?+uL5KL$C&f6NUza{4&`J`uS5pX2_=+5dR<)05#WJv|vU4?90(dfIC8 z?8yCP>^}5_rO4*A@ib*@z^NTpxO7V+HN=xxeIS4!OOG?{{i%8hmN{dNI{o7F5 z?moUY?sg8yP%yZF3ykAnFD&gKEhfxwZ|f+;FD5N!%MTyK_{D9-rEMjJL~Vpb?f-3v zi{38al{RkwJ}YD>dl<@IT0~k}6mD-L?BKvJCMqS$Zz~}p%r9&&CTb@wDI)D4;dnZf zy`7APhxZK|SWcH4Hck$Lp6*Vk2M~kHC>vCL}B@B`Pf{E-fPT*JGcKXX4=P1D=SCc^W!TFGrR|1|9|sYlHYH z3~>5AJd2E~w}XwZhxcU<4>x)Ce+J!u9@c~HWN+hZqh{ml0E7NB3}60780HlckrDc9 z`p9s49`-JdH~+uRMm7(t9GnkJuI1tb_rH1i)n7Zx$ieHc-~Rg5&E<3}v9g|S3K<)_ zzaGKI#^2$u#e%W^I%MZ;;G=@U)lG6=K7zx{woXoS113^yZ&dc|H=aY)ye@ZP=&<3^axoHW?l( zy%IWH2*rsCLJ_7gDwEkUo$ z;YYIeP(48Tqs9faFG-N#5k!AcYxhOXpgf7fb)043@@VW{3^$w_^^E%?VvJ}qH5*US za9Pvb)d`}u7|SB zK(Fw@Q8r>u)E+@NOGG6d1&ke4hSO$+(Zs5K=`2C?Fb{D*Y6HttFg!u5f&dJ{dWm56 zCTdVS!=5WbD5$IbCF+PPJVq=IImU)Q({`eju@eB+zDCQ3xrqv&bbgPF+4*J?Rmjx$ zhehLo(z2X>AX%H>ro*ItBrAR-t@~%x5nbDe-PX9xM*?iU5fiLHd@Bh9c9>^8(SRi? z45o=ifls4B8;xN)v)`w+osL|lEQKM5Gs~l$;f5xQy~t=zI(r56q)b{19zNOHA0zNm z#{EGpR^nzUc(fDD+ZVP|k*jbnV+ERL+^2yfDMGY(vo^tIW8rXsRfAy=YcC3|U5_S< zER4(jor=ICLy5LQY7ZxT z1{GhruZG;6?K8%ae#U*pOr_-_A^aayxUKi4PY>7}kMmGfp~-@1@E)O|vg#_9Z-}DdOxlNTBFL90t1PEbxBCgvHfQk*dI=en(yg3py)oam&-ijTj=G?WL(C`g)sD*g5Y7mDLM3PA?@moeYbEu#KZY z!Ec8M{GrD$F)DY*?bK8T{cBVN3mVNzs7;~pPdmEEm+ahC8#~pV7YuyJ#Pkjc!c%tm zPQPA0x(o}gQJ^#=w(gDcz|eZ&gg6J8as_=GQwBOjf>Du=Ta!4iJO*R$>|e8|6}g0Q zR5`MgN*aN(mVYSAflQuQe9Z4)ip^;VIk&nen}joYX9_WZ?He!5y*#uw3-RI^y35$g zBVwZAaaxSXJ-TXaus01V&M@aUBdE#_%oW&RVMZt5h8kf4l zK8Ug*i$vZYMylR1uf&eOi(#rY7L!g14`vR zjK8f_+vR`oy?CesKeF7#2*rp)rn+zunIK1&32GayeV$=W^1Cbc+%5E}zu0zBj;z$- z={+TfMV$xAnD*j={^{w3^r*UX+Si%;C0BH?=iDjqPH%dhc4nm!Pu&W;!$NHI^qWfB z=RY3!PL!XQKIXBJ8b3IRjsf~x;3UPSa`u^MK zl^vy)nhN|5NoVs@U%D)6ZS^HnsUfE4?&)>nSicuBaNtpRQRXTO7m%5i<>|0fj5#)#p#cNe}T#K}(1ytUf)x z&gm44b|zoqQQ(h#kos$&(wUZNE<6a_Nm~v}8ptWEJ=9=^^J}X~e>m{34DXSj-tfMa z!WS#ns^TpUWSNDvTZ5ZU$W=KYKdGLM>m#O}ac5|ZrY};;RPFDZ^KBKhw1mOUZRurC zPa4^o7)!#mAx~jAU49o_DrHlp1r6jG?eY{3g9uP!dJK58a(^Gcc?qpuxxTK>7bz6i zlY~r7B~oEOn3K$LBoLXEn${3k(I9pQAH5(lJU+p}*X>-T9OZ>mFK1IO3Rcj$1<^~!UkcARP?;3WAFt1`Xdr9M$h$czY&P(!`-mS zFYSCkbU-b*(uF7VBrLx#*3Q7z&InGXI}AV_?JD73JW`CL zb*bv!K429PIz7FxC!tHpDnQio>C0<|tlAV!mL4z3V~>v*BWWM4s^$0g zuLRI2Q>sUEH(*thMAACKb7yFXir!CV6m?z;Fg7k3S%ItMn9np>3c_Ds87BB_Z>FKC ziTCc^JA+G?BA-1IdH(Wc=bUHTy1%NiF)cCfvabyMpF1(~{(W?Rp*%yjxi^>a0f!@gMuOLH9%Tx}{RO^%DKiucftEj4CUA=bArfvcb z?H|}iGN5*X5FPVa6Fw(7CvKMr8YCUEY)}|Y21_lOdCfDUI&3a1hr4}&>V}Jft z_Xyo5lBTl!D=0cHj)RR2gV&_0t@`Dc#26wPn7yju9f6J*Y)s*dQam@jAKtGFE?pyEKNbh!h(s9nuw2DCr#5m;-@z(ecFqdxVTPxk#>6#FgtD%HGjvuyS(Xzg{iR2 zUESULRg|1-1h!J__-HbfH?y@v6`!uhOuK7ZS~5#`d`WI;^?Iy7zkoQkor zRz??7P47ZP=Um$>pQX+DB*FRS-7itywh@(;@bnfx$&O;e8-7!%&kf^v-KhE1aXbUF zm64&>C?hv2*KOC6oQ{6{cfo;*fsMsQAZe`4fy?4^0SX~{*{mW8} zq^5k-zP`S!TwHk9Ub?G?hALE<@aEmSH|O6NC+_=bWaV~VUShrL*gT%%9)^ghsEtT& zAomrqaQo%>5=+SliW}m3sxB@(FWjdS2kuFhfwSpXWNMy`ZTEyFg@r{{1DwjV(Vu^` z$}DPm*}1E$s}0s9%K>%|iy>)vDKRzyc88=)o47z#k_4W1K0s=i7(~VpE zOGRbn<+#*IF+Xy0gtr3aIyuR5@P}4>b3~m;HyVE^R9&qntgWq`Qc5B)!xlDo)fy3N zFc%0uSg8nHd60d(pdjVN3khZ%WDovQJ$&+{r`E35^XFIX;Gb`~q=I(1%>`&KKC>-V z^6l!Z6{SdFCVG4!Bl^xAs^HaYGaY9_H?h!MT;M`m-1zI!@g-zf^ZD26>W>)uVOE$RZ z^hniVugk{_6`zvQ{ppHTiYD_->^jGR$g$PM+=XK+9kO;Z{0wyaim$ik)YMdRMNufd zVC#_xY~K)e++!aPse$qn`m-}wx6+X91Y1BjUzayxStH0q zVp9lk{LczYO49sj+9o~E%RA@&YHuT-i6hyb7#9m{1<~|L^Y5!izhAa?=S%xwj%w5L zW0tg@-PY)H_uyN<&^=WEp=uV^y0=fTmH6f4ItQ^vL&TCHX>XDaGt%8WHzcA9bXfjvDvw!@|B4GXEVHU8^Yqhn&W9x^6i zM`CwyPp8*vp?EXqA#9tOC5%~xF(C`~K3}?Xl`>wMpse;o-d?WRhx-$5Js%$EY<?`|#2cf|D8##r zl<$8<@AxJ2tfWJ5$Ha~dTMu|Tmh|UvcVWV*sJr##kH_=p&o>K54^M=pyx6oU+*|e? zk2V5YJCo@|gZ(v|rH3{;W`pemV=mt#QdwJ!cLz-dAxfA64$*+aoHJ76*5Y>8;*YVc}?DUIrm=n#}0Y* z*CTCKAX3y-l$%~OK%SKQ_0dQwaI-kgjw0Z?-Ed9q^q@t+bj-~0@0VJ-x?ejU3NB5` zOJ{#MKXbF$GL*D>WTnB!ONtQ^ct->lp69`iOTOIAjO^+9$@L>b#w3cGX$jFG2u+T4 zbO{LwTH4y}NBi4eutzxHF>s^WD{hV&(7By>*@ZdX6yV!w@mn=nn|ygDCMKrlYIV~x zwGOj`-J4Q&z6)e$&*IcgBtz`Ax3_17i;1ZD+WK=vh25v5iUzqfQjTuL>~P}ZiYQn< zrGXm`%54)fhaGuAE-iW-ZRbTI9MPxt;|`CJ=gFU4aPSQ!b8|+T>zzCr1QhscEX01r zI0OEV;ljz69=)+73@yMyEVeUiS+6k!w z249tq&RK5lgcU&6t*rEXWezic`1rBv&70Et`BLq!Isnj~*Vnhtd2W{B3O^T!egB7H zJ$_7oLO_Oxhv4P3KSK-b#|6mL5G;;F6WO*(C`#S>0bv1l+4^$p$K0LrR;bC; zD#V_+cG-VXQhBrJJ-3)`)dLSWG(P@jo1~|7=yzIw{O}_%>{P%^NW<=zTjZ3K3zX77 zi+rdoSR<5(qiC0(WJfGFb&a`Azdn2N%jzU1F_G|Lwq zOn|R(o$W;WIIBLGR@807VkFy3gS`Q*hZg2xe}2U$By5puSD9X{Sz=!e8~*q)I^^*8 zT>Y43XL}T$P5sp<6APo~%5!sbM@x0F>c|eOGON3to13t+;|rVS%by{8k^Ojux{3aK z;ow?qA|e!EF@ORFR53G&HWNqlK|h0<_jX1uZVjoPnOhz%EBS{1`i@O%Qc~x|umdB+ zGBAe~igp{rryK6&w>`ly*b}UxU0)^r^|>|3QW>QqSx)wPrM%{`6(t>H?;8j^+OnN9 z%SwkyC?0R6AuwjmU$);-l;s+A-qXrT1U}~F<<*3pgsx4!qWtvfQ?OGXV@xZn-C)PU z*52iU9gk$nwR>!9hYTqi4=WSjywRHS>?GM+6bwt~@7HZ%U{1WR{`)5H`SY7S3?9}a z<$BIHZp8F05*~;v3jdr9d)}5WOBsWD?JGnT1AYZXL416CTgEvZ&xI68c7A>mFE1}G zef{6$MDwBo+}v#(X>yTg6pw@+s(6S!5zKsxT``itV^lu-vh@%DM#BOr3)}h8cw&Zb}W9^*H`N@!l_#za~9To=_b8EHqozNzqsM%S^U>-XJ^O3l5eABP7d}XDCWAz z_>wf@WiJlD#kq!GyF`SluC5MTDhMzzH&4c62_}1d5g3^)%{FW?{DOh?sHXU-Mwqmm&K3NM&AaD()?CO=brTmbao|B zhKyR;*>N22hMmx`K*)HLh$X>1pHnCsKnlpV8%`jH;G>-}>;1}F;$Hgg+u^Xcz^zz@ zsh9W3?R?)GVA}*nWBP3H-G?CUwK=PdV8}OpeX3B?%HM#F4yiV`CGzToP9k`X?w>Vcv51#km+kAxpVz#H(~}K& ziF{fa(b3V^{Y8o_$XQQbe?O1rFnYHmBQw$N95<{S%>ztGorh?)O3p! zm{0%_Nl{vQdfiCKoN&mVi)C=1osXCh*}A~1Opa}PyHWhxER}l1fMX{BujH3Ap$s=~ z-VAPk=HoTITpKOusHUpU7~iPw#dQzrHrR(S4G08oUz+GnwiQpJzy%Jcn8|t{RR~k2 zk-nzHiLhkp-zQ&o(#eR1@FFHAMx0QG3WusQUonhXzhY$Rz|pF=RI#YG@duZ}y~5DK zlaqa}3K3ZTt#&*XRz*dYF^d2u=FmNx`{m^wP}2YohDf7eSYq%@by`02;2=m$TzsGL z7Bv-B+v+dd$rm>uz4orZoJoa3=>Q$^o4SBqLlMYnQ`-26-~NqEvH=@iC8}}A{@Nsy zlI1=7m@v`ld5L3xmoU|j;fnkBXCv^K+ejp*!t0y{=K&~pTb&$SfrJyv*XA!-R&RZW zn-=PX_g!I}AH%J%_KUxlj0yfO$c7{|DSm(Jm zE*u>+`%%%hhp{#1On0fSVACchArX;RAOB11#dmk1%--f%V%7?#K$FE=ew3N~gJo6t ztL1Q`alFO}&m&`%upNZ0cOBs*MA&9nK>+h07`QOc4#7iFaYz+ITzV-vE@*0Oer2e0;?Pcz) zG=6MdH?g@~mR4F`-cvDY^RQaj>xr<}8+YRUmtg^~%=h5XW;czM^-N1h!(!Go&&9h} z*f}}N$E0;{E3wYrD;P-p4*bVu6O(x;wmS}gw5Bcera=tZ&zG%BKG>kX`jFEoLE}P} z0}}HZR-ZKP$^V9;1_w%bh1lfvSk1$UXJKM*ZEHb->OJI>nL^@2sHdj~$rpj=IW}UN zkB<)1fEI!Dlcsn~3+Vfz!an**6Z)SJgryR^iKYaM`yg)YKdS&Hx zJW|FXDBQ)(vc#J$6~FZ=SB$u{9(;QGyu7@;c;HG}ZzoO%0Ey>&dx7qIy&0KQ1<>is zdu#szNQ(N_KkFWOeTyFe0+sMvyuQ;K8%p993Khn6$tlk$e+ZJ*P=HLT4GU0|U15Dg zrAnahoEh^SsZ8ds%^Xm_aGLfBafFrjA31M!uuz`%1FKx%#a<|ub^ zwEbpaKwU!vcjMI(b60O~r?t>tvTXI>#@PKmr_pO)VGq+FhmIf}NJ4aJl$SWCQNmQp zwp=v4rMPPUR=zilr56aGM3&>tIHaWaU|EH#^%b*dPl@lz>sI~r>8B=CI7kiNvOnO_ zvFL5HI$AB|yKImhx@-4|woZWrSc;}8AEB_=-UVeJAJM@{T35Swqg<=m?e8abfUvr` z?Fj4&QoABCt;omL;|vAC^rZZ6C&)(6q;h-x|t4U_Y}igvWkjk)@w(ty&ayk9tY`VIp}3A3d=fmn`8er zv$M0SSNyYbF>h@3lfuc7&w6Q+zz5(G_wh?SgT<+OBQnr%SLJ(>9)-Ulsa-cVHkMn8 zNoCYnBFCDxU5@gm4xp-HepT**&^Ewm)&NAfeEISwr%H(lg>+8iRg<}m-;*A_;$!Af z5W-ARwl#1-OC7^Yn<*r)v0>bZUr?5%gUN@8AJw<>FwhA;$(sMeVJWv>fFxC2sb}}_r=hkl)zbTGc!s2?p$;wI+k8Q+8{buIvUv$hEgJpV1O?9k^R~BgG3?zn!x4Jsh5`F9$Gb8< z-rk${W{z;f_WP_1tgHqzm2N$|D|U<~(`cfnP70}E7fDG;*@Fd&M*tev#lq-z>rIyl zUCLXV!%@;c->g?YJb+9D1s1}1o_Q5_$@IfaZlk$CVVCr{MIl=I=ndy()n=&Q)YaAZ zHapJ@fBu|!&!Z)m=8w%ZQNpa}#+0<&;aXkb(N?e5?=`ccFCuG>SBm4$C}Y}uJ!9Y` z{S}bE^`C=ZfdIb@jg7m{imayTm%NQ25_aSUBFUusYK(dkb;;}3^d3!HxSv0N?l~HW z*|5IJ=l)XGxjH-dcKy|AHm1*a(FB#1wt&L81qI`PN3~0nkByJV2Vz!1@~s(3aB%Lr z?<;dpDaP^VE|jBBtQ0 z9RIDv*nE?B<1|8;_c|0eUfmkk1*qBFJY7+1{4j;LbKQRdppynvG07SnExXM>{OD*B z*@;8@%_3h`Rw7_r!fia9|JsX9t*pSKPm`h?TCC=tza9fG48$sAd={3F9de#YwyC#o zpCtn$GxzPDhlZOQA4IeCqN2eRtXp~ylar*zOs{lU8>iZu&E8A#;4FS{*xQSGP#ea)Nr%4GIy*BjccXV0q0 zGoO)>kwL&c!mNNbn?6048e3V;!tTHkr(UDaHO=$e-IzXwX0Kn%SYD3BR`Cq*?BA@c zOx#-NT>#V_4hxh($z@<*FtlhElUG7kkO`3CPVG+GXpN}Ny#eYE?8%?*TED`t&@WK& z^%cwFGm8WiA1KERq*JC6?fn!702hS;#oUD8^49fNw?60y&H*}8Gcq#DHfMM(qmMZk zDa$|F-@W3CbT&GWS`g^W*SSL2xT;glE_t}>hBeUDnF`sRu9F^e)i5kk{V(wBkDsigThvJg7)sFbfLiU0c7_44j#E?S zobInzIH7bwNM_ikM|oBcQ{{;sKZ~v&9UT?e?ZHd>be$w9`^|7FFrPp&13pCh zJ;skshKq^QS+QDPmvojAEG{mNH+XS;3E8!PmWgMCE@ldLM@=FYO5tu(%icWE5kv`1 zef`uydt#00Tl0^-oQMijZo$I~H1Ax}%@x4`#C{qO;ifkve7Nb2P;%PBrVH&ER8cqG zg!67-9Qr`J(c8zz@XD1q=q610j_4tTg)P?dve)JUzf9;0n-MXRvuDrl{rM4=2Hd|V zgVH@QfP~iryG1wi^5~D|&V(tsy9-R4&~jq6`@aFie8nn69KvQ|QqtC2uA)tgYSUCm z=n0EXLcM4E-IJg~639-nS|IWx@9CIEA%*#%!Xa@6noVAwiN-3}D|`OJotMJT8RC)Q zfwxfB*VoSuWwS5RW+j#e2BczS4hXzJ;5loZ2AT81JMEJvwo-TI+OhlnmQ@FrMzq}H9WBo7}x+$6WB(qoMfLhog-LZFBGyz|?@yPe0c|I__W_8ZD5xfUs8fF@VMgFnO!ZCGMUR4MB3u0MuZs z1#flJNcnstE-fn)4m%FEcXaG<7K0}wd2K^I>^IVOfxphR!Y#S3u5PP?NU*rNI%V)m z;um0EpS|Tad2|TOQ>{%Wu9&2x(T;Uavd|>Ib6)JjhunPEUJwIyii3l*2WT(Ek|uGm zW5z5=Lo{cp*5vVBqFMtQ{D^O6etzPBmobfvg>U|}w|8*Z_Z>lViTm0Oj$%+^KW#mh zk+|_02pzi3U-os{tk~0gh0;E_VSiSw49(5gGRZV?eVlu)^~+oL_(6jMSfSWy_g;uT zH;rgSa#}0|x+~*!#fYgJr%CS(^dx;CYf%}!Ue6AVKfo%PoO&H#EgOk@fVY?3k3FRx zyw{7KT-N|x`z3f=j|!;L{Kq?dTCCV-le!~sOum={EEW6K{`;j5nN%x7GP3@+=He8O z*q|mtmivst9*Q|F?#dZ-FiBBm<@81|E@qz#tMZiJ`)8~5&=l!S=g=&6p-0-=P`9fX zQeCiT#?9fk{v-5rdwc7n(Z!Ny&z|Y56GGRbm`0vAyQ=a$?2D~~)u-FC4Zej^JE{6> zyw*arw}HojL;*!-$-{^E-QC@CU-kCr6@NP=byJ8%y{U}-z_k6O#*QhArfg&-@VSoL zrW!F*zsW5*W@yr)+U7drYHv(RSTyXOZ@!j!x1=4SC_`JtllAW!!|Y4sTtj zoSd8%zzeA4mpf^n2?Vz1)Ine4N3=`-trv7a3jv})xccZyC3-ZBNs3@mBAsy?k}d`w2fsAy;wzP`;wA?9Nj5&6LNlj5DcYV3hoyu+4R z*W>DHl9Qt)MSzCt`*>(FTb{*V1^yqaaofdL(8=PEl+2EM_9$k1GYL!G5F8%q7v6vHprpS3EHr(gNr5Ijuwjil zSNgEadqypnuTSpEHzHI!)JVE8L9~LP zTNc%lr&LYA4@=-v4$bR1Vt<&`FmOPc>}tBX9awz`Vf$U_kGLU1$8+6tmPAn@J@aF` z-E4JZ#5+qOah;{tV2!12{zTiGA@~ir`nQs7C11$5RpPPDvY>&Qx;qob0%=d-MDw=N zvX@O=88EQWl!*rvfKY5sSt^e^SEs&{nDKNN8F8Uz@U2YLELE*p10v1mk+R!$D>RM2X*9ECP{^c+oY|9ci` zZ)~T*!o`@)hZMZhWZiT1>6qQSJ3L5_9MGBP_m4b9 zlO$?0{`$5!uiAm2%wO|VBkKw-*|@%z)KMZhU(97VG&Z>MW7ACSXWgJe=Wv-OL`=_L zpRTAr9aA-=sze20sBtE3Aao}%voi<*8`Z8f<{yWeHWe=i83POdZEjk}PZJYcsRYrk zPhR0di4rxo+6~oKcu$W8^J0nm^vf-(fXOIwlQrT1ZVngQ1<^3JH^)`ngstvx6^i)! z45)B`pNH50S);$wRKbk}c2=HK%lb zkDF*xb0G^7QNzaTRUxl=H9o5r#zz13Qt99b4uV_1*AOBDJoJDngZ$>#)8(Y3Ig?l3zUaNxn#2}5Y*<$WxE{m;(Csy} zvPz4M#YOsUE504>FFS2(+uUCs;^S{Yusp+p0;mvyghya(djQSGO*aM@DJBuQtwJNk zb8pk;{{8!)F)>ohz*ZU5(9S?Z(YH3!$^yU%O)7Bvos+gXh-8!j7lPjcH*9e2T3?FL zV)Rakd)+s2)q3~Xpx$0~9CC7U@QWDBr3qElX{Tk)_;7 z0C5~FBzgQPu}m|qw56p*2aC)0tJF?=TgQ$}!F#S`7G~yD2-MIgu$}Kp$Psg)fF8yx zZtK;{Rlisz%Gl1Pr8ki1Z5b*o6xhpvf2y ztUnOPKliIfR-l7|RH$>VR)_TS^Yfm-XwL$)+)0p0-f%p11~>y0A_#_@ z!?jp<*76bZ8#?05vFx#95x`Z2IyTwArATH`WCp4hQe4f&MYSM_kfJfZs`reW)`b^q zqUneZ4>cn}DA;bT1TK@2k#QS}Jm`b`B_cYE$E%%pDPEvF;Z2Rme;W2BJV$Z1XnA~k zH!UGSSyz|1T)%)2>;v2C&fU8uP~!pf+%)YEyv5I-KWiKZ=!3WK&2+gwZH|RNCm_c? z|Q9Kz9e!tSA%0#0IeV`ulUOJtNWq~{g%Lb~FC*i}+ zT`eJpNOk8BpuN*#WNWjXPNr~nhVro6e+9}M5J+eefOiPPp350+}4m;Vh)8~r9kVEH^9lckB^L`JZDjiqN^ z^o_3m;;?o4KC_m*K2%m(DsE88EczRlpKXO8|5EUs_46V z)E;JUo+ZN?Ae+pwj*Wu@3)-GiAqQfhJ|bgbNjvSJ0-*{O^Xyh&@!0AsRJm5irktX7 z2BItgbj%?wor@cTtukAX0@SIiD=)aleyd@|e2h&`G98kLL5BAw>?DLyK1j@YcTbf+ zvhDrHZg!>4KMI&J2j{d^kfN$(&lY+_wjI#~uuB(z46pkiqUjPz&G>eMOFG)-&FvFX z=F{<_&d$Ak^F}EsNalT!Vj2XBh0$vshzO|$oDb>QLWu+@hjT+nL2|Zlxprhl4McDs zMn?AiCfb>M$?cR_<7Mg94GoNpq9EdJb?XmD&0Tw5T3ICHcm7G!&kN8tUDzH}Tq3Zd zQeHlpq7Ik@T@_!~OhNnlMo9ckGC&i^)^i-li-FPx9Ct6j{V;5>kdO(dGGok&OZfKK z0nN_#6=WZO$yG$^4=lZX>_XE6W5@j-S&|@#H83%W1;#P3*%EOd=%4~2 zaMTdVp3})i4KhL4Lqo&E5dg1HRu<{!AYa7q<7uWb|9UjP+U^cdQ7W8(z8p9Rypcp*2%z*Y7Yl;%jQ$1al_iPJ~BEw0<)}}A>?VjSY^Y@ zl;^&0jI$1jt5P$Od${cFCRxu%H4D~eu>0Ubjt1G@t~Ne8h)R8h{dQ30@>@$T4Ys4S zP*e3c1eBcC)35zvB1F$g0o$mV-2SN{>dHK9gi)RwfG|;@MKC?VR2vor`j`o~Z#X4LqzZ!u7DBIrz-w~-H=PH&l&h+4 zC`cx``S`jL&+LT^nErc>UuG z7b1e&)duHONXgD|ww}3?>Uk$SR;D_59XP2dE=m3SVT6uC`1Ek_UKhxFIgP8V)8UZeDo_)cij*;^)*2 zsbEha4gtRSu)10uVMPRPcD4Cyfu^XJoCFsH(wT3+))7&M6+&`2mu()2lrua$2}uMd z>jqSdA>@*L(Sz^KCN+it>j9#PvIh@vB<_(wNQWLMGNh4F=EX<$FZ#}i6?J*{&et1& z7Xl>+ahDZz$q=_7v>aV14^t^Ios3Xt4r1_-2-P)xHSG>e7o2DAGa#;|rKJSntg^C_ zJ5dOGHA=k&qCa@nK4bBv4K!JU7i=Sh@G#bA{MP+8U+wZ`s?jGFN#K~pWo1}UU_5;K zlq*W=4HJb=5Zo=Ql7TgL$4{o(Id9`QvzNMmQ^`r%Y_hsY7 z0(mn6N3b8zMxeq2H6|VO%V4-&>Fb*`{LOyHJA;p`ZNi`yL>h$aWGEOT9Yh8YBoQ&X zv^1TepME3LG3FaI=w`3VC>X`8iS3S!0c=Lvxde+W&Z%F3oRl<;0WEhzFsqx6i8 zWgPMSB3NUw!I=pO374-A3km8=j3UZ>M1cxUgTyg}6$-?W52B7rdk?-r{QaPqd(Bjs zgY!$yf}XB!7gCIX*i}tKafNTb(K%_dgUw0H?{YByD zMSsxrL!Zjo-Ce`WOBi5Q`kgz`z`fWZXbRQ<2wfVns&S)$F?1sX<<_2Z2D(2-7z;8j zu$CGiIkebkD%I10*bi~_Y2R@6O`T-J2v&tapr@gyzI_`l{a`MM9U|lcDE`y{xxzXk zfC>s0W|ea8j@e#mKED3mIg*~`+yTdpo$>lEB)aVXT+D$e_oIMSg7y24RQ(Jz&>rv? zgc-%ppHl%K1_pO7B`v4edNH9JTg@w!1Xp+^o$0I)11P|UK^6@0AA(~sgia`00jMh3 z+Oh)35+U%2o(rD=mmF!E*M0mZW0V9xux4w>LJDV+uNls zZdLjOjJZvmh)YP6g2JZaV$nD97l$Lc;LrhT{Lk)88rT_LreKuyCx$S* zP3}T9OgAniTHCkr8;jPn9X-4f8yB~ohXK+JM70TiwIeY6@{7vz<1rdzV?QN~z-gGGj{R+G6LtH>8vbR` z>T*Fr%n^iAKxEjw%{T{rW8gF9HKozixF^YzlapS@M>oHBDq*$@^&2KhoMw) zQOCs6)7&HON)4}PgoMZ=cnet2C*QmEL)A_gWq5B>F*7rZ*>UxWcqH7*$cTKPlWhy` z+(hCN#?HX!5nfR7vc4W+-9U>6j{p1B{CN$u1{UAe#Pxb8N0_1b?smwwi2eH2o;wi} zYNa0w%(cXR(3U}H;bzOU$Vg0Z#m`g39|UU6L5{%rx?Kr#j@MLD(5sY8)m09Bv~-9T_+YrwR#@=qx;iw>AjE0rtKk!2zhKQZdTqe( zrK(O_Bf0=EdiIs$0FJa(5xjUChqOB;<}eHlJ-6%e*k?F7n_lS`H}!rTh6`D z^{!s4)h|J0)xNN04J-tNB2F)AHC3)JlajQ=a`zQ)<6~|*9IHT20)cv?qtHK%SBQDh zO^@II)+Mi}3>SP(F0z9AUCv{5c0#*RlLlzYUa{~yDv7TzGl|U=Q@mA!Snd}nuJ;2_83=mO~3KR!n zoI8BD64~lY9Ua5EtUJEdPq<74;8mD*AaA{PmJPv&io83T2~>sU-0QC*+X&SEoB9QO zVK!B2DVXP6pIInUUImh)1NI>=K4kN+Hoq+WNnAUTpIXJb^hCQ3iY^Sk_WLW>~ZNr4dr z?v}&pAGSZgzD0!tT(?EEt{xt{+D)Z6^i4}8F7$&ryB<1I*FMHc7l6bE(cc3IS|9mL zMu~<<0CW-1DoEQG6j%bJS_V2zZ!SS1{=G4s1P}v48#CSV`WtoKy^kxtpb2i+n@{o@ zR;L*@WJ-Yd*xU1{_?~N0q8k?8F@A_9phSAP2tb0m2qDUK1e>EFbHQ2_74Q-~XB99o z(@;~3zId+t_>O|VOaannf>Qrrr~ddx8qDVV_wR`27crQ^%NXYnXNA&gsMiq!4PNX4 z=4bHFCd;IfZSta_bb&sSwn3z-dj0zOi^S#PpCpz0M~Mk=DexIb>r;rYY|<2zyFkU= zGaWFKBJMi6>G`WCg#p?G>zQUV*)`(B0pks^F){o0_PY+jW(vqlgRrp=f}a)|6WFId z0%QeF)q%Y3@WnKtTKX!76;pc+`U^nH1z2>1o(&`En<4iokAJVrH`)K$GmSx#6hTBC z9UTY0mz9HY8Z+p%sae0|j1t%rv7=uCBsOEO|Ql7tm!$h-(J93^b>2HUI8DZ}r+-05&Ir{s2BeT2&a# zD)btAC6M?Of<2=`FfGWw6wX>=5%AVJVjjv;`XKMqJd9wp7#vh~a}pRmV%1_LQza9( zCUpVPN#NIXO(A$s00KACdPZ8Yz&Jd-FhQn>H~YBfLjS9PrTp%DxNC{#0H~naAB?fQ zXvJ$uBay2MTU#phND5j=E?lF7PEN3Qhlaw}*4*-C15!_9`*f_semv1Z>zF4eB(y{O z5%%y!^Q)Z$CK?-KVZcMirh20rupATO$J))j0Y^l* z2^1sjLKb7=3!3i^oa|QM%^*X=2w>+QRuaNnp2o(nX1{B*)|6g`O4h~21(?AF@^jC8 zzT!bc$+lO0hsob^z&{PJ1faaYy}7tr@5KuOq@h5o!HcIk3`(}nOCpr65HHlA*^y=& zDIMz1cNyq<05ejIsS4Tm9GD2NUA>Cf1*VfKqbi#*s&GpXfEW0gD(oeAYZTi4G#C-3 z9=3PF3#u!C^7;JS1=`|s_2h2|Qd^{zG3PKZMn{B$_|xRv7L7_C{E?%-o)Yz!LqyOOToU3%Xs=olGMzAu#T54zSov0 zx(M%&!TdFuoa3Y#{JKZ`;k6i0a^t`Y4rW=m)~>Xxu_O)E(xbs7A?MTdN|nm;q|ju+ zG-ZHZV??#0WIg^ZNFBOyts?2uHFtjv&v zjHpC}mQs>5jm&6}RHUpBqU;s&d%QZI?{)pob^bWl=^XC+{eF$-^Rb?gcpW%;X?nWE z*5LNFYZTO2W#jGJc`g6G_?7ZUIHUdWv16~YHBW(G=o+y13E&XAcuLF!C<3PfmQPMF zzrhysjW17Hxi}^KWKlXkSgRLcFvc2r&=lfJtuxqXfsj2D1QeF$KHQ77`;L{zpjuxT z^*8zxq@2lCxVTRJlENpqH; zc<-VJ|Kp#%{DQ+xsqY%m zedXuoMoMST*0q$h!Tt-t)3u@Qt1UY-ts#4eo~fU7D?5XZxR$FW#56Lbu^x0#n|3 z=Kk6t`%R3|5$a+$1@+4t;JQCm|`h4vynL1nsq`%7XzI5k$z2W`MSEQ@hONJ}h4py0GC`Bpb= zKPP(j#-1wxk_}~`iYWvS5%m>{f|EBTiZQPN7fDQ znTe9F-Y^Fj&rTO4{qajf-Bwl<#Q(pkB*k(9Gj`?>9flRQ3lKNX8qpjG#% zZc90La;deobz&-KMUWhPP`sgznSl3bHM(d@h1o3kK93~78mOztCV(m)jI6ApZmtm zoA5!$FZA)upH+Uv243mTd<7y2L$Z*=4cYUi5mg0@834MqRa?$0UMB>*iR`6 z#$Z|e0RQ>D;Bv{ig-Zez0qp&;@7$SfYjpPW$?X>s7H$fd(EQ~RwJ{7gC)m01)||iG z0bN1Ta1(Y9T-mH1;PFEDc;aFJ`@s|6K<7f=^e@X|6X&K!mgAK%z+wmiiy{DkH_Tvj zfy_HJe!H|h#F_Q+^XF>!5_F5nY77q)^As76M~eQI`D4#5l@=X2B;)b+a%8MX82^ro za#i5PC!lKQfEcFt`%7&W&D8k*2Xlv2Gmm$kZ0p4?*@}+4e)WxTM{0l7cjubVnk4+) zJJ{}V%+oXCpHcXG(VFvaYO~AOG(?30flfH z;_@EZJ>nwcbbc)bAi#J@&N2%zN&$)s%8pqvx8=U$B4PH{k@R>)MX!h<2*oU%)Cq%X zWSc_+g&tjN?@9SI+wn?GYkYsy&#sWxmp_)~jh9}3?lklPlchpGGsTX-Ta>Q;kaFUz zF}qCdXQhX7!~v|mve0}Sb{rSD1Ok6#c;Kq}!F7fwAW1w(ux{=m@RPO2$~ZDIGD7yg z)ruXmt}6^#*%0MD_%`7eT2jIi6LCfipMwtUW&!5G<=Ji0{HFS^x>i;^#$H7AJ-Vzltyp^WZk>46!5y+^=}tVBn9@#IN~Y; zXE)yy#YTRcjgme^k(~i|YAzZ#{FuP$7UKzQQsu(vw6h#f!CaR`ZcH)Mz@_IQ3q6aT3)0x)JK-ROSVi-S^7HdKATt9~042`+a+sh-AUnbAu+GQf z)yRMGA~TYCo7sU)e5b2KiLMW+DKJ(A7ztj*359c1ebh+Z0DnB9(QBvtthK-DkyU{K zN)He61`$3MeY+-RU5HY8$C2VkA3)4ikfr0x8|weFeg!u-~~ie=~&T9 z?xek81q}J+^}Oz&L7}qQj>BrFX629+!==jk;gJo1UQ#QWn>RhJi1(ZcRJcZd{Ys{-gfla@==k|s(9=*6Ll7?R+rlil{E|}vJ`}&fK~nW z{3P=~cWjQ<>U2|;yc1DH#@Dvb!8>S(5(|y81pS1yBGXd2)y~ASgS&(e%+1Uw{t1)g zG3YujB_SaS{OQm#MDDzy76Yfm!dF7HMErks)cLJuXgH)S;HfMCsqD?&gbaaNp4__V z?Z>`65U)5NZRNJ~7l*w2>Afg?NQ*w{czxHUH17~N1??6XKC$V@&zG=TFFLWkA^*9XgRP&1J^jvj-m+JGqeX%*qqaLlY z^PBg+^;C92Nn-oVR}!W5o1A8zxX+e`#?ZKdHGum8Z!fiXSUicJ3pz-SnXCVnB5gf(9Snw>sxVh+3}Q z=jHYD@*i3n8XC@eH#zsyA0)8EP=6Huvdp!-R#@n5-_3=ej`E|P>3!8sN|MD9_O%9w zjYgDGwz6vM(`&XWu>KA#n}L=ZMZBT2b8mvDmYI7I97)qNGsQEa4+QSCr}1ghM4$~L zU{++KTk5wdJ!<+Tg}cb~q6?|hxx0#$z26Cna3`$z)I&bZ_wx4Muv)ii6KkgG5dqze z`|f?_V3o?+sdeER0Ai^NCRRH*emeAvFn_9E^ExO&%9w?MQUva9CAYiO|Gvx5OK5jrin1YA2%Bb!lZ)UU_#&4$%ld8aD?hsSl*SgVgizeoTB@EG~C zg;UL;kL;MZwze-cq*R3Y_^^94Wsw~m930%T~ zc9`m_m-~iq%Ubt>fY?EOrf;sz^H_(9+Jeg%^bo#Wg5hO`gIgREez$lk=Rpt!SubZS z7YiNy@Dxa>sn;dcP+m!r-;SH8jHIj+X!v^3?P zFW32=lQ^oJGIC9y)IgxnIQ=En)lYTI#^~ij6J@Yx4-axJJVG9?;_?06RlXJ-Z$dib z7SWKIpL+n=%A}iqPUQHxZ6NA3btDD&F39IMZg=>uNWC2&S3m)aeT={`xyv+E>_!z% z_z=P6!uTBE`_kW+PR$(bJ+$4I1w~aL&|(f2I%rlT#MGezd6%2BV@?fEAB-fPtbhAE z?!-HmGVMO=o_s}lzY22gyPviV@T^R~f(CxwI_KzZGL=WQa*ol?XnkJP)sB6>DsU&Z z57UcIts{m9@LREAz3pqoWz-awK_t%B6N|FDBpQ@Qh>_5X34*`~mt-^v* zZkdXrK%Y?B$3+Y7M`c>#>^@1HK(Hvae zgcb7}wt|+~)cthxh~d(Pfh;spgE`^ZiCRBmpWe2X1#`YRT9Yq}o=U?vS|Y$~W3bYi z-0|-wlVYz6DEdp?!1tg^5kIqK;>ScFU=MxPT&7a(?LLien~Q0pBa%>H`1{X3Qe?2! zF(dQmPss?;F1&)&0GAUt)2cgn@3y>uPr>6#NzYEA z;?VxE5B&1*tsIyjL;~a)_C>HzmwR3hc>)6z$`R8){R2)eTKtZ0Z`j=31!))LR!{fe z=iu6epMW=Z_*mwKYjMrRY%DD3kREDGniYyy2HZ~f^6~Mpcjv>p1(FK3px!dUKM8_x zWJKhLt!7h`Nq15ffPJ%lZk)22JoxM!bTi#!#vvg~X-e|0#THAi@M+PrqRFy5Cn=aP z`?z_q1{YF$l~&iH$z1uZYjgg#TA7grFZueTn9-*Gd2a*Kpa8Z@s}pb?r%$r=)#{m zZO(9d^3}snsBs;X0{AA=v$N*RI@eBDTh$er2(b5DzEsNKi;d@X z9G+={kwD}%>M-nd`y_hu0>2uevZeJue)q*Wg6GTZYvC;sM+rjq>{U`54uFehe;N4g&spTAq?`8 zEnlwwX8U7@J%)-IKpHt@xIc8RXJ2zffoDAY>RMD>fLb6kdKx(K{gHWp*637ksVE&i zz2wF#xwfoZ^KV$oDk>}2R>-5m9BC_pC-Xu=OSZgLQpgpnf@qt&Ap2k9rpmB>x_tv0 znVU*^JGt@7V6TJ_FPPRUhi&fl%D(&-l1RZ{N_|CSKg5NvWEy-zGx|>(;)CImBnr-t zUMhmDv2N^d{Jzm|UF&N=8HZtJ9Y4!=09m8s8BED_Pn0@-`J2%4zn1aP1S})$mYk&+ z{*?Va`Y9NtuU?$-27H{evgAR;L>o8m^nDj_Cq#C|A;>=QgDeSR0<}?czIWhqw~DHc z@`79j;*>){XF5AOi4zgGitL6BlASEO%l(&{SJOqIa3%O7N{}$9^B-0j_0~(tax<~8 zvYJZme_f>bvG$FVg3S6dYZ-1lD8lfJ2xnMmWs8`W;^ZK?C%6kx^TT-WlShww zt_F1JIy;_u$IODM!u$MX5zg?+o*TZ zj1dao$MHCB7Zg-IKRIH{7OIw{nr#+sV0|171#Sjs1^)W$nZuHsGt3GtH-7U_Y*6`Q z@_W7^MclU7Wfgji%e#9{OmZFPoZQ5w^~$7_t$%+G45Fa8a&O(DCs7pqYgP7eQ7woy zz!#mUUaVjpzGUlI!#3aB&5@nEOO_b(qd$3Fot&}0`-wD-VUQixpa&p!c_4&P8B3+9 z3mUv25{+uuWN_9tt7N80Z9q=!Z-&psra^`saJJ9Ad~Uj0+dD)6i;^tPu4 zKMNqV-W!)3s+F2GXmXlgO|~ohc*ne*0rf;9N~>^CZpX9A~|p68n3$rCy)X_@+Lb z_%%9OOESKQ42ygV2jn><*ZH~L8}Ou@z7LTrL?3HNsu{8Sg#dDyZ%GP^ZfY`TRA6{g zZqYK~HqG4cJGu1Y_uL|ZlwcT3pj%*I%o^!>#*MGmxUZ@;2~Qp`{GU>}Zn15We^%oEg7# zOLquY<$RsIp81}vbE?MnndrJqg1wbzBR;ad%KH&SK?w|ey%&G`zcBvg2VX(q8>c%I zYR4l*mNJB9CA$K!{1#%fE`xj;mu_+)-!J2^E0W!D;*LB1JVo6OT>bBa$O=c2#v}t? zWP-?24}GELMGL!_OdJsxrLL!px>9L7ShahVnzCBSepljWA?J^;@8(m|$^!4QSpI;t z#m$V$HbFyY>V|=r&HrKS5Z?f zjjjA8fzcJSrA57@uEC4!3hY}gsOCd~j@ME)9Uy3`jrnHT?-v3N!ADD^aU{hE2je&* zL;8qoc6O|rEzyXksBP`zSdmWgMAyN&zn!H;$@#-;bWa^Q~$K~%^G+qTmigokUN z7tvhNC=zX}l`w+<{`MJ099AeFme;r3rj6xnLzWUL_e9aO#ViD?7QuZjM z50zd( zJTOU`RuWjdwxzA@m6ykl*9`$3N@!t8w>be^%bfc6s_jpe7C%3!n7Oy=o#^{qz1Suq z;*k%Vh$mSRu}D?mXbDi`m2X_>gy1B7!`_DrV_a19Zdy5PKwQv$0}yv=-^!frYhhxd z3*R0PI{x^VgZoUh=E&0`>EMVA&PT>Cae$MuY-#>DIlu@~{QSj>-l>K5ZNL)IvH`9k z76-86q`nD0b&4>wORd_=T!2t(yi^zrcJARz(BOPzD+kTfrRl1q(ro4AHv_(ji|S{6 z{azVeo{re z@}RQ7m)oAfuh4%14pkOdP2z5laL|Jvz~UFHuFx~q>Q(x^H&&z`AYV`%8@uYV>KGMu zjuGXrSWOwpHA7W}EUESQ;&y3b@#vi>h55bdGBa3GJasFPP zF@v}b+)Tja#8p*!!E2(Q@J?hHUkK6iA0pzUOY)9J;O_{o57do-B}gkY0`P^606-5e zIQ|n(nZ-CF!CXwRzQ zXB_r>xLy5YTZ_m&8|I=mX5?_qaxHJFc<>H))rJksxQ$Wm@22~(@LlK0*LPZNP?C;? zj-4VGIf_PPxxYJi4i5{cr-FjQ%Lw-32rMYCQUL<@6Q-UxZ;^3j3}wq<{ndk4XoS-^ zWFU+i?O`jW?;oZ5?ha3e!F@zUAn* zmmt|DuuH!q7Nz_6!sJ04Z>eLQ`7}xGrxDNJg9d>Tfocu_I@}e-+n-lfiX1p_fOGi3 zLWf0LNzbVXtR=J=MvwA$Ml(WQcqQ3gn`$Su_DAZsN|qs+`@!o#J$D>kdh)94yO#ye zHu4JyRD-%CCM8w-um72J5!lGiaIL6_4gDAX98%?jr4pt$Qr}51Tq@T{nM=8koO<1& zwjDoQqdDKE@@+sBYjfLd{R2y(ou)T933Lx0AqJi4pm*W48FkFW=Vjj^@NFWnQbif%NgFx)7t4;H=REuRE+4!D`tT*Te)6;hU z0JF)b$*n&voxGk?M79n=3Sr}>n$m5u>!CwY&V#61o+WqhG9&I{^=PWPI|V-tHPuU$ zJ<>s1tuuo2cS0Rn!9cJBBuc%g9h7^!>~Tc5_6fBk2pBt4<>a*fR>t@V-vRS5i;22NwP_V7+GL=(l5w20>Zrci&1)uJ zP-dU$aG&JQBMsygU&Z(;bbc4}2PN%1^iJ-om}qQ4rGnIeUPLBVA@{L8w|emWG5SD& zSkQiKH`0x*iGL+RM@x$=Jnd@;;3w6?@v-tbQ{Q_bANlVDXrx_EUUHor%Q?qeKk+$3 zFb@FTkt6r6Yll8M*&|elgYJZ3z5SN#H4Jo7s2^%TyBdEJSt)tvt^}?DX%^CPez!*0 zdt)scM|k>A(k{K~kIK-ycjD=yglx9Inqc99U7LcrWvg$FiQAY7Q^qT!_9i7JCB5oi zde;r{XmT;bN7W6N4qseM7@lr?WJBO?B)$LrJGLTBSpLk}#_lHyRP63)ztM#TBBye^ z<8Tr1{0DsJW!qm_6=urz39Vz}#jZzr$chBylcuc4vw0d{zjkqo%Q93`)Jjv5);tY? zNY4hx1*QsA*hrp8-6@?GKpTDHeCjcM@m*O^l`v|adiKZ{+^3mT>vgZ~_&4uAeX5(i zoRxa3x*6+&Jk1Whn4QbQx1zd^K2f5J9CKT9;qRWi@MEq`?M#Ue<}fV634mpYswCay z(QX~(D{PldyIt}{s@xauq6J; zgz>vrRc&7r?ffIDCNnTWG12A_91Z)L&yAwe3+5~^$Pv)x2>|W$o2SHj?6(;|p3gGTb<;p}*CD2>p%D z6`#+$1+Olj+z8eaMsS7dEeV6#fJ@PMXym5le;ZuS%>>L`42ia2q(SK)tSJoC)?F1@ z>tLQ{($lT06>7BTaL9rXJ2kciexl}iT!0hZ|Pd@i!cOeRp}I@Peq1M+UOLLSSKLVCyJLr&yJ8~om=n}{5ESmFW9=Wx zzEiz|O&)#kxxk9|kR6ibR)e?FN0k5xD#@LKhLiAqAO`%4!Dhr+nm=V3%=5TsRWRN; z7Pi;wnp(z8zFq~inu?-4vL6O>fd54Q8&!goe39MvjyX9|a2*?9;CZ|M{M#8F!+SRQ zV9iisU%1l5NP!>=VbLIm1fM)~)M`xA(SaQwk_Ql=P-?_MQ^FDTMyhYHUon?J>L!hW^AG$H3f+A74=rJtL-g&__TMOPn?3T|b&%u$+^S@IoDzr!^M6gz( zjfA`cL?QVA1breta#Vufktb6qla$oqzCqxo%|?NzY01e71u7TY_M)y52X%;-oPYCL zVEyUmfpGDpq^4F=Ja3ORBDNF(U0Tc2tq-_4GDoPG4m~8iaCC>%!@oe77Zw%((uz;Z zNx3|t$DNGhb3969i2|uSVS9<9WXGjViW{jvq+M?4cw@K8;VY?ML5dNX8`)P7Pkt_4 zC-P;Jj$R-tw)|_s+Y~-|sQ{@149O(C43dsaoGR!FNWX=*wtIhBAV+9us5d_o&+1*h z9Lx8tWjT;(1cM$7&4epC`ea9i`6eeNp*+!$Hy9knNrvN~vw;w=qb2a3 z!9WMGJw~ZtP-1wL11{kH{%2%3)sJfhSFZAzfACcPU*aXYID^&I+~udHjf>jIKpDCy z=a18TY{G}?sTI%HF73SDnLg+0D{4Bk_od@c0Rk`V%v6QABA=Xh_xD%9CrJ!!cnvo# zs@R_AYwG9OptOe06{V{&x@(m4Ylq*hgjKw><*sImP`H&i*={{^xa5nay*(4fjH?^d zqXv8xpC>yolsh!j(N4S$owUi$@NQwIr9PXKWDME!ZvL!z?#!&Xr+RD?7UZpN|=Xg>(A{rxfg=I+CuiNI_yLaQ?`6m~NSKflY0{Dy8;;0fx z)Z*p0Nh~*&-vUS)f6={sKF(}HF6zP8?jmr<*jiXZ)DgRQs284zTg%+BD&U{e>15n} z{ORPz>RPY&x|J?xU1?>FIUT3P$@}wFZX%rGXHo0pxgAdb?FFpVR)P&*+x&U5rg| zUO$IkDdY%k>Bc4_ii8;@+Kz@HWFPBF?4{O$N{6nSs$85+u3Kq1-B7bZv6@c%;BB4E z@jTzxN?Tp^9Ylww7Lvh1!&ZV`kx}X7i$$nML?M83;}&4D951+s@GTS(3K6f3!_tJ2 zA!cZAZ{Kj+s=a@fDp8^7^=k}zNmros34OK>NJT-yZSaaq?aJHIi4V>B3q{2tg5g3- zgV7fwDGb#=ZnsV@E&~H}qUQ}YYv-=?+<$#9j0HGNZYqVpU`=D?!PFwC4kRQbw%d2r zQ|C;pEH5vU{t{tKUrv4)#AysqFwu9xf%N&jloiW`@aFl!i&w5N#nvePc>bErHK&;# z4q5z=$GjzLoEW$$y6qYP_Wgm_?vS?vGT(6Avij!vPokp81S5mpAXRFVsBRQ~zVzpP zRXMmSyrhz(q|YaDui9-WvMQ*Be+>{$I!9mX`dZ|-XW9|I=co(GBu@eFne!j;oZBgoh;uY z1j3i&7y&T>X2kLAaj2|?Y4-pnl41|8ADcbHAtq2ehA~3ayF;wQQiuoFJ?yx`91BdD z-+I~aTs?`q0G1%cYa^GZ(zRHsLN;5rH||{1n>TBB$%}f#%sXo+_uP5%gbx8MhLGNI z{m7Nsf?gbeAij_H`^yg|?8NOiK&A^|PU?tehX%V=-QY~{m%`IXQ!ZBFiOEA#&93^Z z)$63Z(%i*0|J9osC@HzF4c*lU19UDYHLO1ip&ccg^58;Hp zvFXy`T4$|}=c)bv2+@E}AR6Fc{Tb+xh=^7ExeD*k;MVsN0(E6*nFuErTpm^(k;+ed zpP4*T(9l6S*ZY1jA?YUAIE%bD)#7@IIwJBr3sg!uAbR)HE%3=wwh`3~K?2n-Qr$Xs&oF?wpVXU{q@ zvC};F8R?uubY2E{6}Z@~-4IVcBYkEC>SBRep*j zPoO&`vPMW{`{&+WQW09s{{BUtRROuQU;~74o3Y_agHkWEG4907*NrQisG7(rC?}U7 zb`ckpI1;U3GJ0(g`r{OL<1H6#1w#2C^WQFD+V2S9JrV*_fzZ8wkay^gwNFt;pV^wKq-QT!(x1rezZ3-zikA)2R+y)!0u?wYubsT(q6k{HV;aqJP)~u}0&9SGW`S_{+Ng7;$p6p*&0F zZ7Y@?1vK%3K1MGRN^CL;4PA-8i3uak+9~JNj119NZmkQ?CMlp8D23j)UE@L{wd6A` z;uS@-!vxI5#dAm7l58XYPYdvP?mSr-jIMslTc2U+KoY%6SF=hcnQ0r)QS8?W_zqDQ z7yq68a`xc>J(1`miRM3fMtg2^QE}Ocm^RC6de70@5(H#?aT#3)6@@Ng$nJgRAc*As z3EQ>4d~i}A0slly3h|1B<01fr2U=Z9R>ILMRpnW207JflNw|hZ-H{`2>G=r+dC}yJ#h&sdNY-fkEfW@-F8h7cF z^81s|d8nOmpO97^ivy&pfpiLaQt!h0Yu{90e6K6M4pEAiITS&dL~BbrD(z+E{6P~o z-MgR8)Ctf>>4I(q%%Xqy6LJ!{@PoPTt1!|FBR&3PT;4)NlkVx54R@H;$$_}!^? ztS45>yf5XFeIJNy=FKA?_WcS0y%z30J)Y?D8Mw2i9PBfR5+eE@!u=W9#gL`5^nFK;+ zI35))j-NhUJ|xNxcIBpQHlD5+0Zq*dbDKnh-bL}3+OLL6Hz9!qaYXR;VJ07y{XLt_ z^3KXWFK_ipU9kB+!+!Sa#NsmP!0{}}!zMXe#VnKenW{E1WO|W%>oR=~{D2TZg#iLr za@YMRp3o!;xQ!hDCtQ9C3#Ah12eBw{r;zKRs!A8jj`5_hsdS|F_1m9Me~`KU0^`eG zMUc#q9nZ#7Cfy=O+-8NtJ0~ydI=p!~I0fDUON8KeAeT^29IU$tO&&zUdWT;-cDu11 zUnqgx0&hnx;I|-JV_<(^RN5PkC`uc)Kl;Ov;=<1R`nJyzTnuFR3=D9{RH>(&_AD3p zvIVEg#9hZ_CeRV`==QUGzAaS^Pc4v9Vtp|6fJ_nKSeG;)yM3p^e|;sxWqxU#FZb_n z`bXLyJ7x@)t$C37S&|Xgkt?#FqyGZ3YoCGg3^6xO6W{9!Z(ML+Zz)X``pdITYRsR3 zXJD$0oP7TY@|+J9ns|XU%$o^9R~=)76#)N z@2O7fs>r^UC0R{zOpA0Do_}mnq3%*>&e1i``vJY5oZUlOByD!?Q}b(J$PB0G zUgwWa{5dqQ_y{7oSMVfCdL3uxkr?N=20bP)OZ4RN@)hLQ%!g9sb{ufWh{+##_-fCNVMJi@$Jv=z^eBaw0s2;%*R57n%`TX!hz`W!={quSt-f3_nDHNT5XUUUmWmmu54-$P?#vCV@- z-f}?-7C)SCKvlp;faAq(&HpnzNA>dkd-fOp)N~<7sth6`mqr5b(Nkb!rz3hJ610mJ z3oJX5;E28yvK3t4{MUMQUwfX^Tw*xpV)AEk@%YgDb-2xNrNm#_h1MA*WxaA3tsh+P zf1$p5$SdDv*W~eDRQ~7%;}pyn*F$3hm48+3{o#?b#zV8F07WV#TEQ1kIg9{8MS z)E8}VF|dAJ+9q0|{*bWj3I_ArQzbW<9uSWz&aBNR5b-3%3T^Lf!lp zg_pAZE&m$Rde-fzb0E=N2ZkJm6vi*AsyP|d3+0nR<4|2cyzNuL9lvWYwa|MU3s@FL zzzRq#{I{|o%nQwI^tJF~i(Z6en&Wo1ZWAxwF)n?ni`>Bd(KnzVfT^i^*v~XO*8U!p z1JD*KX9s>~L_k0#=0D=|3fp=C-_C2;-{2$o`yQU*mLd?Hm|r4PT|$;!K$RKIuR z!gYnl@y~5-hX?(%6Y+Z^d>m-f&^(fS0*r=jK@u}cN)Fem;fVaGbT6gqph`A z!<_MRM6!%dN<3nh%yI1PRRGUDvV+bnn*sB}w{*n~2^gcUr>Ez-uGBB%pUPf%=qik~ z27#JP&xNUkfzgY4zZM#VNeDX^umo*>OT!N(If+>Px>L{*;C?3E_NM{n;jM6;z-j`b zj*t?VWKZmKpQRf4ni4;ch2Og7y!qZm*GQg<*3*B57-+A3@*<0oDA6$pVQ6@`s;5WP zm8X6)(mYYMqVNXBY+}n~WkgFZ2rSo!%`G#DbKd=Jr_k-tLhp%j^f(#C-SrrDNjhJc zT-2l2Z8s29&^|W{ZX^(aQ7|?BUDYC&2V%wD)1-el{;)i2x+Q^pO&goPdZibSM&e@;EBzc4NR6iVk3S%#nco zP%^?ig2wrwro12S{jH~7s*eB_B;N=&e&=UxF`O!Z*U-`tQzRn!QX9N;4L!JZxqPmN z;}4+dUI*o$rluw-^+*Gzc&E!rK_NwAThF|W_QI4Pv&6VlM7Da-py)B@v?7ihvMT_!Y9y^c@=N9;{Mggd}R4sP^^digo$tr$;h{(V=gPDgM;vxEmhfhoh4-0z+ zvUPgkCeIF;G{NnEJpV(`FO8>OK|zl!VkK8-tw+XLW3cXyRFIv8&JsyMX(` z*g|#`y|nOy0#b%H1i-?>>TOnr*L#g<`89--Xw$~O>n>g4=rm8M=pMTyI1TL?u1j=b z2EY>0)wOhXCc-~?QLHysBgSiA*3b)T3IMvN(5Um*aC$WX`aA>|g3 zbzJv~MJFUn?Gte-z?6opY8XvTu*L|&p!LdvBMAeSz!Vl^XgTJ(zEh776=|rAH&jtp zR!G-%&Zm*95OxJ8+5Ye#^QQezDPS4FMiKutpS%Mtg#^W77(0HX*rmc2&-QDQ*rx!V zhWUHvBns4@cOFGuC)KQ>tW1ka6EZq`<`t3g0S+UAswF&1PjcgyF`Qn~4a%$Yh1?&vmZp8+5oR8$oCB9~XVIhjoDCQ5IF|VQw>(%l&(dsd^yv zH}>~e#qovNr_s6mZ~g-~@$Kx^jsId<`QBZH0Kn1C7kp?1(eLBkfPYOjNv4)yxR7~y zXx-@JJg?Wys>;fuDk|x_#-~;ZjyGi+L}rK1+SQ*Q*AI+NT#+j{c?>fI$@;XFTn^mx zXF8U3vy0!*)FZwDF6H3|`B!2xERRX_5Z(wp42DATC)Ot$rnxF|(7GWm+0wy*^`6a} z`t99KD$s2}(}-e)%#gtBB9Bg%vgA|>{l8r)$wJK|2eTDA_zQ_c>Bi?z2(jQw!^$M{ zLdh+3dVATm#0L{|t9e+Yq@`VFettsMpAke8M)_+_RFs(P3fv15Ef=9+{cF&7#-hes{Rko{Z~StLhyA1fBDNS=~i&5r9keuw-4` zq-Z$jA0I%;f=UGlGl9gAaFWfwb{)BBs-?UQEHF)sOtJa;cr_&Hsl`uE+?bE6H1|4W zW@=j9bX6UslkHdJEgxH1NM#cH#Gx_%k_OfX!i3n|y}DaPXzBV6&Xbsy1n~ly1!uRm z*NtueGr!Ht-I&hqUP3a*(HmSSi?UYG;Lx#%s0ZZKH*pPECqWfZiAxNh`MNCr@AF8E zM#6Tem#YH^i!1^ucYX8qfW3dFDh*IG_#3*(Ea!Hs+tF!}?^T}_f_R-pXL-W^prulgFMYh(kEQwWeu z3^1pH#|3U#Lm4QVQ4l#JUfxVRvhsf1Uk4XooP%0R6!J5bf=pC`MQhzJ2E#{;N-moaG81|$cBJh9xss^I?iXpDMi&h&Yl6ToJ` zos%>R9Ga>3&&OR?9U2VM5We_#fs9T?bPcXN)OOCEo(yQBmNj4#0bqvJhqPjnMu#T| zH6)8dgW=t1(|qi-XvNrks{(?q(+dYuv=c#@?nS_S5G6+R_q!6(fJ2Zx*RdpkK%u3o*01mn|yp#dx+K7~|Y!1x+@3=Gh`vPmQ9E<0Nf9RkY>I zstYEo=%}ft=jQqloek#^1A!9BJPfc9C45Thbf?V|(G_lkrsDH2m2J`g=J6U}5yDMxU6ZS;}0 z*yzZ;6}V~1MLA#gUf-U{HeJ?ActA+}h(pn(M_x>s4s@};y<|!da75dQeQLk>78GQ> zf?x_gNI7wHj``CnKoD{Vo^yj?Og-E$ZEZetO1~1Wcnqp4S)YkYlBmX!Yxz$p1%-La zZToW<8=f7^qXP@5Zh1}yBssJOPyoHQf2bkcTL(|16`oK~;bT%>aeF zvOpq*zT|<&*}4K4JILXxz|S8ee3YJH=PgJ;0Z%2Y%J_BI)WYHw>}F_ij47GJAvqA! zxNd-U7Zwg6)`}>_5g|wlKE#+`EIcVAWkRm3AH|JSsP=V1(68m@Vl_|8+8Rl7&n6xP z6PdM#+ zf{K&|R-K-_PwT=C;S$W_XvY~)=i92GN+wxR1na;|GbyI!v!e(o*BvMF6^) zS&TM=JD2Eq`A>|AAn}smCBD?^Ix7uD{O#b;8R?r_gcvQJTy%Kt#M1PMF}7Uaj0D1f zmBizbpx#$==$Z~b>xl{osz_S` z&`(b9Ms?kna~~FLj1!Hb!2C6qHv7B1W#&5Q?hZ^n{nu218{78386ASqU+Mj2&889% z7On@DLFOCca4Igkl_UA@_t(y!Rlw9CxN=7$vUg6bt2ECq@vj<8liI$7Y<}T7cXV4hOYd;t&#Qz&NL9jP|z^| z%(P;5c1gREH-rB3B>{t>i(z471N!&ytl!OoLmkGl=}eeEx7v#-HdH@02u3Eryhppr z;!p_XGzaW!j@xT<-6Rvw2aN-~3We>-9*p%ggE;Z+@9`pcgusU+au#N|FnY&JqU2>v zsR>-y#vkJc?>wKm+T-=0nTo(_kVX@wMWL%<`;0iPK%W6L0z+lxNa_#OWu;ElH)C8V zE3o`*o^YDGm_yzP_m8-dj>YUCd#2H8OB_xB(}5o)yi18U-WeTt?U5eZ7&0;q{0Mno zsU8}iPrhk8@PLhUl2JzT_fh0P2fsE-eeENKmMr`Pkncqme`Fz7lF&aG9Wy2jS4%bV zj*%2J8UUwFo~CEJn`>%nNN_QDs~XvjhHZpr%gxRG+SN^4eS4|_jUX;Fd>Gg}B9|Mf z{ks13Qu3tSCPPl29PM=JIb1lBPQQk_hZ(Kl`G*YC0nkK&iFCgalU$^=7oK&L3CNqK zAl(dx@9F*+d>AX)bPV&Ufld+5{wk&}_szkBb4ojXrWco;w;boB{6Ctm10L(O{Xa$s zS=renqKp(WvXc~1k&>)PBBjjiO-ZsUJ86$P_nux#FXF#S{G>LE1ke$0AwGAKBDz$rOhqesNxzS}i5DcV_qJ1~!( zK=@Uo+t7phtPLfY3wpYSBi?weneZFI$65Z)di&Jjfc-4ZkFDYJ6rMmo+TKB)JXH zH2_yJIPlQ!96J{D(Hz8054r^6)obVvMtU9a3zXa>A=mSuGhLi_CC=b&^a5(aX=v!Q z^WX20(PB8a1{(?Mi+H0U?PW}Cln6WYJ*ts@0ktI1sy;m4282BZcXb_27Q5zL-MRlE zA7)2`H@^ROeP>3BQJ$URoBj(LMa-UAh!a>0{PRLh{k7uBl?=_qG>5jeZR>V1NK0fJ z?bO$z<-9M|{&7=g=I@;^uKd3i;JNS8{qBOpom@4TQ!dj&BQ{rlzK;6ekR#IK7E%55gL>o<&e~3G4{y6gAWGt!rqY z$1!aA!e133ozb`uUXct!28uSD$-Z&VR0Pz;W@U*$kjGNWF%+8vuokwKB3ue#5fO^v zTfb;g`viJUG$&k*T@ucmJ-6ZRiDjXeb_$?X@E2)V2nv9kjOFnQj%WwN6MoW7n#fD# z-nikQz89PCxSq)#_GG3puX`U~e=+*Iu)sUd{y?;aV^>64SEw2DFAaS@Z=-YAcBMyH zKwD!rhcWs?So?mKBJ|@=7qrG?P8eEPVho1hD+d?g@#3_Kl$nh2A3sRWC5{g=QKTH> z1klWf#K*_io?9(Oq1EnGj{$H?MBmW=uri5=x*Tyg{2^sk1qy zwxxv?trG8!0Cgk)!(K#1f$EA(zrtNlh!qGUK|v9JK5!1Ki-^7X_N!`XwVcC#)oE$i zs1ZFAahl^|Vb%Ec?%|~hZc2zq$dPa?dK?c5bvm}Ms(*c-?^qjKN7y^k8uauW!{6mz z9?_~P0&t;FAAw8Kx3J(rIe-ky(D8A%dgqc5>@$bWl06z#fB_UXB_vq}+^_1$?|`Y8oD`7?gkwR_mtA`uRo98x(k2?<&>_kdQ&+>;`Y zegha*!~nxW++e>cmdEAd&CIE+WD_pyA3kjv1LmH%00?-27bcG}$L)Jn+r(>E1&Kt7 z@R%MuQz`(;X!7@O%oX~U#mV^G#RJ(Uh>l3r@Y^;cGJGMzO10$m==-h6Qax^p9*K1K z{|OI?vkFKDS;e@41!7*(y_Y#3Ah?WKvGD*k3F8TL8`})W07>qJURg&+N8W4vi19V0 z#_IP1EaD?~FJ9{Ud+WMe4HP_+J62|P$m%Pm3a(ka0K)`<*Wuswc`?2p$%9EjK@{jj zkTpPA5!&onWQi&kQa;}JptE;lg-`6M%y)9#cAZ^7AP(pRactvBh;S7QM6&Jw8mH%!(jNPJZX_>04r_Y8p(`V2VWOxKRKl$@NE#auKDGDhu z?N+ndmktT4Q|1M3yj>R2rd|qtb3~i#w&L5`|B0;Pbt74NVf%t4PzSpT&*MnDQCtxG z4tY8lU(XCM0OtHvlbOvFO+BNSYw;4yzb}|7h;v1>&hF;{5=p`&NT$R8sGQR+8nf5{ z-g;+{hjY_Rx*qp;q>wK|{@!#9EfVaP5|Q(fS2v5+3xTW)7lK-likH%Mw4yFguKB#h z;a()xrt0x$a-Q43N=;1B2!dIBf!_Z9P#n;NH0%ys(IBTSOtUeZ^S5bjEaY$aMl@g4 z6VrwlhKwKs*liCL9!u*>CjER`b{w$cK|k`$q#@6^Wt`SlNEtWMP@5h%6eTH@9u0ye zSU!s{el$0AUM4HTLPE2fX;7iYoosR@k`;CuA~&TcWh(F__>azsmYv= zt)osej>yOmx}kZ2|KFf)NO?A7`f~&X1k`3k<`3;XCkW+59U1UO26&<6STej&aD2_` zmr#_JehZSc@Jk3v+`rM0od&~JOm%g#t`=?)xoeMN16LFHwLa`99W5;iTy|5)ggAy* z48bKz?6My3@4e1y6>M3#vl3O-R#q`^UD;wBAO-~<+q&g39Z&4?zX~H_WHP4C4!-s{ zK{al${^%SRxww)_UE(Fii7A%kI)QlSXIGRkQ&c)JiG%rH@&l|c*rDIQF>f91Hr3EI zD}Y!BI&YGvAb-4x7tmhJfj_Lzw6k(lv5FD?McU0zFD{hPteHtF*s`($LLag6vr$L3 z*(lw`4p&S|Wgi+eGk9505V}kEog*@P@^J*lihmBmQ1vIA%5xfNN05e^MLA z4a;l(ne17TvyP(F&E3%3T?Nf}b#?Xq_MqF@>E;q2>J)LL5S=bk6|~?jfy$xC_qPl2 zDHEIn?@G{xr}G@^`>w1dBq>e8fV&E@xXc0!|4P25s>?cu5KmWLQBgRYH63oxX^_DnW>DFsWaM*U0 z`;eeJYHI3F-IE9AQ%0k|j-3Z+4sJt4N$JCbHR7wsYEfL0F_Bge+Jm_gau{fxLqkI3 z9ba?aKT^s8?K5r&LK0;7jjJvq^270G{-S12{)y-P8F`~Ot*(J{wFd%nzdqu}Ddz`a zMHAFoY%kZSn^NE`i6|^|ue1sY_H}Z2jH(@~I%?hycgYKU!3|xx+Xm6?k(G3F)MPA@GV;fsyMy5D^^k!>5X-YqeL8+$Pfr#6_+r%v8lo<$e> zq7$lQ=&pq{ayY1jPfr1>G%z(~!x<~cQd}HaKO;10O+m>9ReK5Y_%Y$5-Z%43kekF+ z6>A>pYw(iVf%+s_F?bQx$0m9E14UQCIE0UbFUY{i$ltovYx!CM)PjSA&U@1DrVcQkDwp`i+xa{a9Fty)Vop$^PVG{SLJapENi)i;fz+wUYvL%TClsBCO)>id0U}Hd(;tR#0Vs_ch|1a7*n-14B@rK>E_D34qbLOuiRWHF2S#IMr#Z^20er~b+(XTV> zr4X+AspC5%+hoTcX^t0v!|2zdNXK|~686cEWHiXVZ{4kTD(>-d3nY6EOX%PO&38Gi z4txP23Oh#f~6XfAK;B!UR8AV{=~IjAGbZ#Ak~EH-Sc+= zS^VKpKoT1O630n2WGI)+L6X~mD4AnDA#JR>3L5*PL>SJz-N`;&Tv@q8a?iD}#0@5o z+EtzMzBl>x3=NSmi*YEB$I&BmmdqVOGS^PW-iO#;>|N7##3tJnEgIiI$llaPbc4DA-B*!7_Y6Z zuc}+YY#+P3B4y0d|$zMFi71Kc9Nxe=csa9+aj_Vw8j;}E=F%G|P+K>)K+ zVryrcs!Z;RGkAR*ZGxg$4Aq>MOb?(cqLPQ`u*Fs@VJ29z>7a%7(yNZev*4{L;;J$;faPj2Vns_7AI+l?h8UPoPJoC z^o+gt6ms@QZN>CK5GGfDSDObU6{NRxz^6baU7=pWw4%6LhLc`fVw$(E1ryrP67Xls z;<#7kS=AHod^GCp6mUExBqa?_IbDor#$AZ2zZYu>6O0C<&Pz`=hZsueoIWj2$--0D z5OzwJ@6<}<)kP!#5rczPq9t%68I`19UtcoN&U@g&<@4IKd$~i;>-oQaPplrG_O*M4|G@HaKXIZcB{})a z3J%QAUSnSzsqnIUJ=npX;`12-iCO^&QmPWgxPkw%WV-Px# zKkb>N?9Yi|&H0IMj+rRrBmb&iSa^H^F8}jImaaUp7(-eNS?*sPqdVW0<~kj;uyCsE zzoholDDP2s7w->NiwXT5Fk1dWz)jh~dldsK%pFhK{P5e$_HTT0Z~sQ}AE1%G2;;=^ zgEqJ#Kfj^3-1`~>JAgaIw^~wa063Jpyu~jGX?!XC9anzj+LM1bD`q|YbQeOBn~ z9w8r;@3=uRY_*ZG>&DrfUlspUZXtz*a?sIwK-mjq^U>+=gJDPKx31TuLtg}TUlfKK z9Jx!p(>G#^=4_4C6LZS0XtC#tbQf?#ze08?@#yZ^b5ZwNc&3|SA|Y1BA04cH-^{Ne z4%Y($&q&-MswtKk?T9TE!|Hdf!7Jf{!qa0(=M?|^ySAk_ONlzq8Mp5gfGg5v1GI7!$G@P0RPzc|cVlFvb z#4GG_la+D8jGdd6Z8Mi-J`1baehd5ih90f7dJhhME!4Sg(WD;LJ2B{TT!4A#Y}Tj* z|M%-|&sRehV^>?_oJ_xCZdY#Wv4vkFlh_M$mlfOxK*mO*S5Nj3EHQe(oKGcL5Q>!x zF>+2t#kcH9_nSeXB7(Do4@YrHnr*Fw=Ey!VLX++N%U*Bxkr|=pB|rBOKNo-Io4OQ&G88t6oYi@hXT!!Bp@U-&eoRP z=#aX_iDkTWNC@zbf!CX7oEIfoQ+z9Td62AXG{GdikH*-7qhP?CZh-x(>$b;FpY|aG zkc9fuoV+G6u$qvV34(h5A=An5gQY4FZ{A9cslR_B)xm9PSv zf(w!Ubx*I-Dk;ud`fI+Ah4~>8)FfaKf(_yTL5zfe0Rj)aM#}>k9^(^Vco0bC9u^)>HK+XT2NFWUVe{ECVXwqAQLT)O z7yzU-=xD2*Z%0zcMd^v*M)JobTGGtFgF2}6Nb|;(ohP3M=P1DDPjWc{@9`#fK@$hq z<$b(iZRGQ?R`u9)PDiK_17^#*Ns^5g;Gmgu zy1!lX)K5_r5Lj<6b7fu_{*9tPm8~URkK>_xmEc(IR=IS(DMMo&N=(dZBzxqa2dAGa z-?MX7P$D_{1O)|Q?x}6o{9&9Tgn)7)(gO%gl4o)gM0JCp&yRH{xr`xXIeigG&jgNju+kp}YAhLQlsEl}pY{dQ zD;!ib}eh)>=d?8g;kKpX31D1hFhGr>1l@9uhr^g{{_+(Mf0c_ce5Lc12`^ ze&j%%!iPZx(zzQq^o;EqG7>T3czH@sETJc2otqYVs{&*W?8`jZQ=wsYA145M27N#a z17}plANR&K)BV+$|ICU<$RZup%3mt>&Ji?cQc^fVX8WFgb+fPPb-DOG$}eDr=jjf> zf|!uOm;WlfebD7jne~M|l-TE&FcL5xZ5)u+kUT8|bJ6=-7?8VJhg%m%HM4PsdfL<} zZ;oM3Gz%pc6K=8%Tv@-Hjf10)eUnLOZ|fBv$7f%Osf~=11kt2BerW0x3V#mZ4h?7= z1Yd<4++%AALr6Z-M@ZTluJl{w8iE4*^fp4RfnT*`sV3*pLr>#B<@d(rNeu`ZG*95z z{%1jI%GsYgB3rhRP7`TWFBYeF1MXCzDF34s95?dZrA;=U;zyiIXO9;{{MXUt7jf$G)Dwxu`_K{xjBr7OH`;B+YPB( zWO8zHKzL^EiTEi!Q_pySuwcjt(r$J5u*PP^4TPfnaT@l|gKLa;41MO>X-`|N>VD7c zj{K=FN(Au2Vz$4--F4bV_K5oBt>QFdNk&99*BQ97H2LSxaie9OvtkB`leuBhG&O5w z-dc~ze4$ZSy`m=;Y%Ey|In@*)D=~ht9-J5(8{0c~IhMzpTIOffNA^RALEZ)klI-&G z&T1;&u~u!Ts)t}n5RmBIS;_%4#BDubNup1OVRVPd@yGnKFSvtrmZ1ev?mSJijM1ck zqV9HwsdUZRxE)RF(#5{OSe;tZbzmVyidy9s#a1VodPcOZSu~Y3*=BrIr!RIha4Cc@ z+w>$KcGHGb00k0Zv>_uBS643=-cX&_e0_#Z?#DH7iK$8_I7k}>)iVq7(^&kjF!Jmy zn;dQX_%R#+&O=q+3^5&^P<&GKeq=%*o;^U%L*7?2BUG+wuyoDLPEA!~8aK2fQwyVo zfP-LO4lWYBBAWZ!xoak0GqA`K)3{%X(Qz)I@FrEp6efd;V(f)aYjc*X5);*W3Xvj0 z#np@3TR}H;^V9hMlGAsmAY_5KaZARYew{?@aUV`6@Ujtx65Rb-{r|58&;cX@sU)W0 z@y^m|tT1sgs#%Q9B-}$sdIZUsm{H(Zta)SSB^#!i!f3oVlx0(|#N)NHP31+#$DNGP zQuZBmUPpnM^&x=(5Rnw$Z#8**-so(ATNR-g(6n+r>pa7RRVR}2=FnIE!4{v16yL5p zJ(uFraTr2(g8?dtv$Y`!{t)&*rLq3`gu*iSbZ^-=7BuYVM%%MVY^$@k5L=l1F+N`M~(~HNZ+Brv<%6v?{!qFD0)(-e~*# z&9{^O&WmtLYwh06L@@IDD8DaVeG}2lD_5n>G4V*SiYm`k>VlSZIS@C5%tIK!3=SO( zDyp}ouF$zP!{x6B&wv#ncQV1Ok&TQW%Itc6@Z5DQBKQbUV8SOoddWA0r$OV~;K3)#abTX8u*rFBY0mQCYnVbhJEYT>`61mQ#=V_ZoXY^($#z|aDr z-Pd_=u-K4VxP72w-0IkU&uv*%l^X=xKYZvx6Q&D_5LA@L#*iNW2mXfF& zYzm>)^wqi{2_-(@jM>x^*#vXnl$3!K2>=_*3muhWh%~{adz{`)iP@V^R#Z-2MI|+l zZ;o2(h4n@Cx|4!oSFphRVH8B!8wOMWuk2m}9;J}Sjsg@1$lC!H*hly+QqgLOuW`-c z=YCOPE}2-3k&WQNiQ5Zaq=n!!3)jp7$QbTD%HP6>eHD%7acLPunF#FNVCwQOjH6$^ zxAogec3M!;U!^rRrlL6~*yy#bC)qeT!!T}H!Q{Kut0Y#v+vdUUqWx4<;lYJT3n9VY zUk6&pAkHCDM^JZqV(cX6V|m)sUV=N81en+Y^no?vcvYkpwSLm=Dtt{|TU*;yHLuNt zR)mldj*6n9gy4__TKe(fq?uJkSL;_ZFiiC_= z5|K@L?bp(AjotI(m0_2=Hz+xJELFvb4IrKGf78BRm6yR&lAJO1;Wq?$kX$wJ*!TxS zLd|^uZ5$wS9SrG&ObfMmFq~IWb#?%Tal;D0tx`4qtqcNZd|S&{u{<#piMUkAm^R{{ z#?_&-dv~m^Q?20|%l=HhU`H>p@|<=noX!xb#kX3JRXWBgaKW?-vT2gPPKFJ@Vu}Q$ z)hI_qJvAx0QbBum$`u3lCVdkG?z|6_A6THU#eIcD|Ar76gvgOOE-?7o&1Pbd9A>H! zxfP5>x>z9)k&uzgedwa#3>)6Lb@AA4f; zdB7;(a^h##ym)(; zWTL`QgqVQN^<0q<=64SdJveylhIgAV<5?hC{a%%S$u~%rJyi3ZyJY%UL3psd`sKc} zRSv)AE{{Hu8qkN%17fs3OithA;^LCp+f&>B(tGHR-L`*dAO=&DG*4pBAb<}fM(DL6 zLpTz+^qbrsxF2(SZWZfP1u?&XH6F#7q;YBxBnTu)JI~g6Y)dSmq2{GzWpW`#Yl?V{lgADM=nNapl=`(gz)SL*S_R?$w$stDO$!ol(l$TP-Jm2 z=H$Mp-J#{LfOz(=ELE-ynFb9p?*HMrJw8qZQw9m5Pe1}Nt>lj}zM+!fGxwo2$5d*P z42cKzL{bqyO-Na34Q&F&Mka@oNO`Cd&;|}a+MvPWxIa$w{V&75MQjJB4*jFg%k&=N zuvuJMI>avfen8ga8G=ebY@Io2vUPJt)!;v7xt;g9Sq~>8S8N?g2b>?kG=`9m5|cu7 zJBr*N>#^RrsJT>ttp|P)q%XL?%`3+r)6gscXF&ifBMs;g55TzzCSk+EG)l+S3secg%yWwo!>_Y6=m; z4i2Y#@-A8-0bmrqMS~9X2$O~|PF;53Xh=G~;C05+42-b^#Y*jfG z*kbF*BnhxH@kk~>A5LwQ*A~qF?!e}B7cQs*)h}JS)*NDxTPiE}!R;9Yfc-e~^iU8G z*N~Eu5<)8#w;!iAzxouh_bk6R)oMrR9Sd_Wi@S6Qb-)&)&A6fA#|;MlqPmyzqyc5; z<`jD@W~3pIA`DpD6tF!KYP5a(mrb+nPY!pl-xXEg{ie%IOgGkLoa z>28wug#`;}y_jo2tUBsjQp**$XvX4JB`ONEsE*lCNH` z@2&NdHaC=*Hc+1{C!GsqU`X#gJ|qX`3r!HV8#J7b=QhJoOmdKa`7T}N-aJjya63r> z<6pqFsrdeqBGF+0lX6=b0C1X#j+^=Qlz07Si6+8jOf-spg+iXpECJuW1z@vjC>o%G zIE`Q$O*wys9|wm_i{LE9afT$e<>lGRTqsY8lHvH$PLz14tPqP=SWRMW6b&)#gL^TW{m%Xv-23RPa1#+PDwGBo@DP@nnfdi*>AyNndK)Sr zG=>Mgy-Evp84H2?lj3HozkxK#Bs2@e`SI*Ou~X}r^ApNbJ-%1wgQFw89n9sHuogk| zy1*qo{dxgkVva;%;WQGVlN(&e1Qqnofw6A9&cBcaqa zFP)!nKTErSZ;KL)l!b^}Kk@z+x`2PkJZ3Lbyk8ogSYCufgism~4#d$^;~arU704x$ zVbST8EH8`-TABZoqORmi+?M}gRCCKg1xl4SYMD?ESI)n6CmA;Ce?Hk0l|{dCiIvGu zBaOb`7jhFC;1vN#V+Pb$+vK1vDmlYc`+7P44jgu`AhTMDwHcZ&eneWODUYi+d)@Bn zbGf?d0dYt|T^WvYzo?XkQ$w`YOPZ$d?(6d6;+bnbai_VGz%YZWs=MEjs{_tHqB~1@gEpGp(QqxRCukq|&xuB#An$Ot&tZZ_FVOkR)X(={Z58};&r&u5 z>mMr$FAF;B+GfG@lUN&&TN6V+L?7gP9ga=tj3;IAgRrXVBmrNimV|P4DB8gsP{CYZ zg?uWaaKO?_;v+KPG>o+1);&~sy6A7tFM4Y=KGo^X1fs-j5iVReP3DqyMiH0t*}exl zDW*L{6U)iP)k{RSz>7TI?@tvSc#AzOt?Ou=GIYsMH1Ij>PK9RfshZ?^R zy!v^C@2<=VuiT2ZFJFB31kqSI{ij{T0p^dx?@$oV^mNSGt65%ktKz_9Zt4v zS=ry1xcr$e3n@-swezyan^LJ@y~Fn=Q=8yE0uyepf772QzAP5`u(%P}`S_yIn?8EZ zi_darKO?&A0JO_t0I63)>;lAaEzpOM$*wpUrS%xq4e1kxabLJt?mmY~I@qfHDdfo?dy zi6jitd7_CWs0T7@A|b0liTkJPYUVA|4S8;Jt&Qcgs;PaI zexo)ceJA**;7}!dw4RVgtZf!0sjv*OD0BE=WH=Y`dES5ZabES^!n+JmOwi!h;jSdn ze^Phlo-QvQ9ST-WFN0U4^K|VRl2VU}eh5zqLjjF#qjuz3nZo*`j6?*}3xHn7+gs&7 zHbI0VS|qVifKh+MiD;g2IHAH1fnvJ;qyope)&GD1mbDkQ@n8H&S#ygctK5^79*h%^FwWRK0_xsu5RU@y(#DmC)G$liPap4xpWR96uGfLP-wmlETK)T{uX1kP^KQV#>!B8P!VW-l1aCl`*r&?C9YB)> z%U@M9E3B0oI7B1&(YEi-zU^o)@y$uMNg{WF9SD@4F_Ka3em0YaG8f)5C)z#!UX9_- z)guU(xQH{&4zuk@)E|`SA-FT~B_BF-1)rm?qh_}dpS%~$=gOjKHQe+qf*iL z9QNnt;zC?$9~SX>k!pgUcQ|kcN5#|WxSlPgi&U2IKZzt>E}U>=N}21I$Eyiu3%v*f zQcNyub{`#ntyYqXJ`Sm4wisw3B_jhWjUYE*Dxl&=FeeMLb5PXac%YZZgm6LT_KzD4 zUO2X?a%gp!A3n?kMvDZHVm_+@bP@jk{-meD2L;mxJ)8)#tOxoq(c8+9flWQ0tD+}e!?Ks+fO78_|Opf<>($PA2qN|71YO-O+GCS1fcG6r4 zh69(6_Si%Uuii5hVdk;Owt+g{{{kiaEi_|5Qi(kP-8fnE=ZahIZLYbmBP-vVk zK#|7I!4ZNzd@x^oWOqhOXanFr7zl85($lK%NEx^d9$J9bDMMPIgP5n2`G^| z)yPJS099K0ejj2m4V(?0G+(Alb@WkBBDG z#73kI;oo5>4MrV+n7#%o|LNLvz+3>Y6fP`y0uo0#M1~t8dJG32>?_AaJd|#o$94Zd zrvmVxKeC(YG*?>!MFqS>j_8+YFXi;uXiK++&z>h{rH>y6+oD+WJVe6V+uA~w{?6Lt zQ2nPMs9XskLOQUL_iww1%=W1dONxq86_!skl5?CmW=l&;QKZ`)vRAfP-M({b8)jkB05rj837V8Tos~Khrm?VHte5 zekf!|#)*BBiK5tZ*k9g=b5;mg^lrblYO!ob7Z*cMtXL!OfYMOgv3NL#{OXeFXD)`)@wLr#MLQEO=URp!2R2w9h9!}p;oeJfzZxwytDM*{(~Q5$CMX47pbV3A5-J0#0Z z$|aIL2w3jn>0TXz(&2Q5lQGyR?~L=jc-?Ng2z8kkZ}Avx!I}^*k3~Qw2vIe;h&RWD zVJ`uO*z=ZitrpjvnU(E{G^*>)n#G}txj*I#p&5h$$c;QNC3Kd~qWR;eUw;2lb+3-$ zKJ=I#*o8VS>Fpj|WGw8=M@3m3U4rR%y;MUW%ZRDc_mNdG{?*y|ASFXg;iV&iwJ&$>_JfzmcsWFh z3?zcl1~W_Ln93(760cv61!jS?W;Ep}oBOX&t`?kt@<80oPlT`{M!^YU<0B)s5B7{J z+1u zig1pk00-^Wk0$KCcfwVbLQ}aE%ButVs?v@}wK=lipd2j1gEzjuZ4F2;;MXi!K~i>d zzXW{NzwtUvaMa1(S`xbrsbs&rYC_OULk;&X%X8F0a1DIrw;w#HLo$&)2NO~xPq5MuuM zE{h)waQS`;OZqx-QP_xNnSbsw7mQ>SF}>@Gg-eXpu&?2a2C7Lga+JOZnpV5)%FZCE zm4<9GNMFezfInP(`_Af*^Vt*9W;qy+C(jFWjBg#g?2CY2AR4;3d7SL3J8`(9L_b^^o7X!?NJWHa}A0|{l1TCEeAlqA(x z!tkmu{NKjWn25(+FUegCtcAn^Ar1@mt<=ViI)E*3@8GS3A`A18v~NMd=L3Z*I|g2L zbnp<=A8!q!ch~`&7#kTlRd{%&ZJm7&7ThG_7c+q!0T|Z)vx+2qIJF3+#2m!8J|Zst zws%~hNBcUY4ku5J-sWS~hlAM z5IqQ)j=F;C#kx`JYq3#T6;iUskT96ul+N{>Bc10B19gRT$naT22LU~y06)>|s^)XQj zMTD|TPkaBuMVc3%_~Vs$B_wxKZ+^_(afY_~bLj8c*+>*%>0Vu{0|Ns|^gnpTpB8F0 z>#E_EfjZI_cQ;l5Y60S}KwXF7UE6QpbmmcOQBqBysIe=8>HOb7J2-B&&z>#T-QD+b znDq?F(}Jvs#3i&RncZ26d$d1hr|^Xjn=&c^mGbTDrJn*_Du4HIhTk{q!nA_K9GaWM zsL22EETjMj*GBdz?7ep1o6?A50MB3@OP!3Irk9Bz?aeGa6*y**n-dCWIiQQ&d-vYh zDsA&yLjeQQaSa_-$I75>z7C#9lA^CdkDi#{QMxt(5SHp3Y2$j<2_}s zE2!`ToMg+#G`>lzcuBSmP|HyhJq^f5!d;=bJx-J4{l^3uTQEWcJWWmr9>a)hkjxnR z65QyZ1Htyg^D_Iqv=DEMnh6HO5WHGCX78RBuPsMLGQ>F0?Kj&_4>S@IU9&a`L}Y_# z9ns?yoCvBamg2uyAE0a3dC1mmZ$`{&pZL#^C?ZA}9}`p68qkf96+ldEWTpb-O91s~ z%*DIswGx;D+-UfGroYb_#?FXHVNB|(AX)>dnL?IYB*$Gqb^t%EYpehAA^$dF%uTB1Fs?bKu8!m{!07`}20HL+{WtyX6T zK~db2zfkO~?i*V>7Ylqsp0^ zVfX?wsD*x;3;|xVZX4OHppk0@y*h(YM@MoinenUJUYzlp;Vdb*+7_;p@ypL8Q%pZOJoH}># zyt?!nzVk6b=&K`rc+m`yoxIoGh?()I2|ka>x2q@v>{RuJ6H zkqfk%)YUZMtpHiVo;dlo9TV}gQY$@jiRkU&@g$}haB(B@)mN3vakB%aaAl#r=p!6A zV^V0V#19h_X$Z+dLz)M0c}F%o>6S7`F(2sQ%(N;7yACjZwuMJ>2XIce*(0ln9zu@; zbs68c0=4N!HWzcw{2A~$tyh`&W)MHGk2)SU)Yuf806yY)8%#b-ZL@-Kn8bK@|py6kg$Z%7XVOCgBOk?l#y^%t0qT37R|XhjvQJKx6EAm=YZ>8ACgQgDj#&-ce8okduU;m*+F&IWoV7z zFR59Ul#*f~X86Y^-lJxV259v(z`uj0@F#lslcHPGj8**p$f7@oUibtwV!y7h^xR## zLceNpG(Oo*Q}cj5aG193Iy|*?)l@5KsXA!YE~Auv`t)f4s>V!|o_IPh8F_rtPv_~Z z3i`DjhXx>WUC6IMLQ$1S_VNGx5HT|fxP_$NU8Bjck-)}O{^pr@SkwMrou|{q?=c;p zybyYiT}+~{wismy&Nd<&d$IKAu)#xkAO$5Sr@}KoC^qsOo6?UjX#c`>r^#8_bMd*_ z+U=`*dfIw|+Amoun*e(RP83A74&E21YR*Z^>8#V+nFS`*4%6u-~}%`_qUoDm^wtu;F`byX0GvW34XL z)8K?q%Ho42SaA5~!OoSfvd_V%^B84-ZqNX@@X2$}lexB-s5KR`^PTQ0nbEzmxn3bq zq3-p{nib8CjmPplkd{&>(#>Rv$YS<8Ukk{H5n=nNaV4<0e?dV z-2*(<)BT&Q>sf7sHm2;*kH}s}M0dcLX~<%JK=tR;vV{PV8Vgsom3S?-U+%g)>mG$1 z;WcEBr{g=0?})>WgbJYlxz8()Qvm4&0)#KdsYr5K;FckU;y+ijlvLD{Now9n0cJbZ zn|+1=_OZrs0%bpantZP3$cc)kLG{380jxj7wInY97bc-b2yFv4_DN-mxYNZo<8~23 z@y}}mS?=8IY${a2OVj-@Q*>s11fPP-7OR@tkTaDiPA~1D#1dw^hY&u)veb#u#2Elmje?6aWGQ!C;Kf zw8h<>M?QW(^5coOyv|4xkjoyB!eO{z@yZbx7mDH$Ci0S{VvGmx)t z?8!li4N-r2H5Jd}fW&TH-@KVm7pD^*q${-O=pem+f3#rd=YL(ZsPyg*s6vvuV<%=CcQ08`Me1j_;&c5|otNwU9ljxumbaD0@@b{F*(d1c6_31*HQA2-cH ze$kulPff)W#OVs11u}Z<;Nbn==q#8Z8sjt{$UW%_fWLxZ9hgsW3A!nE%&K80jLfzZ z3Gv*MH(ek*#YG9kg-q{54hXcEu=rCJ^OHOt&aIi-MI`q3wZN9DY%OKOCAKml+M*r|0 z>(vg~(%X@wx9e3fPEznMWIv(02j*R~Jpd0FdutMsdV3W9U=&E-2FC-$rDXmBLZF2( zYGV$?*zmqqssBDO2127YQgjsgAjF_}1(qtA|SM@K&i)mtl1>IM-S zQ+Wy*4FtGczD_JkL|htF&P6J2t(v?w(iis3d%bR$aq9f|SsCb3{iox_y?EMW5CrD3 zFH#W?GFVC)MARTJwaTuDgu9c}aZk7(Ik1f&077ShT}k9R=m-mAPG2)i71%-9TJ76^iM z+#B~pTy?b-uGhGI6?2-E8p-*NRw#8bjq&D`(^@^;e zt>@J~FCgCdv*r?8;TC@0gha#KB(bleW378)wi_mjok)0FcKw_GpYZ1yKA$A(bk(09 zu4EN4blH{}ka71%{_+76!P;74Ye2_Y62A`Z3OOJE>NR*cySmx5$v^iW)sIGLCJ7rV+UdC&p>n%{* z1H=HB(<+6oBoBIC5}yr~6iB4q7?Xhg)T%_9Lvr|a|sw~(mp(2@FFDib6)rUZu`F~NG`;=0rNjeREE*%5%Ok#F!xf98KH=ZL9|txyGCX`*=69!{$>@(Cz!A>~?;7ax`$>Ijo65rq14NX-&q>tz z@bEX`?P7Er>3D{aMh%(Fm4D&mCp#X2egXMtfZY;MnTh0KPzzh#j`d?~#pg0FckQ7( zYT82|w6cL};e2|2_AZx*q2_OqS51}gyEG0;`o((%KlWB{M&a}teJshJaCUxmDxvaM z+isvQBzhZ@EwrFUujj=*+33KL*%GNxZ++v{&`c5D@w3>#9EzOR1Fkan8i=)8?Bg}+ zq4hoV+*2AC%D~_570pN%!JG#VF2d{@Fmt_|*leB+i3r6fHad_a0*eoaE7$^F=INwD z|GXX=<5digoRzN>6)E7kt9bNQBZ${>4-w{LjukKQ}%B&z_E&6=PYz1HN6kj z!rQ){WoITt8S{rZY&5}b?#-6OWgAM zuKf2<&|TS^Pj)#p5b58&N7~kdUnas8+)GEEdq!h|5@Mu#Pk$O)9iu0P?}gH?7EZ%@ zEES^30KspJ02Ynk-1~4_ zDM3#!9kaNAEmrk0W3K3K6uD(~%%gVw6AqbgmkR-1>DVVv}J#?$vmV@S^z#V7DhPL?G#Vg8G%To4G^ym zx?nZ8(~iJQ)V#(W8n3K}8>Y~C+6?cd#B=-Dcn^}1^u3gd4K*>u1J^3Pdf`jUFp)LK z92~-0TlYbngz=mq>%2d$PZ~3T=OpUx-HkXDYak-2!-Z&D(<_hpl;=ZPzEW^Fg6$=N z!naKBSG*>Y7+TYtR3vMw?{`u;Dwzp;#UPk|)ZSzY32t#Y!uw#DL>;*

GS%q%Pc$KsQX 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 literal 0 HcmV?d00001 diff --git a/docs/src/assets/logo.png b/docs/src/assets/logo.png deleted file mode 100644 index 0cdf623fb958e4d4e792c3a1e28c2ea12056be7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72255 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

GS%q%Pc$KsQX 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 diff --git a/docs/src/assets/logo.png b/docs/src/assets/logo.png new file mode 120000 index 0000000..ce59400 --- /dev/null +++ b/docs/src/assets/logo.png @@ -0,0 +1 @@ +../../public/logo.png \ No newline at end of file From 1d5a0b22e6099e6e4b096ec31c15253df77faf75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 13 Nov 2025 21:00:55 +0100 Subject: [PATCH 107/131] docs: update documentation --- docs/astro.config.mjs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 6e6803b..0e0ce23 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -1,10 +1,12 @@ // @ts-check -import {defineConfig} from 'astro/config'; -import starlight from '@astrojs/starlight'; +import {defineConfig} from 'astro/config' +import starlight from '@astrojs/starlight' + +const BASE_URL = 'https://domainwatchdog.eu' // https://astro.build/config export default defineConfig({ - site: 'https://domainwatchdog.eu', + site: BASE_URL, integrations: [ starlight({ title: 'Domain Watchdog', @@ -53,6 +55,10 @@ export default defineConfig({ } }, head: [ + { + tag: 'meta', + attrs: {property: 'og:image', content: BASE_URL + '/logo.png'}, + }, { tag: 'script', attrs: {type: 'text/javascript'}, @@ -76,4 +82,4 @@ _paq.push(['enableHeartBeatTimer']); ] }) ] -}); +}) From 72e3d319e55efbbe4a0390931a6688214536660c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Thu, 13 Nov 2025 21:12:08 +0100 Subject: [PATCH 108/131] docs: update documentation --- docs/astro.config.mjs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 0e0ce23..d077680 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -55,6 +55,14 @@ export default defineConfig({ } }, head: [ + { + tag: 'meta', + attrs: {name: 'twitter:card', content: 'summary'}, + }, + { + tag: 'meta', + attrs: {name: 'twitter:url', content: BASE_URL}, + }, { tag: 'meta', attrs: {property: 'og:image', content: BASE_URL + '/logo.png'}, From d244ec7980dac87f2721e96389d836ace65ee709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 14 Nov 2025 00:46:27 +0100 Subject: [PATCH 109/131] docs: update documentation --- docs/astro.config.mjs | 1 + .../backorder/{connector.md => connector.mdx} | 10 +- ...d-registrar.md => supported-registrar.mdx} | 45 ++++++- docs/src/content/docs/en/features/index.md | 5 - .../features/search/icann-registrar-list.md | 3 + .../docs/en/features/search/tld-list.md | 3 + .../docs/en/features/tracking/watchlist.md | 10 +- .../docs/en/self-hosting/configuration.mdx | 1 - .../{docker-install.md => docker-install.mdx} | 8 +- .../{manual-install.md => manual-install.mdx} | 123 +++++++++--------- 10 files changed, 129 insertions(+), 80 deletions(-) rename docs/src/content/docs/en/features/backorder/{connector.md => connector.mdx} (82%) rename docs/src/content/docs/en/features/backorder/{supported-registrar.md => supported-registrar.mdx} (72%) create mode 100644 docs/src/content/docs/en/features/search/icann-registrar-list.md create mode 100644 docs/src/content/docs/en/features/search/tld-list.md rename docs/src/content/docs/en/self-hosting/{docker-install.md => docker-install.mdx} (69%) rename docs/src/content/docs/en/self-hosting/{manual-install.md => manual-install.mdx} (61%) diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index d077680..9512f39 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -40,6 +40,7 @@ export default defineConfig({ label: 'Developing', items: [ {slug: 'developing/technical-stack'}, + {slug: 'developing/add-provider'}, {slug: 'developing/translation'}, {label: 'Contributing', autogenerate: {directory: 'developing/contributing'}} ], diff --git a/docs/src/content/docs/en/features/backorder/connector.md b/docs/src/content/docs/en/features/backorder/connector.mdx similarity index 82% rename from docs/src/content/docs/en/features/backorder/connector.md rename to docs/src/content/docs/en/features/backorder/connector.mdx index 6955628..125b106 100644 --- a/docs/src/content/docs/en/features/backorder/connector.md +++ b/docs/src/content/docs/en/features/backorder/connector.mdx @@ -2,12 +2,17 @@ title: Connector --- +import {LinkCard} from '@astrojs/starlight/components'; + A Connector allows Domain Watchdog to communicate with an external domain registrar’s API to perform actions such as domain registration. ## Create a Connector -1. Choose an external API provider from the list of [supported registrars](../supported-registrar) +1. Choose an external API provider from the list of supported registrars. + + + 2. Enter the required information using the credentials obtained from your provider’s customer area :::tip{icon="heart"} @@ -15,7 +20,7 @@ A link allows you to directly access the Provider's page to retrieve this authen ::: 3. Review and consent to the required terms. As a reminder, you can delete a Connector at any time from your personal - space. +space. 4. Click the button to create your Connector. **Congratulations 🎉** ## Legal considerations @@ -30,7 +35,6 @@ In particular, you must consent to: - Accept the provider’s API Terms of Use - Confirm that you are of legal age to accept these terms -- Waive any right of withdrawal, as domain names are reserved immediately and made available to you Since the terms of use may change at any time, the link to these terms is always accessible on the page listing the Connectors. diff --git a/docs/src/content/docs/en/features/backorder/supported-registrar.md b/docs/src/content/docs/en/features/backorder/supported-registrar.mdx similarity index 72% rename from docs/src/content/docs/en/features/backorder/supported-registrar.md rename to docs/src/content/docs/en/features/backorder/supported-registrar.mdx index 79ea953..cb205e0 100644 --- a/docs/src/content/docs/en/features/backorder/supported-registrar.md +++ b/docs/src/content/docs/en/features/backorder/supported-registrar.mdx @@ -2,13 +2,15 @@ title: Supported registrar --- +import {LinkButton} from '@astrojs/starlight/components'; + :::caution[Reminder] * Please note that this project is NOT affiliated IN ANY WAY with the API Providers used to order domain names. * The project installers are responsible for the use of their own instance. * Under no circumstances will the owner of this project be held responsible for other cases over which he has no - control. - ::: +control. +::: ## OVH @@ -21,6 +23,13 @@ title: Supported registrar | Subsidiary | the country linked to the OVH subsidiary associated with your account | Required | | Pricing mode | choose whether you want to pay for a Premium domain name or only standard prices | Required | + + Retrieve my token from the OVH website + + ## Gandi | Field | Description | Required | @@ -28,6 +37,13 @@ title: Supported registrar | Token | your account authentication token | Required | | Sharing ID | indicates the organization that will pay for the ordered product | Optional | + + Retrieve my token from the Gandi website + + ## Namecheap :::caution @@ -40,6 +56,13 @@ connection. This information must also be entered in the configuration. | API user | the API user as given by the Provider | Required | | API key | the API key as given by the Provider | Required | + + Retrieve my token from the Namecheap website + + ## AutoDNS :::caution @@ -55,6 +78,13 @@ supported. | Context | the "context" as given by the Provider | Required | | Contact ID | Contact ID of the domain name holder of the purchased domains | Required | + + Retrieve my token from the AutoDNS website + + ## Name.com :::caution @@ -64,8 +94,15 @@ supported. | Field | Description | Required | |----------|-----------------------------------|:--------:| -| Username | the account username | Required | -| Token | your account authentication token | Required | +| Username | the account username | Required | +| Token | your account authentication token | Required | + + + Retrieve my token from the Name.com website + ## Custom EPP server diff --git a/docs/src/content/docs/en/features/index.md b/docs/src/content/docs/en/features/index.md index bd7b107..805df41 100644 --- a/docs/src/content/docs/en/features/index.md +++ b/docs/src/content/docs/en/features/index.md @@ -22,8 +22,3 @@ A confirmation email will be sent to you to verify your email address. ## Create a Watchlist ## Create a Connector - -## TLD list - -## ICANN-accredited registrar list - diff --git a/docs/src/content/docs/en/features/search/icann-registrar-list.md b/docs/src/content/docs/en/features/search/icann-registrar-list.md new file mode 100644 index 0000000..1caa289 --- /dev/null +++ b/docs/src/content/docs/en/features/search/icann-registrar-list.md @@ -0,0 +1,3 @@ +--- +title: ICANN Registrar list +--- diff --git a/docs/src/content/docs/en/features/search/tld-list.md b/docs/src/content/docs/en/features/search/tld-list.md new file mode 100644 index 0000000..a2e21c2 --- /dev/null +++ b/docs/src/content/docs/en/features/search/tld-list.md @@ -0,0 +1,3 @@ +--- +title: TLD list +--- diff --git a/docs/src/content/docs/en/features/tracking/watchlist.md b/docs/src/content/docs/en/features/tracking/watchlist.md index 8dd7dc9..f28a246 100644 --- a/docs/src/content/docs/en/features/tracking/watchlist.md +++ b/docs/src/content/docs/en/features/tracking/watchlist.md @@ -5,11 +5,11 @@ title: Watchlist A Watchlist is a list of domain names, triggers and possibly an API connector. They allow you to follow the life of the listed domain names and send you a notification when a change has been detected. -If a domain has expired and a connector is linked to the Watchlist, then Domain Watchdog will try to order it via the -connector provider's API. +If a domain has expired and a connector is linked to the Watchlist, then an order attempt will be made though the +Connector provider's API. :::note -If the same domain name is present on several Watchlists, on the same principle as the raise condition, it is not +If the same domain name is present on several Watchlists, on the same principle as the race condition, it is not possible to predict in advance which user will win the domain name. The choice is left to chance... ::: @@ -25,7 +25,5 @@ Now, it's your turn to create a Watchlist! ## Limitations -Depending on the instance configuration, there are several limitations to frame user behavior: +Depending on the instance configuration, there are several limitations to frame user behavior. -* `LIMIT_MAX_WATCHLIST` : Maximum number of Watchlists that can be created -* `LIMIT_MAX_WATCHLIST_DOMAINS` : Maximum number of domain names for each Watchlist diff --git a/docs/src/content/docs/en/self-hosting/configuration.mdx b/docs/src/content/docs/en/self-hosting/configuration.mdx index 6202f1e..bc5428e 100644 --- a/docs/src/content/docs/en/self-hosting/configuration.mdx +++ b/docs/src/content/docs/en/self-hosting/configuration.mdx @@ -4,7 +4,6 @@ title: Configuration import {LinkCard} from '@astrojs/starlight/components'; -## Docker ## Environment variables diff --git a/docs/src/content/docs/en/self-hosting/docker-install.md b/docs/src/content/docs/en/self-hosting/docker-install.mdx similarity index 69% rename from docs/src/content/docs/en/self-hosting/docker-install.md rename to docs/src/content/docs/en/self-hosting/docker-install.mdx index ea770cc..3bcc323 100644 --- a/docs/src/content/docs/en/self-hosting/docker-install.md +++ b/docs/src/content/docs/en/self-hosting/docker-install.mdx @@ -2,9 +2,12 @@ title: Install with Docker --- -1. Download the [docker-compose.yml](https://github.com/maelgangloff/domain-watchdog/blob/develop/docker-compose.yml) - and modify it as needed +import {LinkCard} from '@astrojs/starlight/components'; + +1. Download the [docker-compose.yml](https://github.com/maelgangloff/domain-watchdog/blob/develop/docker-compose.yml) and modify it as needed 2. Download the [.env](https://github.com/maelgangloff/domain-watchdog/blob/develop/.env) and modify it as needed + + 3. Add static files to customize your instance (under `public/content`) 4. Pull the latest version of the Domain Watchdog image from Docker Hub @@ -19,3 +22,4 @@ docker compose up ``` By default, the container listens on http://localhost:8080, but you can configure this in environment variables. + diff --git a/docs/src/content/docs/en/self-hosting/manual-install.md b/docs/src/content/docs/en/self-hosting/manual-install.mdx similarity index 61% rename from docs/src/content/docs/en/self-hosting/manual-install.md rename to docs/src/content/docs/en/self-hosting/manual-install.mdx index 3a802b2..89b16ec 100644 --- a/docs/src/content/docs/en/self-hosting/manual-install.md +++ b/docs/src/content/docs/en/self-hosting/manual-install.mdx @@ -2,6 +2,8 @@ title: Manual Install --- +import {LinkCard} from '@astrojs/starlight/components'; + ## Installation To deploy a Domain Watchdog instance, please refer to the Symfony documentation @@ -23,60 +25,63 @@ Clone the repository: ```shell git clone https://github.com/maelgangloff/domain-watchdog.git - ``` +``` #### Backend 1. Install dependencies: - ```shell - composer install - ``` +```shell +composer install +``` 2. Set up your environment variables: - ```shell - cp .env .env.local - ``` +```shell +cp .env .env.local +``` + + + 3. Generate the cryptographic key pair for the JWT signature - ```shell - php bin/console lexik:jwt:generate-keypair - ``` +```shell +php bin/console lexik:jwt:generate-keypair +``` 4. Run database migrations: - ```shell - php bin/console doctrine:migrations:migrate - ``` +```shell +php bin/console doctrine:migrations:migrate +``` 5. Start the Symfony server: - ```shell - symfony server:start - ``` +```shell +symfony server:start +``` 6. Build assets: - ```shell - php bin/console assets:install - ``` +```shell +php bin/console assets:install +``` 7. Don't forget to set up workers to process the [message queue](https://symfony.com/doc/current/messenger.html) #### Frontend 1. Install dependencies: - ```shell - yarn install - ``` +```shell +yarn install +``` 2. Generate language files: - ```shell - yarn run ttag:po2json - ``` +```shell +yarn run ttag:po2json +``` 3. Make the final build: - ```shell - yarn build - ``` +```shell +yarn build +``` 4. Add and modify the following files as you wish: - ~~~ - public/content/home.md - public/content/privacy.md - public/content/tos.md - public/content/faq.md - public/images/icons-512.png - public/images/banner.png - public/favicon.ico - ~~~ +~~~ +public/content/home.md +public/content/privacy.md +public/content/tos.md +public/content/faq.md +public/images/icons-512.png +public/images/banner.png +public/favicon.ico +~~~ ## Update @@ -86,38 +91,38 @@ Fetch updates from the remote repository: ```shell git pull origin master - ``` +``` ### Backend 1. Install dependencies: - ```shell - composer install - ``` +```shell +composer install +``` 2. Run database migrations: - ```shell - php bin/console doctrine:migrations:migrate - ``` +```shell +php bin/console doctrine:migrations:migrate +``` 3. Clearing the Symfony cache: - ```shell - php bin/console cache:clear - ``` +```shell +php bin/console cache:clear +``` 4. Build assets: - ```shell - php bin/console assets:install - ``` +```shell +php bin/console assets:install +``` ### Frontend 1. Install dependencies: - ```shell - yarn install - ``` +```shell +yarn install +``` 2. Generate language files: - ```shell - yarn run ttag:po2json - ``` +```shell +yarn run ttag:po2json +``` 3. Make the final build: - ```shell - yarn build - ``` +```shell +yarn build +``` From 9830055c0b8ebe5dd31083963567d16ca858d26c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 14 Nov 2025 15:14:42 +0100 Subject: [PATCH 110/131] docs: add robots.txt --- docs/src/pages/robots.txt.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/src/pages/robots.txt.ts diff --git a/docs/src/pages/robots.txt.ts b/docs/src/pages/robots.txt.ts new file mode 100644 index 0000000..68176a4 --- /dev/null +++ b/docs/src/pages/robots.txt.ts @@ -0,0 +1,13 @@ +import type {APIRoute} from 'astro' + +const getRobotsTxt = (sitemapURL: URL) => `\ +User-agent: * +Allow: / + +Sitemap: ${sitemapURL.href} +` + +export const GET: APIRoute = ({site}) => { + const sitemapURL = new URL('sitemap-index.xml', site); + return new Response(getRobotsTxt(sitemapURL)); +} From bce1bc0a4bcac883275984ca60bd7d831979f05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 14 Nov 2025 15:27:43 +0100 Subject: [PATCH 111/131] docs: update documentation --- docs/astro.config.mjs | 13 ++++++++++++- docs/src/content/docs/en/index.mdx | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 9512f39..56aceed 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -15,7 +15,7 @@ export default defineConfig({ src: './src/assets/logo.png' }, favicon: 'logo.png', - description: 'An app that uses RDAP to collect publicly available info about domains, track their history, and purchase then when they are delete', + description: 'An app that uses RDAP to collect publicly available info about domains, track their history, and purchase then when they expire', editLink: { baseUrl: 'https://github.com/maelgangloff/domain-watchdog/edit/develop/docs/' }, @@ -56,6 +56,13 @@ export default defineConfig({ } }, head: [ + { + tag: 'meta', + attrs: { + name: 'keywords', + content: 'Domain Watchdog, RDAP, WHOIS, domain monitoring, domain history, domain expiration, domain tracker' + }, + }, { tag: 'meta', attrs: {name: 'twitter:card', content: 'summary'}, @@ -68,6 +75,10 @@ export default defineConfig({ tag: 'meta', attrs: {property: 'og:image', content: BASE_URL + '/logo.png'}, }, + { + tag: 'meta', + attrs: {property: 'og:image:alt', content: 'Domain Watchdog logo'}, + }, { tag: 'script', attrs: {type: 'text/javascript'}, diff --git a/docs/src/content/docs/en/index.mdx b/docs/src/content/docs/en/index.mdx index 174b625..bfe385b 100644 --- a/docs/src/content/docs/en/index.mdx +++ b/docs/src/content/docs/en/index.mdx @@ -1,6 +1,6 @@ --- title: Domain Watchdog -description: An app that uses RDAP to collect publicly available info about domains, track their history, and purchase then when they are delete +description: An app that uses RDAP to collect publicly available info about domains, track their history, and purchase then when they expire template: splash hero: tagline: Your companion in the quest for domain names 🔍 From e040f484c9252e5f70c32fbb732f05d263cdc8a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 14 Nov 2025 17:06:47 +0100 Subject: [PATCH 112/131] docs: update documentation --- docs/src/assets/images/create-connector.png | Bin 0 -> 50649 bytes docs/src/assets/images/create-watchlist.png | Bin 0 -> 54136 bytes docs/src/assets/images/search-domain.png | Bin 0 -> 94522 bytes docs/src/assets/images/tracking-table.png | Bin 0 -> 50470 bytes docs/src/assets/images/user-register.png | Bin 0 -> 10915 bytes .../backorder/supported-registrar.mdx | 2 +- docs/src/content/docs/en/features/index.md | 24 ----- docs/src/content/docs/en/features/index.mdx | 101 ++++++++++++++++++ 8 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 docs/src/assets/images/create-connector.png create mode 100644 docs/src/assets/images/create-watchlist.png create mode 100644 docs/src/assets/images/search-domain.png create mode 100644 docs/src/assets/images/tracking-table.png create mode 100644 docs/src/assets/images/user-register.png delete mode 100644 docs/src/content/docs/en/features/index.md create mode 100644 docs/src/content/docs/en/features/index.mdx diff --git a/docs/src/assets/images/create-connector.png b/docs/src/assets/images/create-connector.png new file mode 100644 index 0000000000000000000000000000000000000000..42fcd44323dc98d5ee2d66d6d3968446da49758f GIT binary patch literal 50649 zcmcG$cT`i`+bygIl@2OMFM32kr768DC<;gu57LWB3B3p;R22vc0t!fnh;-@FyVNKx zGzq;02vtZz2{qq}=bYd7j&bk%-S3WZ?|+QV&fa^iz1H*0`ONw3x4PO7=xI1;PMtbM zum14f<5Q<77Ehh}L!Rm!I1>I+&g#^um#5V4-F*TzU!Ph;aQ)R?bdo?Il8WaORKMjHj|Dw z;U46_V|-h5MaX|Vj%NGkzZX<%!Eruy#b<&Eeev`}GcO`pk zF~I_E5x9S?VQ0i-4&N=xC~ns$q$Qua)RV+?azsFt?oIn8bVkO}OO0MuINEBP8`4px zZ$3G2Bra!0x0?A(U6Pu5F*I0lvwm+TNZAy&_%VBqe4DI+pI(B>;0M-XCu=3mt9Hl zWILOVrqZduN4eTqtg`=(UA*tY+<_>=J#_vVN^Y%? z&B3A+yN9ip=VY^?|YOXcZeNwo3 z@?t`g!qztmccQlZ2D5qK{vun9^5J^9TgRoRAwLaFiYhh|Z`)`Pn@NYwhUKV(Bv+K; zo{(08!u~?6yBVVr(bCYdsB*O}LDYgLY{q-S8K<}=PdXx4Ye{q;Z?!R66Vv3p9Jqq| z?^1TG811tZtKxLVQr`HS|BiA#sL}Qlx}=F!N;?@%88RCE&%lfrn~`;H`hZ{8iJZ z8L6ipJp`BC)4+^?*X1iLJD0FRm40S1#ij1LkXfAsm-ncZJJGSEkwsf(E`)6y*4)M* z-@cz7c(6iD&)J&YNpWprM{+}FU)}1ty*@)a@u5pzKXdoP&iP&H!gtD>4FrveFj|qC z%Tc+q2g;;<6x&e}VsT;U_0sAio$`HuE=kmi=vn!xWgk-xX!a4lFbWk?=QRSwC~{hH4| zVg-;ZcQ%|kw1q|5q$ZroiRsv{FhuKgD62VJ8}!S{lB`RoKB4dM@K?QPlTI&M-%WWj zPJeZ6R@SH0rb$a?H7|2s;W`!5y(GjpgpTHS8?MU1{hB|kKI(Q?d)xdRwqXcks+Y+g@Uo&6!}COTq}?4E z%C&`@vlxBCj&{}IgljXsV{xr5WajrypIW&Qmuow*0r&XB+#Tx6BfmH4iR!?G+-Zf- zM5urH(WeUYMO=Ntk}@I?fqKOdYo(JPXnA{5q+K(X)cU+{*d_#=a@}`*(&n$C|{Ex<6@eV zwDfuWA~~SM)S>?poN=k&c=ph5Z^}m#1Lg4tTQ{OaUr+}nB5*x!=v`X!Oo;K^Sz4C% zoUxwr&8EZ7Imm%QMyg$IM7L@twrk8KM;X`7gptUvs?!rhqLfKoNNg|KX!jP9iwS|& zo{Q(7?ttXY^|d*d#iuM`>AF?-mr`8K5%3gRm|!luZ&OLR9jcf&LSIL*vVyl`pP)Ov z;{7{{!ix)Zwb`^<;?w(w+#EjYKLDff9{ZG`AZekKk=!>#^-;oFCoMdC{P`cQzBwt2 z;zDOp%qRM>&MGiti9+Qk1!x=iEttu;h_VELsZFt{F z`Has@fDac!&exhJT@rhNA}3(s!-IKZFr$)86IM3BCH2LBh9MVco#I?YjZ!*vax&Kz z<)QE?!5M|5{mX4X(lbWJmD zK`*6GNjw!*G_es+4vh3u?^XUzkE`kbBv+nWf2ZN$tN*6d_W%DW_09kKB6L)X4Ih37 z%;_tM1swE8Q_deka@0G&n?) zpcy04=~TCpV>RW47N$pUaSrI38+qJamftPO`?~#k5UL(y;2WD0(sXQIWPvjNqTQ{K zz4$OjLX8~Ht*WQIY3tX&Y8u+5d1+uI8`SvXo{mf@JlTad7|6&HgZq8@{VLIZicAJc zwSPf;!LX20k^{=~-Re&B;#YbDIzimM({*6>P(Mi%txa|oypYB&vizEAN7j3fQ^ ze$|8vr-4Pl&Y(X>ofY-s$67ylld7_r-ua~4L{G|(Kg3mLzJ@u@9hHiz*i665hK%Eg znCLJvs(LvSL{ju8&V|h-I~G%eL?YTN{v=uf{}6hzkJW6urjB_ks=9wYH}ztPE2F~J z9f)Z)2<}Z=T{lbO;L-4bny9EwIX+0kn0;m>$2pHI-KJit2|7(d1VA4C2FHokQPkK} zPi>ivilNqwFdh!6Nw>Da3Z{*In(`q)%K&&Pm^5*qvTfe+*+vx;^2%++e12xAUEkiYWN`Q%Qk`n z3eAK*`MCs(z?C}6$uJ&Y!Bpt{+nv2k_AbJjWiEQad*M*};@bNxoD;xcnJnL>M=gWh zmXho`*C@2+AtI=m#qNYKTG0kEA)~KZ5-7u#Krg?dUrKQ(Q;vgOzao}G#{JUaIj#ED zv~S#7z7NvAUFez#Jlq&`b3=zFpG`Jgz^DyP`OG*ACS=_z22kkrc{GUe@g4D&BqCB- zW2gcHP~eJ@AaCTFWm8a0)~=qsqVX%Pqvo7ThMCwQfazx4e$`^(?Bbo%IuRE;YxBic zGa5X;aqcAlvhp0Y%if{OF%rZw(4I}Y8m;hE$*JY_*|{-01U-oG)`jXp_#Xmosj?IZ z2sVnoccvL6V#7DH+6>*Y2g{ilVuSjmZHhC?WSgUkZxDgOEB*we0xAI8@h@?vhk2JQ15Af% znmi&k(IaZ;mLs|FZqa51fACXx`E=jad>J#22d>QkyLv*w_%Pn37R*b7M76_&lHk^< z#=U9I>RZAX0No3sXP!j}&mRGh>f>ayMOr zNs>c_b*o=?te)RI*+c*oh!aH@18^=Jm7?h9ZOS8gyii$=Qj%Y)RoorD`sBvPgWFJp zbPbc@1fk%OpB=NxF#Lksx6_pEJsrOG&i5G}VN8m`I62?xFaWYL*i<erm94;DNi-ecN;c5_#RSY<%pX0W0RPO;$MS2159u;)wVnLIYNYHt*F|(Vd>&3TCBxdH1>zD&vi|P;%kx%58>8LDy$zBoJL?(ak>EQJ#M`4q@{CJo? zUGCV#JzjpsHW3$pRUPvKFq#LF?}KU7PG(qDeZ&{Ui`|b9{Nm0{`%5^u`tJ~9M()fS)1zfwTI8dCgb^z z10Bm|^+;N1mG3SRh33$e%kKmtRb;Ia$L(m&cI3dAML<-jJ{`&~LJT_Dw`;6A*qv~V zCS<>7py3D(#RE)yJ8A;Z#I+%DQ33S>F?=i4*()@%{-qGM8a>^@N^FSL7-RxuaDnfv z*jT>EcQ1N57^X}yRB5J}gI+g7x4T8^oxZ&QJk{m0r>89a)feL2p%>sopWkt;`q!R8 zZ>MkkNNEwLM>lONH8U(pR~s>gCQ77_hdGF&Fx9wRT>TEPD{n2+j0;9j>!rWD>+B)SYGXB)m{k{V1`Xgp6 ziuP*0_n$Kity10D)c)=k#82!971;Eod5pyERdivY*VEj(#?Apc1=l4ldQp@PYnT^j z7lgq)HO#>H(Su&~y4``)dKr32S~>*a)c!hx&2wO`kZUTtQOs;f<-T>8^E zLyY3DG+i18w0NdLJ0sOvHx+LEy{xAi0EHVTtRCgn ztRRLXvfo0L8ZK1DzVG(Rmq}$o(dAwg4_$1ybPIjPr3;^Ybgw|jIB?+eO_Y9!cV{j? zj+!9OSn~ILz&6)Rv#6`~sdrZkN*Ji>@8_3p0RqzbTEkt5fni93W^uNUrjliH#ZE5W z?xvDw0;?K_S8}?qdYu_T@#ugQ&_qZ=b8DbCRG~{62_MLns*^1u7$xVtIS!0 znO07I^%ck935gaybgDeWhx|e5o9W zog$N593W)-{q`{ld)r+VrtJ}@mDEFDX*+gBP<2nPi-3E_PAB-It75!VKecAe^Bd2XgEhg4i)f^K$O}gAZ~@ zb_YQL`||V_hpr)LI)xB}UE>BE|3p7sG{rix%2NVh^ddT{gpjocYn0lnRD+gop9!<#sDD7arF?B|rpeQj=WlZS}Zt*xqzI-R}Dj15?MEsKHdlgb@%V=oZJ^ ze%ZUZ3oET@WxV2fPFQmE&&y}$QJzrQEa|}YreDWW^afFWtXG#n=!6D0hz;glZWniY z!Ir=%9;f+uQ=-B4l9rk4{f(pHSH~e0jqmRE*F{*YeGdz!RpQRbc4SRU#8ds{&cPGQ zp&^+2sZHy&oR+Y5Tjb{O>FaQguKet|WOb}FL;(%)4Y8Y2=tfFiLJ&0D#_1PVlJE+n zLpYPV3$B6*5_;!fP>(!0g(taI_kYx8p(P*a_7d{&qrL+74S+ z`CO{yFrQnC)|Ge)?YUQdlSEya{pE&Ge&>AlbB(1QdO4U=+Gl)aT}KXmSBuiHD>7yK zmzSaN*L0gnOXRxGB*QPFZX)E#`OjG8c-6==7R(NP*WXK3oBrOsDAdE5sbL z*fKQEam@>DCT&?;qyh`%?lDQldD@#w!5QesB`ku+@@(sPDu+{dvcgY>Cul*(CB-nPZ)le_AOPk z-t5Kg2YER;zPV}M;S=|mJklivLOhu+YjxLsw|&$WdAj)8qu7(6YNq(4ct?)Ihgu3S z$9?=F1&{2~flBlBcNo3=jj9O|7wfJU8--yFKP1-mrK36D)$2wLFGNNJaHwUx=CG#` zHT||9faCU=bpPf*S(Gcz?rSCRjWAc1x*aRHADYhir&piaH@lSZ?uC24q~ks7jMotX zU@zq@e%flQx_}=u&_3g!>e9Gl0P47rU%`&@Pd@3J#LuM(U44Mf3>n@&dU5s4(6FbB zbbRe@|GP8`_BoDL`YC|d3X~L4eeOl`IFVw}$m07jLCVTOp_G%yR4t|j;f?4jCNlUA zu;_^jb5M!*xxcVq|6U^;vxwBulO|a{lxZJ+q z6Wa^$>$>AF-vu6Hd_lV{_ZlJ9L2Qu*WpNm<`dTfi-{ zRcN9I_2f2plAtpaW}Ld)w3AvQ@AmZ*d=6*WtkM%RWncxd*)zT01opI-ZTsdSCKE zjvPTy?spSX1qJJSn!>N;CFeVgy&U?e@n;UUo#gQ5lRwjbsmfkyaJVCgf_J=r7;8nL z0^^7;v11;1{%Xl}I4W3In`zfy4m_6BsAK^X*aw4M@9YX!HiK!@5AcHUEpN8(VLIrH zRP3^#6J4$?Y6+D3jURvFVfcM&-sqT#N+=&ndk7~P;L-mmjiHFW4=VR8GbfdU;163h z-^*w){?10d?+XU%<>_7Ivmo_EsG!0h)coIBY=0`(OfFz*3V2@aQ^)XkeIH`~Z=wG` zbpQWyY2$yR@bG`_N%F6j+xF5#u!=HhCWz3RxYTCzsSm!_&H3bXm;I`!&qJnH8K#d- z_;u2`L=y>1y|jQ@Gk(;_mWTwJNv@#2Zq=uEca4H?KTwL4NN4Z5R@osx8p8+4%4UJ> zyFnB{8gO_^%jZ)^CUZJc9(^;zGk z$EN#fVBnwG5(U5{?Scw(>4>r8$DFlcpvCayXs2;lppwJ|)3b18%P;3O>aR_%7l}as4kEpiKBKudQ*4aaZC&VdO6v zvTV?8zx1_RB%+&K3)aMp7SGee5kV)i4cmj7bMI9d@^#An_wj>~ZvfknnFQ5D+~kjh zF{*CMu@0+sMl6zoQQHC^CAR{ zceikL2;jWpWbrQBh7N8?0wg``0S}C?;RxTIjdNnPl5Vu9akHv9SS@Jd4LZ6|1uCU7 zLX5+cJ+iYeDOwLVn|V?D{z;Jw-Lusu7JyW30U}60%3Fm6b)^Vtga<8)(3>Gs=v=5f zVnonifF0?x`6-y;Mv+NOmN~n|m@0=O-6Ds9xPh6Z>CPT~>tTxPg(jn~Hqd989aagF zlqG37yRmml$tq9(3s9k8WFrANuzi+57FJfE%|JnDcL%#EJR_>V)vZ%}3h*`z(Y6;& zt&371Jff3#ZQL1oX*;YLFZA}+TNqg)W2?xEPUK}{u0AXY6v5%Sh`>6Y zE_YBqLt3{gOHX^cxL?g4dce917%~vxl-n1@lqGvRa3CdK*#|#h0F^12KZ0^~VOU=$ zvT`IpzCLOGwmlBFUXJQSrJy@jIGlB&HpntZ8^}~9yq#Zpe3vr@D}ahRsN2OeXlN~n zE-iSXSm&k(g=XHjiiH#;bh4(oce0m_yhpQ|y4}4lbMX;%ql6cK$OVsl_Us(dv(74l zuiok&fagKJ?`!}Sa~0t$>31}k<}p$7BImNwe5Pf!4-upz0XSKc6$Ou?GzSVRbY%L? zRSn8{?TcB-_<1=gP%Eq9s`{{VVYLYqmVAe>Wa9L@U%BFhbl_#iGx?510taD0BQLT0GPYSJp`|ycvQi; zD75rgp+uA5&k#cL%SS^q&m#G(V)$!U6f1*=RrJ?VUrS|Ni<}{=QyH*Q-6k+?a8RG} zymQ`)efT{g+0DX9jZ_kJd{co;9KFhQ`?Nw|1YfzLkeh=F@mLZTIRw+iSsHYIc$R5& zOzO3{@3|zm&Re5E0bL!sIKtj}LYP!20kZd|Oq9XtGv9#F(_9hd?d55;06$k*x-K5X zsg6mMLMYEAUgV*kAyeW28EGA8PJ^BxmY4Hxyk*}}h0yne2|8r5b*C2NG%sx71I|-q z#0h&PkpSPYAMsB+-vk0x2d7|~lm%8{0qV}PIP_^ud~qMcG92frAC|LTG5I~=n)>4s zFMSa2Z>ZM7r?NDz6%O#4+xMkM>rg42NqiReR7Yw5xl?@FwDgy`Y;{=_Ywjnr!qDuI zM62OHfT%<*+Y5m07E>0r%Jt!`_1l=_P&^P86-SC$61)c01v>8ZI<`JBchsQYv*eyE z+a!xWg+GOqHoFs~7|qnbd=yyEUGyk_$&cE{%MbL1en3Tj>z(mlAOMMvAml9<50Y(E zM#}pM!8lCCkah$zOHaVF=zLX#w4ouRumrJTs8sDrV#<|{_Y--U(hXa!wA^0XoeC9k zv*L^X7&T2LvvRvG0^o4ZUt8~kZ66P6M1x(QQb4FSVDI`Ve&&rr;mf6pd?V48I9;Pu zQN~3e>*xne>i*UOc^n_EMEU|*>|I;l#xJn+4A1vaKVM;gmi(if-bqtQN9Fw0ii=I= zejAln&~R^0t4A3PGD62{FmPL4?a>7pea+)u>6wrz?+M}E@IIXFk!42eii~!oud{0? zk_Jz>I4Pkqv~VSng$)*|faSQWsHKXai2TD#9KtSPBw)&v1+jX(UPuq?4Y;|j_pLUK zF@Xt}-BQ73oD}_1r3gYZuHc&5nTvRu zNxf%D)+R+qo_tkG*5&nEFT=6p=c}5)u5%9caN%hH3z1^!+V+;XQNu6(IHs>PckfbZ zYE=WFcs?+glV(L04>$nIOk7ww!xQ9Tpy|GL(^9lWsQ6<*-f{oz*djez^q2Dyj-!=-TBaGdqgl!nr1cEqP?7 z*Znw@Co@t}SJQ&-bJ-a~OhIuH7a)H{hH-exzJjjL+NG*L-;!gbZy)e|9(C%8DP>-MZoce<%EKEc=DWHovU%5Y;c*71CVMXH;?jAh zAyPWA$MZ){(uXbL`2DZ929@8EM=+=^NQso*afzCvTjVnF{f@Q!iFf}b*$&bdheb8h zYtFN)+VoX)QPeZB!x%rLzvsS5M4cfLdENjkzRYhvmK zHbQTCt&eCZA;4*)b;97Z4}YJAEhc9TQN$OPJ}0gU}Y-z=fF3J5#C0hP-$ z@IM2`MGy~Svff%YfCb|Xh(P5+s2=b=@ptq5jfC;7g6c79u{Mlae1Pu=)$&{l60Ppcu zZb#Ag0MYX4jg-clGDZFe-p5Qf<`^ZR5;egu?j*hbde(-niz7}J56Qyy0FZrkg+YqD zv|s!S;0L<8Ii>g0`EUQXR;m9fgSz>#YvgHYm&jf`ykMr#S;dAVtuixb5s&n;&z2o& ztI-*(DL-+^*jz?*wIRcQIEFS^lV}Qh44?2k{mTgYVp)E9YH;h8)vxIck9PFpoUkqlh4ViHWtjp-oXFxNwBJ zzN$^8bywTOld+wq{_1W;tB*~8X<|M{M$vw3`q|aSX=p?fD!iwjwl=Gv%LykoZW!VS zoJ+dqW53|9NZkn}o`YSIYo3#@gO`7{#PRzbEt-$b8|Mv-yo_O!H&huHZ*8GWjX9KV zz|VJSqUD;)2SaQDD`BD0s#G!APz(+0B26f6Z|otAKRJl$T>aRHDCw(y03n9l^2=Sl z1n-GeYp6kHixs=E$>jjd9V7S>sFS=f7?Q zRPGIp(0-iap$d2q$a}zWsK9dS=}HP0@~>T3zPY?A8(-=k_qKVSkZiNTvZ-I}W8Fd_ zxncv&pluZH+?{M=nW(nv28r#z+9qE*XUsMnRU5a!Q_h)Ka33%nOKfxRSXZ7uu+J-0 z%56A?D2hvkOICesYi9VUs>JXyo3&^(*WWn4af1}vL@~n<@W7vGPkQ7`HpJHDuPHRE z`EJEOWYu;*`nWyt|H|nQ(mBX5jEjY!R zz7l!elcDQ-zBzImWfaxY!U7YyYS??uFaegT#Y(6UrIV&t0Inf(r}MySXYXpmIC_Hyo{B7){)kw`(Ki}%qIH?wl?X@ZCO(`ZNk#-EEBUypln z;tLHoig<@e7F?*N&hf6*z3U8!I`a*#3@KsZdf$da25951Z>eW#3gJ^-iMxDtEkDmh z*A?E-u5*V^Q4{(qHql6ol7W%i*a zV^i%Fg7xtOf6f~}XSu4^@_4@>(2=;H$?yR7qx$4-RagM0Pp!a~S>%v}oKMQS^-;QT zt>vumm(Bfmn!RZBMBQ$U#=*L@ytSnu?>b4K+i8n*G zdS#KCBb7WmeYTP`I1b6N>$ag_iIdx%W%;E&hZft%&UFq}u_}Zc1tq*G%#UlnIQeaa zFFv7_+DXP6juygaH;Nex9vMlq)I{7ZyX{kAYz61v)E{9e5Rz;1rm!5J`4UP5RjuU+ zE$sCtdeHE-v4bw%vBOYftDu8PCEsN-08 zYUCVg*nLkd9Qm>}NOD>4)3b>io_mGA+MZ_M_l_Ob^5Jo|k}g~~Uys~ab26C1dO1v( z(W^_Gj>M$=yrF+5yEMtcB&YYw&%j#&m6i=%sb&tRUD~cXbl>1{RG~gBT{;>+TbkF8^c_TsnVs&mC9GP#GYH%&-DE4yZ$Vr)>r6hQiJUV zkua9)yl9KMyV;Jp&qVC{72VN#Yb_EZEq_xxwuCi6e&*5*`I*{hCOJKMX(&h6$pc~~ z&7z6<b+>Z)bxs2sI#jBmz|4c~_PD`i!x$*9F*bY80g5ZFx z_nn+S3gN4Yux{3f*o4xsb@P0QbltY^PBn8xI;UwB9LkCZy6#71rC8$Rzxjj&U?=DJ z?@G2;OS+V9Y8POBz>v4Tzz4Or0d1~We=KV>u=nB|4x&tYB41Kvry)vz0wntK_mc-)FZrl?O67lOPCfY{fY@UZwYrw+CX!v zpM$iI4E(Q2q6RwewDkRQRKpPJ$>69Rh~4pUP)sz;TPGcatEg4FG0`$~aBw*+=S4p1 z{-G*+_5#gQ$iXvR(_Q<*3+$!b!+}oTw$2Knoxb$u*#>OmvoFUTRXWzWpZ3T@y2Af3 zv4ZXFJpT0OWY*p=75$(PVoSTo)?IlG^W}7g>!uwg!^Hfg;USBKwD9CphnCB~R7nl7 z)Ng}Ax>8SA{@@P5*9eFFY?YWSd?-wJP&H>rl7BK{eBN>Xv0wzDN^UpgT~UeQttJld z`8sMNPy4d1?(kECD%az%*fW)0p~gb(cg8KmS*t_i=^+Q%tVrC>o)gNlH>mb>TUCyA z)mENE;_Q;v8V0Q`=sF@K4S#jiIoLqqc(?xk8z*lDZ(pAFQ)-d696I*4C))ve=h6*> ztA8yOHDiu58lVgbVy;%rR8aSHhrBNVK0#4db{+WYHD!{?JICEAh`YiX)(jW)P1|R< zmA549pwSs0a9y|rkUt``@xc@Cx<(#4lYpn5*}8qbEH10(;fJpG;!#sehu?c&*YqCG z>=TtkJyVWv!ttx5=Sy#;!v?Dc@fks8MJGX02P9oYaWF|92Uj^D>6rn_*Rq)IQ21e|bt5wNiqyWgWC$d!C`$24<|y*pYPsWDj$0Su z16Z?%h52Vs4wZKJQz92K6qE&?y=rXk{HnzGD!&;n@1mKJBq7;Y260XfY%EeOJnkDY zY3t=mw%bEc=p2GSJ@FyGN7;VMcB4q;d8}tChVXJjD0NLDSm5QQ+-PKU zGSXlMccMF8h$%8u)!2~HDvKcKXUcx}xxD(!^tgU#6}pR7V@yoQ>6D)|PVvs0nXsKn z@P|dJz+#;pcg%X}50r1DS06`9EMQ$s4vEipWYV7aX~k{>cBS={ZjqLus4`s8g%K$g zif^eZB9ZJeNsM0HM>B6H2ATtK=Q;|V9V(~RL<^>LXQBFs)2sdhafI(r+{Y$I<&Pr9 z{fx8wClQ+tJBe;g`GN0JLh#zk`s&sQGL(I$weO8a{^9q8UaxFcCAR4VLdDMf1`neY z5-7QjqDg^)Je4$TpQhz_R>D_psdjXjPWIAeP6-pI5bf7g+-03v#D*Emj0Q0afA|Ni z@AW5--&{Q3)1Oi;LM)ah+=o>v=jI%PDOORB^hbLW zn6SN$U4&EQR25zl#@uz7JA?UQX#MbXeIP@HTp(~)9A9L1?BbMQD%P2R2x4W?%zqA* zp2J!qv3CVB8h-jH{EU{LuXIMObC0SI!)@5=;a(W@8 zF}~j{?qy5TnpFQu*sq83cqsMH^Y4cBH*X4~_J(sctk|T9=hm&WMW5L3_F?oM_?tP> zpk4^8zyuKaS!F0d1cb}pzn8R#=6P_X)#`{ASmO53MI?X97J}A*Mw)zf!Ab zF6vjao1EM|TBb*`8=D`Mrf2_&`QY<~RrOm=rCpFGP(+LN55fbf?|$}?8dOl!#E7rSmhfWq<_1SX%X-N1?X;HCFhw`{W5hQl8l`6qbpy3$d2M* z{py0QJKU~U>HbZRHvZye{ls3(4^ zK-a00TOU^HvbK2!QChfjIPmWJf2m4s-84no*%pM7jK#+_=$3Itb1GJ)B9d>jWS`kQ zE@H(irn3=Ko!vQMJRi;vk?QL!bq7dC&sX!_U@zqde4gzhpa_g#wB$*%#@L5FDL=J4 za6h-$9WPiH%@rCR@>2Y@dZqwa012NgAKZP9G1;758#WY+Qe^eie{N2yVx|p!k!P?j zQP5H5%5fV&*Lw9qi#s`YIOR=mgyesY&q$4$mO(9Vzd0UVSTK(CHa^i+gl zY9-c<`7}i8_F+Fd&|3HB{R%R*kSuM-9nYMOx+(b%ckYqzNp+-qaDY!TH%bjV^>S8z zc+(lY;;OldUY+qjCB^PTuQa+i~YTK<`~#vR?( zZvEt~^lM@ta)*^fvPHmh|Fa?K!O*pKo@MZjs5}k(8KksSZ~Q8Rp^oORj1+w#9AP-? z2;Q}>?%eTbYwIi5rBwL@NzGG~E)1Mh7 z`Tb?aW=CTgju=7{PDa?z{*JKLkZvE8=AA^xriB1XtaB!&gk@{~WScap&6U8t#%4ZN z%pL)VA+R?i6@`#6&NC?&1KD39X6MrcQq&I>)=`y8mfy|tOhBa-Wi{6vf04ahnWQe*fVi2C7Fctx8E-x zBzo#LGeD;eK}DwmaC~(pmR>vS%ZQ+dWC3r`UhIF%oIm`*sN6QRBZ4(7TQdO;+HQ#;~e^dnOC{+5ZVdbB78;J0p4+pcH{nm;5zRA3JDx?&bz5@ zgEO`XaA|xit!N04PQ-;wYf2?t1j94@W3{B%_@WpaA4I>00yyaiOtuq1K2_)c!GVZAw^H_?EOE*t+Kw3$yR z+9F7CduN9}(Iw4mg!;dee?>a4k!2j{N_Il)l`yWy2wSr0CZ`3-8^i^CFe74ieW`=D zDa(NZ76KH-%l^O-@2&`p!VbTc)Zu)6%Bl3vo+!m?r70j%bCSCPw+0^YhLW}M-!WL&t&=Kwd zbiE9@+G1bBth(53BUV~*5EUI4S6E_Nnx!qI!s6#GvV z9(^j}OU6;(Sxz`AL5LpVTqZFo=Xy6$+2+2pY1DZYtEBN3a?8`53~$hJRTdxKiU$wF zMB4-U#rzYMg95pNK-)$rcvXCuMX6_xA+-rwF-992KVHxjM zjO@mXfuLB`)O==Qe)q!rJlUS=`VTH5@7mbAsDn#@FXH7~s>SfO(((2Xg$osTAaM>i zx`m3|lV2}YE&Q-iasNyaEz#eQf#3>ya40&l8Cs z8!M~sALe(rrsg{DG?i?)bi1YT0$<9{f7FE=Mt(p4YSWKk3A1By=E||@RfwQsKBGv3 z*Ux$MR?>&8=LabCMqd9mG#r0N)tUQB%J~lHA7@)aENe~<*22ggstq7s%)O=+d4r*( zU1aV`indfOngi}WR#n^xyFJds4i%(WBTWi{&FDmE+1T z7ySvn(zmkQdVqDMsHWr{c2xYB-7fV4R;Tv^H7U}eD_Z_n&1tQol$E7cLw|U~N6?gL zt>rcjnjzNOWR-LjaQB=>(y9k7W$vb<;G8P^L~plW*{BfDcvOZ=lOC0Az+|e!r7l^~ zG2SNW{Ti-}51RwB*i`Y^POajB-34Nxq#UaUko5axtFHZYW2_1aCi`8*7lSnFu7A`S z`cXxP+`ppEVf3%O7E{mS#I|efx8b(Xv(x&Qr(>mhr0!L%^ExfBb1FLcYp=(V8#Q;V zLY}}cJfU7}$oYimv;Z1cSxy2P_|^$1Wo4GEA%$V>$H7{c7u8OqbXluoFRN(XE=dXX zc+HABV8LEf$o)e;;|R{_k{6AEy{JNPp6-C%(UQz)81UScxXUk*%X0eif|z1S%7(?4 z4N)HPKb(0U=Otkc@xGUjov%{}s8V4XMm~EEGmIW(}E=soNWr z@!zjvv_3xT_2zk9yVCA0;n>vYV?*u=#Xhg^MYm{Cw+aeV*k`xcr65eme%r%Ni5`S; zl*Eu=oKCue>?DYgxO2L`@r`4ilaYP386h5hE2NXXW*k(?m!~<_nSGT!Z?HxozlWK< zy2UZ<1;rdB?JrMSxA}V=uUF(I-^;T7l>aSN1y)8ajw-zE1kyxA#t}Jpls=Lh*3j|- z%Mf%f9ezS3>l5zlejbyXh@n}`uYCd3;N^_?+8XkL6=j)(X$gwL#gb2zuPbo9Qc<${ zu!O2OV`(7``lMuvji9qci3w#D*;h?6PNiaMr=IzjsKCrQqd*(2Kv!5UD)$3(7wja- z*dC61bSopAtc?eA-r@?|R&W;}rW(2WB8*=z^mY)e`yxMLqLrJJdMy!>X;-Ca;)|Ss z9C_6u0=Gyg&l?Z(3v$xx4EyWD-eZaQU82HZpL+n>wj>ts&}!_`lqZ8aF3 z7J`4iyFOMXm0%2YAdb4WQdlV>q##v6A^3*3A`??W!@D;Cgdlh+={V#=>U5A++u?og z&wfkgM1PK*@o5^QgmQ^qp<NhGN5$>c=%UKsYKj_i3QsfPpD1Q=kDsNv7d%5Urxa3jVuNhqxn7bd50cVtjeB8fM z^}>%l*a!a()>b+=q;O~k`Vq-SZGVwe^ZBHNoO&nuD~aFIeYVwv z<+*dpHeM9oZ&40i(^iqyN?b8g>g{&V@QzMLz)(^b?j0?sZn<~M zF7z4osgBfxo~#Z+yl0$UcSHbVMY&=Hk9zY9HvsNB7u|~SigT%&TD64pbbZ_heh+6X zUepD(UF!NEN5Xh61>{Z)ZjiS-_rGB>3in7X)Jo-<62q{JzGsSx?40N^ABUE1g!0=? z)Pn&!>9c3kn}2N!3_z6<(kIxpi8e-s(r2AUVgnPBocVi7k0;N3PcS)Bmq^}ZK}c`# z#a;C>M%LXC_Fv6Uo9%V2XR0#dUGs9c+6B zyzqT`#31F{sW_KQHT2@eqwlvcsSD>giWq8=J{q6;q(^nG5+CBjBR+R*iRux!E+zml z!jN0jgp(hbh+gtUDE>PU7h+ZREt^T2{ar!wCO2~do|sI$;>4PLC!G&V8p4`ZWfLV~c|37*lgr{3T8~jz_%J1D_n!l$})AVw!AKAn7 z+m}&D^|u50qE8{jApSo`h0(u#$rrgxiFCkJ!a*M=E9ke-mW}Hoo0omndc(j3MKb?4 z)(@Cf956)x_!{>28i8Y4Wo)|QO6>GGucOSab%DU7L@+We7dunr(ho zd90n>-lJC<$eqN1SB67-OM%@!hL5gt{YvCDxJP6-nTPQh*62Z?E}(~jo(vm_0Oz;; z_K|{qKQ}-VKIWuQ0TV9*&;}y;a~PmWmz&)D{02?uh^^2d30H@Hk{DwviqIzJp){x|#)Af$5ls++Dc^zU2}E7^X0T&d^qL z{D%KrD60km0a~W#0H4cmMkv5MWIz}8yhk9Quv@@h4JWq&0>a3%1K|N?K{qgpkMSK1 zg?7N+8ofEjFwG0TzLE_AH0l^?N`9;Zu_&)P_ZVyWh;E_zQ6<1#xp(5aJ<@@<_Hr%tJr&2 z+4ebqsMU;Cif-+xYTJlop8C{x*XvJMa@Oc=fXYVglo%b$o+#Mg>#!LYhIIGzU zJ?L^qm_{4BH}Fm;z_C=}XE6USmAxVoiYIsVoNGU-nF1?!4!G{<3W}jB zX}mSs1W?Hw=pK)@O5|h!UxzUw0$+7oPKpaht|pK;FHAlZEWXLO=(Gk#b&+BvRrdd3 z?>*z1+S+eX1q4K-hzQb)QbYul4h9Q|NC!oF6_6Twkq|^snt%#|bft>)4g#SUfe;0x zcSs@vQbG&$%*B59e&7GO=iGZg-1Fs}n-BZvhGela=Uj6>;~C=_kNd1FWnIJmx@z60 zCh?SDx2OrA2G>fATb>`reoFR*N%|HweR0d@cQiIIOmt7dJ3ZJJ2PRK~&XVi5(x zi;Z+kZtB8Sqsn|3dsC8?j`1N>y4$i#&g!UTSarz`EA_W@Jl!V$t9|wF71rQwsVN>r z*^}Ewz#M+jGjezF9W!mn3OQw*pbf~*3h-hEw>al@tu z=sh$+Ko8=jjE@@C76>XTkQH#fTE{T{Iq-=wm27aZ{4ctvI?DnQ#bg&>uq=K&Eh*s# z=`wd#0*;LA-=SgjEd5@k`{nFVHU18`b_?TUWBMS-%tm)~#Zn+m+)gJy*Sg{KZ3qH) zKxN~h1YO<_clz^+P%MQtxWtp)UxB=SZi^{|o^0d@Q6EW-ZSJ)71``c;EUL|P2} z`O}ED)liT@YfA)c^KV5p?PnS64Q}ZwqlmFTHTN6wHxOX9RWY6JFt@1HnpN0KH<)Jc zDf>VD<-P*=WHkI%@wGcg%`eZ)?SXKkzeHiYSU^KnT^_H?(WM)?W41L+~* zNQca7wkVlEn3>ck`JbUuF|aaH8fh++rZBIx4YB-PW{Jh$Wecs3zHpdS3&_{~NH6|Y z{!?}CcEN=vL0TFa62X~xLp`clGU4VnkkVl2V7NzV4=!$k(A4LVh6LGbHwpBLGHb2? zAa+dmR0H6b-Lukggv_shQUlqTPzMMGL-Ik_L~#*`GRR(tT4&(WAztAqtm31cTm#6z zRBI&C7ggvH?|xQ5sjg}8xWBdtZ&c~9Tj~d146M<#>H(*ZMb#0kRBc#J zPyz;(GYA$`0bw1pO#4%D`Imz>l;HzRjV4|dhDz|l zC`HL}#~O|y*feApGFJhRX~jssbc_2Y(~OVL?!GJ25$v8bq8gFYw;zv(o zff<*lKU>9*;G7L4FeQlMP8k9q+Y0ijvb=SF?zGSVZcWz7)>XkxJPc>k3^H=;cO|7r znKiyYkpb%5$Nq-RvMpY~ZHSq~7riAKl|;gpX0vE-Ex>fonS6ER5757FTGZL-BQrkI zI|pm!Y3y7hmvVOde*Q1Lb=s+>WMV|xT_La)%e(j5elWC~e|pfkb6GVm7?`CEVpO9p zrzy*3gH>t6fajKqf2z`WmcO@YRy__fzY&$*?)OOU0A+IyY^fn`IQXSy+YGJVXW*Mm z>dW2q{5{a;CDH6=3RcE&SMYR7?@GE222|*NkrwUzeP(>jYi zWxZhG_}yG8XXuLHeuw`QVR7ZAS$of6w`u%jpXS065pc82k% zGUr$*^uZXe=l;aRPlbIlWtMSv*D^DTf{BMSJ=$qrd1AYKur zRr-dn4*)fH97tH}+(*YyoRL-mYWyj^Pi*pO>Rg`&-&_A^O`ZW)Wp@X~;l6Qo)%of7 z#u9jA%c$?1IT_X1=JJAZZ|s-MM)3DLPcILbOvqcMY4(G{DdrmO#;tQ6y1HJbH?B@7 zK7IAE)3yQZov1NU=Wdd@Oz zm1$!((8bB17DW(+OUBi9)|e(|$KV!Kq{eu_VM_h4!?fW1)2|OAT{5z~BAqFV z)5PiV5(>-hUkQ`*r%RH9fW21K3b;-8D5qJU{s+MpfFr6S?t)S#&h0F1hK;8A?isn3 z%Km2Vvw+g+YyIg2gzpj5SVOx^zTS;&^|M#d?=QBye-SLtjH>m~`(W7QR5c-q(meS^ zdszKbvZ%%z?l-H6*7WNi(iVPEMr8k7AX=qf6uGb}cN#nG>wf1V#)Dz>^GH1??jWD& zH7?1h0!}2dqIChw{5MJ8Al>%&hSqBU{y~b%17Mn!!vh? zqZ4m}4ONQcv$pkA|IQ2z_9@<&46{i{AnYrQ-Dl2z)NHO076(5Qm^#R8mr(v{`W0yl zq_MA@#r_A=qIZR?4T6s3%=VK4^Y|2F?L9U9bYDqK`?))Pm@EmZ+O|YD z5^4pzd(sx{!L{dE7Cweg_YexmEbX&T3kp(tg3575TazUUDbmlM)IQbx@WQQ63EKL7 zKFGcxxhabFyTe|QC$DLgoOY`dwtmBvSlUz>J+GN=0&KyuaGhZJrE9A{)1k(4?K1{U zAuipK8I@sbill!b+<#e~LZiSt(FQysw(T;y^3gt~sdMe>?1nNfQDufivb}QGARO2Y zN|EaLhyb+LxAS*3M4xmUn(U6>vkU$LfIf1|c&_!H7NadU+Pm@|f~*<;f~;Atp`%9j z`VkH4H_rn#yItV-{Do)Dyp)|G(7W>fdDp8cc($F0dJ@5Pf<*)z66e03_ZJ-;rlmDh zneV6!wILAY-(6yij4urtpn=e6o#+EVzCHP$)LcF*C;~|7Uj>~10Z3ah9*hB`CV)81 z)WUsSdP^JME(Bf82A#+V%r~Iu`55$SZGron1Il_GqiU<=Q-EoVywt@q_|736qV2lp zzs1Zc0j^M7h;Y#ze1h%&T5IZgX`(5c^un`y?*XQw>N;Q9*{=wc){s}&zfC*;*I~>5 zPXOxw^F{u5=VY_A-9S;*OR$A}6t83bH-J?RXKH^x^fc`ZSQzAgL1Pw)9CRv!#_rfs z-)cJGa9&1S`zmmZZ$Y?C1@WU0Mk5c70#;Qo|KVp9pjxI?sIV<{90Z?_0jOnv&_52j z^8i>Wcvd+PE*cp(1QnGywm|rWWwP_#Wz}X-?PkO>83uAiOAg4TcMw4;e&BOlT8nho zXaE(LGt)t|*VLy9G=twj9@&`D3N=9kigh6_h+oy8MCMXGveV@-FnLibUe86*hTPSVXF2 z>Ok3S{44&~iyP!_f3vZz!e3sk%P~1J!^}#>5tVIyE{k=iEDmFHvlgOca37doZ3DR9 zCr#oeX0F@6+s0%Tj6$JK_5<(T1GB$;us*$7zeixK2RBnfegs0)vmy=qZax4jw1A2x z6V3(z=i6A0j*W6bAzR6*TU6L_m!0_-&1R@N8U}KG`a#d|Dc-N_`m=xH6+qecESdsm zo3;gL#@%Ym80)PBR;KYzA7Ccd43QGO;3Lw1fR9nZP#B#FLRshQKcuasIzE)eQ`61xBSEXy>d{U8+^=+R3kQiD9->2KR=BEDxIwc!#i8D z4<=?#<{gf-Bi@d=R}9amwMO0qyyPxoA_0(;>IJOlb_f&~ca+?Ocs%)D1Rq;Vlc6IB z5l^R0fw3_TXaH_T!62-!Kxsl|asK16g1XH>MRBeQ|NgOQn3TjY3?*V`&=z+I-J7I` z&%dNHF>P1_01`AWszd!=e~S(7wT%LvCe^T9TE6V*oT%`bzS9=Jv*Jy!oTWgIp4JIg zn}kZr2PH3%%J&~LcdctEgKCZ_EsYyQki049=sLEfMVt=R&C!S~%AGI+rN@@;){{(k ziQoylaCZ%$c+N^d>oAvJ1IAU-hoQVtp`YFoA*WmBNxRYpP!rz1*2dK?#{HcBf^P#z zHc1Pk2Yru#-=0*ypaRec9BU0&ChtozwSz?flpq~LjtU(RH^MZ;&!!`dr+ZLmj>-Tho11Dile0FEtP}Ii;e}aA4eayJOhMTqf|lv{H5bx3 zQ0X021Q<3*)iAu2;AY>{FJ5qmsIAQYh!dlJhQ!JBX7Y_-{Dy3R;&VeMLk2qe(+vno zyK%@dH$+<(?f1g5#CPJYGRH;I>qY%r=hG-`#|XiZWj#=-~{#2=7|m#pP@Xn-AU%L;{^vTb%y1 zCk$osH=FVP-WLPM4T1^S(i{cp0{N!od3(yr$llFX+sr)6yep%gd3u7ZM*I*MfeU~V z*;k*yzI4^gyxrl&&O=%W6-eQ<5G9j>x~! ze#9h9%juqt4L8%JK-tLdyAQATeUkUwxOXd^Pmr+=Z$tWGCQ>yV4!j8kHqzSgEGryIFOY6`n3#>p@Qu*w|-rID0v2(n;{j~ zEe>*k-=Aw>bd=%2`m)2k&&ytenp`&4Nq3Z3>ILTf2>kfzp4`Xo&xG;Sr7$FU(T^<; zmae9=@4(Sk%JKC`!Ea^8`J49S;^Eotor^Eu-pjap_Q9Y))H)>=7zxYZ73s_`6@R-; z&Y*OU`3)rxKPitb*{_{Z6s!Y9gCFgXtSoUgt49+hB`Tgh+5{4YdM_Wm@1*VE@83U7 zK!*I$RMD5OQiu0ai3|a3EoMG6@?F82)2#B_QD!CU(QuEj^~9-Igd`>>G_)epPB2m2y-8rgQvFI0^LdZ$(_=B%oAY*}0Cdr!TJg<@ZAHdIU8?!GZS{oAZ&OE7GF zf$7Fis06z3ud)QXW*!widsHji8|P7ZmvKG+;I=~_ z8dN!(?D2Pj{|B#_S093gc@?geKGcRjC*d$C?l4ry{y+HK#*2#%6!+=r=@V2#C5$h} zV_&5kD?Tf6!*+SSd9s!0WDT=|{#eZO4=;vaFbC-eec)A4ej=D5!1VTQ=tW1<#^xk# zFo23Sq+&1S)}P3LUx152*E<*P_Se7O3V!-O=7(?J>X+H5mpM;-wK>?`M1#})3N%$h zp@N~pp|bGL~;z|J9(xvaL}Dnz)QRYPTJ4zrLM+yXS2h zZ)q$veIm(C7r=_D;q#iub|}SN2jiOCeB#@ZC(;-U{F6R9_i8$>?$gjBuxJM}Msx+^ z{#NB~&y0P|Reoq;y<~!@L1-;ew6e8w5MAG9g@bASvT8H1{{j5C)7WB(`>!jwnx6+B zCbkaWjbniR&}^dsxGh3hNyuN9`tR20y=fpxv`6httkAHn++D7M`*s^84%PqhT*g1H zn`J~FKR>BL@dRR2Ek|8?d7XE_cGojqj1 zBbjm}g9K*RXZJ5~068A6+w9P7kEm+4s{EFh>TGGC40|Q}$#<4mLB%{!k zXjD>>J;#W9kxl%2p`@0|akpvtTeo<7CN~ScC5BA>oZLaz3JDS9T0~OX{yab0R$*_% z2EY+G=58|2AYlp)Y*`9EGyt!c(Ul05*rEGM#5-2Wfp5QllFtFwIpoQ1U4o?ea4_Pt z)BBrs#U8=7g+nqmR6QiCuwKp-5B*Nk0LP)tw<1|@|`HI^q zK$iVZDFus5PoS(XC8y*{57lpw5FbM-0OMk#H54$VfV*(yEhSfhWKq>r2O~Cg7es2M z#2?Yf0mM8nryb-PuqA!=#a^inJAM)O2 z2R1deD|I-DB0JRTOA+y@y~*uF?}ojJ0=mel>=&tv$T`-jrzp_wL<;i4CJa`gJb!I% z0%Pc6;`b2Pz#lFy5dbE!YNIPhhbvVLM~xJ)@1{o}5b>!ca0#!RG23abtXn9dMXm-d zuk=~9Fx#55=}FyAg-1Do_^jY84A3W4UQK+pz}QcX#WRT3JVMj|x31Gg9Zngb&>Wjn zTX)g;IyMbLVz|@Y(Z{Iu_c(wFI67m%qJB+dwRxL@UED>UOSqkYdd=V$dR6Z{_By?u ze0S~EWR))-wkNq)^gC71T2A%_rR)2glR|B2JFWaSsDMB2X%5JhZ6rL%eG;roNx0wG zm<@`S0eM*)39`af#9Nt8K+3ip=cYIV8Z%6)#`3m)YXJhz5jJ2If|hC^qH(?$Khq>6 z$TUl&9d6_#-KCMqOp!L1Ix&mrSC^W&70U@4d@TDzW)3#MLi*{ShNDBt29xyU+pqmh zU7AiUOC-?kw22^pma zRFFXV_)m4ViLhDihz&Ysk5l>$jfnq(s!>xSCoNs1qk8lTrE%+Jqd{VnkM;ZHpWmfz zhuynH)nW;LWQHgzT7N}f)QjjhuOI!2ubaP&wuKQA65bPHAI6qhr!h{5r~DkdrmaDw zCoa_FU*Z)dCc~^~spro%s;W#t`|NT6D-ul7H9UxcvU>w!PJI+5B#wE-|`@$KE>pTm7yo6ntk zK*J7$TJ}WS3Se;GXquiZ+_&I49LJe1KRqI-cmop`qihrEuAS=K5@L~_{BxS~a5ZFk z1(2*ATl!zw*a#uEQT@E z-HTESrxNPcR}4Qs;rO~oD;&n8sdkccwyl$g?>;F>7l`)_vMu(#@O4oMPH9QzSNBVJ z+83_43ZUx9J}^*$SMlU5%!NV@(xqtCXG>O`d-{HG8+Ur7Jci9~zN*~+poxOh5k~x` zS(!$^3+zlrrcJpo5tbK;UcW8IhNgDfr7A__BM6?yv5$y>Hi<6a9OK zuUiNA*ubb)SGNcn(Kxn=b*zI}wAubf-uzl~QLIIC(WNc}iF+SkirOy9T0$;N&JAUT ze&C>~N|T{*O)83wVd?|$tJ>?myxyw8Nn0h!L!2y}%9iIvd_`7zvI_Z9;}yBQDPX5C zW|Gdf)>YQ$SgULdb|ttoC+YOXgZmgInbjU~p(SECqL|KfBMu~q{#fMsl(ev<1N994&&M8k@4?u)#BwC{7`-< zLjT!jp4m;_C+<7_kCH?FR7dzF-`HV{PmNKzK;EP&0JUEJ{|4e%-h3f z-bS)lUx0h!3s!2X&+2n?*hqcYN>g0ylB%U?7V$YF2Wuj%4ks`jyjPUT3^=#k0v04W zra~<6T)?@=U16*`n3wEs>5`C6OC{}VrHU3LfsYPdCw&s<{%gdeN_U8q&0DRz2-9Sx zptuJDhXl>nH=oFWnAX5@H3vV8L&xpQI~lVvgE06BOl<27HW-Snq(z})9%1=E3#>|! z2fH?H;f$mmQ25MuR*a%V8EO0^HywnBR~82g9F8=6{t58t{N_RAcLfT_N&(Yhvpiby zKl+@hsMYcbK@hLGpDuZoH(xpqp#~AXLgNvdcRi+M1wFPs&`qAB)1@<_v!ZjLbDzhD zUbO}x;`MW4LFhC3J~zHV;h-Z|wu^G=Ra@|jzh1g`v>_A#Ue_=GpYy}(=fK8bH&|da zlyBC6k^w!*j*-qOu~Q|d#O`r;hhC)sgV7i9Ug&WpDGqE>Nk8)*{{_&L!JIyM_*c{) zDiJEP?yh(oxG%iCF$|63P-|4(es!nLJut41n7I<_d!r-3$g8nf(lC)6FRr&&di2W* zt}6Tu^^Aq%|5{k9B*4TJfULK~=l==v7$;vRaxy^6Q|MpI^X(Oy*U;ZeWA^KGgC_9N z|NR=h>T9|d{#YEe7WvhsI_%Sfyct&LGsq zfiS$UajoV!fPq>Yl$dI{|4?F*m^%35O%b&{11L*ys#R9iJ8?OQi4MWodMc*S{4tdy zMw9DtIL{)#iN-b850N4fp^e4>fS&MNE5hL#qsE)2bGro(zNtv;B0an2Q2=28!Pjhd{`>Y)jS;6h}8)Xl~;)19tlZ z=jKWQJFgJ%V@=fB}(dEN`e`nX^Q z4QA=d5Fqs0Lxb$KgbSiXl$8?&0@6gFm_tnaJl-|lGod=bo}^$CbwTL#wA+}d>BM5% ztXAM`E5ziyi0 z!$u4d%xoe0m6!@xAKei^!e2iEx_*#HQDnMmAnRH`L;K@BZB)<5wt@Cx`^|0pRM{u~ zgw3EKsUnkF+p-RuAR!HCw|aT~q*Lmv6TH6w9`PGnp>%rD7AZOUG>BljRT?jmwmXnx zgNo+u8p=2552x)Vj^klN8kGBMoJX!@AkSF7K-MTGxSGLv@L2|^CMhbjfYx#X4F&Xi z0;mObxV;w?NccSC@P(RRB`WL$DLjR3e4>>ISmzHYZMrfKI<^ef?fxuse$0Qmjy@68 z9^sROit60BFh))lkCJRF-65O;ukrv`gVWKeYa0S_%iel%vr;+9ZVw3GG?AskoWA~G zjBS>_)tepd4pkAse;OviA7)2`Y?A~-GVdKzV%OtJ&*x{WJ3z26^G4*4%0+{$LmJC!eHGmT{8Y{MXrBXAny;q+0 zjusE~4=Fe(K8tVI$P#gqob;Kq+5G*JHTLEv=dTB8)GMlh?2}L2e-lY>a+R>~Az~q3h{C#nRKa6J6n5O^Qu` zx17KwnJ3+nNxM`7XwoFmmC>B50a`Uz!`!;oz~fz);>aD^(Z2MVs~#@%+=OL(uA<1_ zN$#5)P$E}N-Hjb`WZCow3$bF#Y$Khif@cx5V?pj6K)5#mL!~g~`y@z~*9`Pta}lbf zH_F7OCwr|ySHQic@k)48Rp^#^=hfmn{y&kQErmqwD3|uVi4TayURtHL!Z%+wQteGE z49^2uul?d5;6Lop@35SMYmwpH8}3MiP?^(2UlG^%A3%jmp7qn(vJk@h?p``5)KlI# zz3{*{mu=wU0S9qbjwd;cahC-(>L2yp-yK9a(Ycr5EkS zu{n9Wjo~`u@juf&hE4>X-CjP&NKeO0Hpd)8H7-C?gcKAm-T9`t37zx(?cv3IbZiUhLCh zC6eAT1>ed9rPl@p>UV=fe%%CZEJs(^G^=JxzVv<(N~=}$H8iWMeZEo181%5SI8nnl zq&|&1OEorU`J)ZS@EKBpZ{&_S1?3QEKU#5M?4WR&vv=i`8cNCJ#7dUW-q_S6vRBDl zBNe97koQyjT9+y|R93aWe|cUa={@55?nkIM4quANd0%#m_;&(86JO&odrHAp=W3s> z84UNqYBY?NkCcbqtTE*N-H&B=x%>13@uR*Ricc)=HZ%s?j7F~|SY=}ILm&QmX3=~} zBB1Gh;3)r$gxzc5D%CbUU)<(~9y`Ybh??v5)ffbj2e%Lx_{%VP1 zZceny_n;p>H=Wg>(&qJbJvJs{eZNMRWKiD#D=S}?oL#m)die?um&Rjhh20;~l|t%k z2d6}QZVPP?doDcEI|36S5=@%*O*u4;OK-vM`*>bN=brTO^R+&lMHd{YEKDH;=e|Y4 z7k&pkOAk!-m0pYQi*DcEPk8hI#>+Pe!j-D+*9dKjOwX`&4`oUr@=Wj3H4i(vbUqBv zel2J310B|i0;g`p3uunrMyFP6>?1=TcLi&;Tyu4Hj3}&tw$^QuV9xZ|0*q_X=OSYd z{QN@9My(+`Hofj4&F|N93!623wJto-m;W04jTBO2IX*Iyb)9oqVg%X9J*cL~5dl|sd2qkeO328^c336m-?}R?GBJ0dl@@@RhBa|$k9tiJ{T#UV@omv@` zc++7)W;n_==^MN*hMUnT>uV&Y1tHzQgyFV?nzO?1t@i2J@^*z_ogT`Owfq)f#8$Y? zdy>}(aN3k5YTn~)wSV+%c^`xSsVF0-(Pvd7pm~5eugyU`|2C@$!uTc@jd=Nbk$->B zv1=p956&Yrl(*=Y*3zq<<6V6vV-%EwnR^4IShaiO2-5BD6Kqxvh{xtha5MZV&A07a zrm37bA{r1(c_t!=nKQP1J{s@jJ;K7Zm1F`}m_Q=)Y~k(69rbZJ|62c{t<3@0bFN>{ z_$o!pE;4t}V>9A{mfQ2Gtrn%XUP;wi1T8OKPKx5`YMERhxYi9j_N6B~^%Kvu4_l^H z-S`a1GB6~>10V6{@h{rE^==nynrWM^&+MB%Ht~G4x8(WkwbPJ0cb9U--GV3`ZBrp- zQ`+jI^u#wAMHG1+Wdh?KX0?~CRYRQU!f{NvSB<7&bVei@QbyYsGVQnQAUsZ4B z@9{ZCYf4Ynnrel)6#iosoaITH4lDQ-%J4!vivB}Zz&YW@8p;9RCe1^=Cm$jO@JO-` z^CxF8M*b=*RF1kOX!nf#)wLec^w9TNlxoWKSW0_68{ghoH->z-iEG+oUj+D>mCP+! zyHtVM8PEEbPvz%z9YMz)_Z&M}ELRbwcrY1B5Z+(6iR#RZ68tjjwlD?A3HZpI&x@-Y zNtnWkJY%)#2g5!~6G#td?Z69A3{3&@m5;B>_ly*Ln&wByQ|@Ju%HY^BQIEX~Jw)f1 zlxpvN(8fXO(&ahfIzOI1RZk4opq{81$4mpm>c)bHEaJJf^^?6c6u)yLFWFP zOPMlD#6|V?uS`r_PS3qqUV%A`8Mn)vQ<_Pj)0Il@gP5mem21rf;JXJ37%9{+(fJVY zVSP-3r!vCb%s0~%$`pykx`+Hp`nmJVLz!g^Cx0|PFwWGyu-@YS$8qe>=z1O9;U&Xw z?f%{Lt8M}a5~DJbFq3N2%y>uHaA08sHG1tQr(@VTIwm(yABvyWrcrzL*7ncY@`^&n zF<5#XbRJO6-q<}kN{@LEv-~- zfJ6QtZVDKGnZwaj*7H>hWYi4&^0d)f9UOI{g%0Nw72}xxesT>S&gZ>3bBd3>lPQ2k zK+}i{WJ9jP>98hpses_5`itPS)-KUflrb_iFtPd>bFWoTL+|DAmBh5#^MEZfm;?mq z6V$)5DHj;eD8-VByyg{g#6B^ycXTohKfWN8xS0BXiEcw5&bS6L3h7a^K?G%jcq`kP z8EvJv#A9F#Fg`v_;2Z$ezJdPp#7+>&34#6$^)M9;-RiN&EJIIsoL zS~#i6#ny7-gi@@E;_Zi(%{If=s%*{lmI8Fkek5p$vzn~++hpXW8tiLD*>>NpSuX|o zHt_0UinteB1n5=9I6!$j=@pqycIfhFy zWXiSHH<^l5nX5{n?Y4O@?@|Hrv|!yQC~V!ENRukgJM;DVWd85g3@_+sYJ(ehz!0zuT%VijUvgYjZXBBbhl!(`}qSf7- zzOr>XaUH+;db~hayr92h;+aA0Eoai>nR;8JsEtxvuTO6;!b$CLhZ^>^01T@WOc06sB2)KJ&wq-f+u2Kp3}v8c+M>v7+X;9Sc>3VYUsFPbzQobNL@ce`=xQU{wLv-9s8y(*-Q1axf= zVhZGGlHyStS!fJU!QlYhV3iKY?eEC0F=wYxBpw|OnMpP5Vvg)-5KU%|ZzKh^53?}` zcL}{BM|1!6ibmQrfU&eA0N$k5_eX^30P<)c2lf+?6QpQR9!A97T=CWPbA)JCg`;T- zg{LTx{+0wOr^Q4lO$U{L5C9pR4>5^S)i?%C`5*Ei#YZ|e1Q=-yt{%X-9#5$56QmX@ z?fMI=XTx!#3_}!40Ccl>y!AZ>9+7Y8YvLCmHHXbNnt_nP!*iPfpd?n&Nz+Q*X&|#00Ul{*C z?r0VMlmTZ2{BRB+#&MBwgjH=R66n|@k0IUThTWe|EIfOF?ZNhJ9ut0mB2%hePYrkb z)8aX`7Uf;e69D83%Vdp7lN;HR^?Y4K_B+X4FCN$besm*-e6H{B>B1cSo=U1;IU?ZV zj}FbyoAA8=TaceePLy>V9i|c$YovPo%jFyWWZp0VH{`EMeKN$&k(85BxA`@f&x&dC%L<9DZd;J zI-NYyJ_NwIN@&Aw*YU4;YH?cG1pyPGCHlypFm$wA{kB>mK;>V+n+R<-|+%4fN9G{eQ4>719s7(xfLZFRrnd zBp>k&1Cg(7Wih8~EB!JNs@Wv~ZFgmwu6D2Ix>N~-jh8(kg7u4l0>~tcZ9t^G?<660 zC>fLvFaP#?cKG@DiS3w?62dmvE5N-b0^pBpr?%RrD1QO2)Tw@PieZX~PjE0v&R9nh#=OG|(T|pUInEppxe5>i_A{dL8o|KlH$YRc34oGGNjBNZ6O^ z*b8?%Tsenbc{WsQqbTDDQoPIIdr&@d%g`|wL%2?LyxF+kSCUEIOgtLd-)%_5eGWM+ zC9d~3Fk%DNypMj=ErlIPtnQtkEbb-XrVh#i9I8q>T!A)2X8)I&C>9r+t)Og61%5K5FE z!Z1gF?Xw-9RAUJ|RROzTZ#&xQHiNIGOX)SieK+8S+{mStfRX(Pg#%mnVb#Ml$%E(y zq9!^Axhk@3JK5Y@v&KJoe{X*KsAgojP{BdZlrTlHE=u*!zI{%~_fEWk?W6sP6{I%- ze1itYjylRHz$T{Nl@*$)lfM>)1$@`fEn37hDH__+z4Bz?PE(+FpG_ag7H{DoJxuML z-a*gFo?fFtl{u&7@gRk;S3Y=aH&Fh*LGH`^9wv!CwJ7Zo<~EHmb+mu%c#HIADUKVg7A{{ULS=Ie}`r*?Z8ad*o-sx|dLNn6|7sO}AT83cL2t zjY9{H_1)cJai;w4z<&yi9RM>iLE{6@St%~$xX>TA{l@PE$VC)%Owzzi?nWW)q?>$;Wr znq0CqZdhEin+Q+(Q|+kNEy(}hT^6X}B|#F$Q;5$1YrR*2`LIp#uTbT(BpTCAOo@Cf zb>uYG0!pUfr-)_P%>R1xf$t|Esm@p-eO%pVwcQ|eF}vha*#nN^XZryK<2A&Tpg%{E z(q>mg0{kl3Vnf`tVUNH4wKcGS(do5^Q@UT|bd>J97Q~p;LrKVbAk>*AjK4K<{2oQz z2PNJv(n=GdUS*1;&5=^rYcC-`pZyM{@1dQs zfPy@J^h4Dkh1&7!f14kM$uMA{ebpWK=g_dxLRuc&=Zq*8X_(n-za!zw;dEcXCnSR2 zVZK~W51|bn2fFToUk}B0A(tzLBsmQaKN1sH?v7~fv^M5t+f4bZVA0V$OW zsoz?{93u5e%EmFBMgxi=1Lrb|-z?rjwt&LVsbsJLk#>A~7*J*bG%N)o{bG2#Gl8I8 ze0|NY^a%2(Zg_%T0}WLBy{NE};XC^Is)w0zJ{wRUp#j7ecVX*ubrO3U)$ePlAuJjD zqgb<0*WO(;{AiF_f+JvwrX!e_g@ju9hc$@^$_bG27kXaI$~+T{l20|fWK(rgMSCRx43PxYkQBk;-1c0 z+sk_@T(9K{)nodk&k}bkzgyikcosWqj1IuRvzx4qu#2<~U!S@jC!pyI1Zrb7kD{aE zooJ~ysCV9wm)L2kay8W?yMyyo5-JZW1EDFcaST_&V%s*z8&no_f~Xhp79t=3_ufmm z$jLGb_|bkEDp&bG0l-mG9BR6kgq(|%a(>g>!`NWaJkupqmL+6ZVx8=z@XH(^BZQpd3D%DDYln9qM;h(QvuAn?N%#2Kov14PGH@D5o=uvQ+qcmdmChH|y7nhhxRZCt z_N5b$87_LRBytYzo?35PY3V4j&Rk3J`;of(IO;uuDcxBGZweVOXvfknDy&NF3*Jnd zxC`LL6gld|FyHUg(pS+?8$zdx)smhuqvi8OGA5fwWu$qA!$}UhLmR5)C;R%A9b0zu z3%v&4(<0*iI#x=yL6O8nHvRckqd%G)f^)@tSZj@Lb-&iASUl(*Y0qE#`3B!0bL}jm z5M48%fQ))dnG`>&|JVR1mCEc$wSIT!cCX$>oNM6bl+aFP@HcwqScstK3@^>b$M19h zo`xcnMRHCa5y-!CPho2&z)NuBn^6J$+eJy6la)!P0SK}LE#@Z2K{5^g5! z9pzsbPQ~55`4Vmw@$h`Cqk{d>o%%QJJDr<5saqy3mKXZ$ z{S{GdJ~~J<`{?fy?QwrnS}MX4`mDx7BpdPX0tOM8@FZ4TL)LJ*!&Oz4xgUMQVoQ_$ z``7BFhAuS>oW$!o|M3T9dzC{oexqgRUxNPFWgb@RJg zY(}qY6jIJLK+ZTu%IR#g}?~eh|Aq7&I!WESI_m0OmC6G5u>`dk?S?n=S&yI>q%gVA`vCiV1H+*Y) zg_D@xYv(gw<*-M?E=)QI@}+~4_j|FsVkh3~b%AJnz14G7&Sru4Grw@9Q@a}1;Va=1 zdL&)tnY3B&@eqyF>pxsAyRT`(!UKA`(gv8EPq*|}f$bKTcf@!u+n6(nCj5A=E< z_i^7O5Rq2-yxwkzI(%H}caaxZ=kdFz9J|cb{C}A4sE;K!Bv)@bIQKNB3C%Bofm2J8#wTyhEMFh;rz|$Hvp~dW*>T2GHcvdG1E7u;Raw~ zkMe8wt*9>3uZvZBtt2N3h!AbRDc^H)uQ?jDj3_L*dO1?r!Acpq0z<}6B|W>p*Yu&Y zkwT?|UnT^zVP-e-;W_^B2XejS>Sh7Vm$fS3aqLl?3?tTqZ9(is?bDCB0-s#ZoyIdQ$spJkVS?5>ZC1 z_|;^|)Q%H2an*WA_WMCnvQO4y551Vh_So2AnMO`~vGtcI7p7y%L|d6OS%$q6NXrz#IZ>CedX9H+_H9>bHP}tP4iF7%!5dCK@K@Dv>PfH9 zB!(U)o?uQ(H~U!h+GBTXod1P~aUPK-uTbpt$x!k?-NV6}{n`CnLASU?=EJV9$*6OZ z`;!l;cW@%2rsjf((kU^~a1;OAt*5*%+Mgff0=DR_j13V49+uni zRs)qjCDL}a0>-l(!@sbdwM9u}Hmdd3P>GG-FN=6pLIlvG?k@b4K=zY}}o`wwmNjA~>LIX;EP_ggo~0O`WQYmZwTUlo0m zr#cim3WD~LKNfN@{^t~x4@bO`d!0#xNR}fp<^9FpO#Y)JLSnASo+zC^qxB9*eL18OhLJ|{xB@gu$vb|6V*rDpM!l zZ4C_zF`Q+lD8|-qsz;XyB4laZh)#7Lk%tk;urTVvGLWjGo~NibofixZ zqu3=Pl6${(RK4RI7`3#M|FY@ii~71`^q{)~jXF4!c2Q*AgmTC7HB;7ytU={W|Mg1; zr~wXcPAiA)UcoRo7%c&l82x(mUrWZy;6c0qr=-{X_MbU#Vtp=nTxNfC>_pMdMj)~a z7xGq>qh3zTZWHz6cJVst`TF>_p7c_YSZ*gPk+d#QVdBlV{oCCC1G*Q=W>Dd zYFdX7+>7cM)E20|^lO|Oe$nDcL!*(?c_Q{qqj9YFh$XY#>V;L?#!jiS#~wW304j+2 zqr3Hvi|vB>K-bXwA~snmJwwY=SC(W1wWAJxIes2v&R@`f73Q{YH@qd>7?-Pgiws7r zajl0P$~d#nZ|8aL&Us{-#E#y%mMkp^NU)aOmlmY9)ax~89Z+(owNtk^cbKdr8WhFy z6-d_s39jQGcRbTDulviiEsDP1f7)V~uVN^gP9mS9FXrds%l*AaK6y0kCu_gJQLgJW z#rM6B2Lb!>+z#uV2GniHd%sE)B|XE&W(X?1PIL0rrm#$fn9zy?PB&Iro^f?7Q9$#h zJoffySCP@X@@9#E&)-jr?w29%=&c7C8c~03&j4{yzx9-kA+9%ZGrS;2eBVbPcFnnvZ?aF24}){fi|eL zIX)9kad$0f%@MDDq{pRb-RkJ>xi}QHEQDy6=~V97or#sNeS3JJiOwjgIv}yvRrZnW zEf$^KK1%bvb160|vHiuCqES;N1rigbZ{NvY4pI|87ur59@%^Xl0?e9InQriSiV$1} z1cA`E*aFSI`j?mcv+wTWt3BUL6%8)v!dg{# zS!G9uZ3cg85Eh397*{*sirSZtcqs8GfYNy!z8_K;CTL&%QGHo^+n@&u2$S# zK)POKzWg+*0F}#0+H~E{#CJic%XW!MOrNFEO)IS(kKIl+N3$H^;zx2762;3B zMVz59-U*ZjOppoo;qMuSIk^t|JX{=e`?}OEw$%4NE;`A7j|mpv9%0y{v&h>A^92E} zL-dq(ILTMV-8H`ezfaTg-&#A*a5&el?`uJ#M-sh9528dj zdL2ef5H%u*w)NhL-Wk12qDF!cE!vO}WdsQlbt7sJ#Edpt-gC0|{oL>I9`DEJi{luK zG1s+bo#**q>;GG}k4kBwj-COr(W9|5_hpp?3R6XjqRzZ2h=uBg$V5(HT%}(=x2bLD z^RjKMmlpM>W{EFlgrk+)uoM)jK7+&fVAE>%f;Kf*xvvL-+!1@}J06N+#iu7EU?DoL zuw7+w6DEbOZKF&nr_%BtMnN6eHXp4#d=E5vv=VP`^XBvl#mxS>>8wn-2(NOoL0Cwn zSnQ9=#t(k`rCewzYit4gho&9= zx!upei7O_6foy7Zc9QluF=SoxS?1o`D~PwB6~E-Pi5yykPL^Lc<3<>O!dUt#`GCkGh-eLkIu_57XN&G-6 zV^o2kR&vF>kN-r%-XVsmyVS}<*zMY)_U|CAh|qVG-2>hG;z&(I`oB>`2+75z_vPSf z_u;E&Vtxj~3llxfFRKc6GyNcIdS4`2!k-(uE$S>4X8alfyvOn8&^``rdaUM9j$P+M66(S9~o?yzqo%i zdE{eG$LtGFI7GF0E+3CrK>lS;(w@t#=Q}878cUq@ke}9E}JG(`m8M4;tKQF3# z0^j|6O{5xkfG6fmH58e&AyP`8qt-z(P1&i$1ZR+-7~TiKYJcOo_T|)0Ym1W;$y}-{ z98`~G{yEKzP)d8@c7A}OY{Bss}ayjsC(wn_XP}JGK#qP(l-pjud@0C|8QiGh5xoKG-Iy*d zF82_ae`)zIxvgj3ZLG_DJOk)|jwN9Re@@$+wclFT>R&M)sUK7zt>0d}ydYcQ!mhJg zim?2%-e{dY$%8NE&T{#}|0E;J=&&qIJ=J4Yxd9^RkfIAjOs8-gy=e5Ggk*sE6F^?G zqQ~ncqWckD4Ymgrn`Sv@-(Ci8&vlD8uu4M1yP5NwfnQ}!8=}n3q~bBUlfY*Ligj0+hsK3cEr6JOvv>F96y9XU!^tLFQJYTLbsZlc?*q72* ze`2dN_k=rfNYNzT4(j77k`ogRYBZ-fzjT8E+@E$#wz1Y#lz5Qntmao^OiHbD!-cNe zty`p?r;M|LbHP^JHhDPLJQZ-s{8I}5-}IfM10R2V^r^=%T*8%y@Rk-ulhsdTP+~krr z(EJU261D(OYj!uZ*V3y8pF{#so2Gg^8H#bu5V%rw&;CaoX=MUOZ*mI`81*g@PcL~3 z9QsG{QF-#URG=L^2Gy&vi2cV0&Zl{aBSdFe|`WRmtQeprUNHjzusQpp}E~JT!!LfFTQobNgcY(YSg#K-}t` z1-3*=DKDzfr+MEpm&;EnMmM~?jjH;aYE;8)!#C$BxNKZ%H}A$hL-C;?{uypIV@>wW0Xe1t7kNO6#QAY?)^0YftnYU`K1*P567JAj!-v8& zHPz)Z+9jZY8r#~>sl}_rBmHQ223+c?O79|e$OXk5Vw(7)qwFSteN?f8%&?*wnErbA zVyC8!a%x2mU+cWY-zUC` z2$Xbsj^H|kyLN#Yr(1c!_(W)G$y~xHs!VG|?s4SycZoke8FNkd;RxVPcMBWeetYT( z>=(@~BYQ)x;!}Mls~L;#O%q<>krhef&VQ$%I^}Kke*cd;L@Fu<8ptvZ5_=7w6q>!p`G@XC?4vi9& zqJ~s23CxI-*z_PZnLX8l$6l@&{ms=m$P~DKy2{Wkx0jQ-%NxW=Kx!#0U8`Mjnf z>L#J=Wk5fJW0T}YNS}FAiYF%UXvVR1s`Ro9(xK*6g0Ma2!h0bVT-KEy$= zZ84IBb((d+(P`r!J+xTicjH^?W5KnG*Kf48WBim5%8LIbelb>Aw7C~I zQ;}rrt8Sqm%Cm?}eV!!olM&(vsL`V*Y!_-xf_zxRcA;RiLLL6*7e;5Jp)0^{dgnA; zn6hKm6oEcG1WcB&@oXN{M^RLfyNyW7B0tuwPjo9CZLB|il`RR$vqu7jrl-IwL2 zD)*B2K+r=4iL1*p-#qqDr5S!CvJ3d>8>3CtMnw$1-@fi;Sih<&@&VS6I0Ll)DSn?x zQBukfnj` z{h%z*Y_2Z?sMt5A)e4Ea7Yg*4vV|dkZMbH!!7iwaxkooN-M66`{(^XBqV1MyQ{l<( z8`lLi@j$DMOPM=$T(yAnd68lvle6(17b(zf&jhB7R4I}kuj~yL~8py=` zXbv)BCybGKDH;afeO6QUi0I~%mQsT3l-ACHaYpQs%NEBo+LjbpB!1rc(!0%zHsM9j zrKfjRW8||IpB9lbpY-FTVL#^8=!3i`S|sI}3YZX0UR}G@kgax;iMy(yoh<;Sz@f(?dx|zue-dW)p74` zHJiAB2aKq+`RtJ2W>T?x!`ufAOcEDFp?FiT*6ht}Xbx3m_Q!tQhaSR>wvC+y*KqC% z^ibCj6-58wm^7emHG zzM=^xn6mq>e$CbA3l)<0ofoZ;hUni-#qe3v+K|wTH0gx1ik)pxV<|{@VI=ppf3GOS zwLFF6NnSw3qN+4Hczispe%+h@V8)XQ{r-^NUFFWwu&y+^ZT0mu%VJ-6yp#5Z`9WNH z?((OmQFPcF6MdP@lW(n*FIEwuYBC#Kq8 zc;Q=%jL&#FVW@dt;)DL=kBSrd7!cc~U3K0@Rq0z?`E|Lyz*?YrfBu&DN6_!X;?LZ> zU-tfxW{sXxuZl}2hO_@e06pu##;j9>&PVaHp+NH0bBGl;=~E(Ur=aBg*&iNH&3cKP zDMxb=&?{cykd<>ojrbipa_jpZTleRs!bmD8BVn0~1OBo-KP(^L64BFdtrEu|{CFaE zFkVD(4!zzZpSRU+n+7in4=y)d#TKg((ulYHIrqjVmeOSPm>h&raWmqnSH4`Wf;@a3 zOuR)Mr?m0@o|hr4WWV`fmfvYfxk_muYg8?>mGo}^5U*1;%MaJ_kaYm0ItU{Yw%v=! zfBz#-=Xl!!c_5=AJ9`jxqM+=A=p^43)T+`Y3iu*2xy4`ctty!dg$c=&n)MlRz(!=X zzAt*}?X<92_;hQ0Lwh+m^@uDIvem;?Zl6!bBpaNw&+Hr+9*wb?xj$Vv^WjMVcO@&^j+q~vM?OUK2 zl&y3|gk>t)mod_%%r=QWTRG2@$L=Yj)B_hPjda{zenWPIl&$`DlH+fFV~*9>S0qv* zs#6M~>DJr1&(!S=gzn?Sy)XUmV6#*?A;KgUMkbJzv=b`(1o~%hmyYk*eB7N^?Bb2$ zJ;fRoJp`wdAe6Sj7cpPl2G>8Xcq=1|~2Q_&H-7ON3#CQY8^$eV^_=I-B>y_uIG({H$dz z;6U9CNIxoP`7_eHBP|&R=AwipNod=nPZ*YBkDx{Kzl{-_N>||AbZa4%v}xJ=VZAx; zPV^W9)FS4tL@&I=@#b;Tk!iclBDzA5kvyzg|2tWOm*Mbm zJu=FQf{5gcC`m<-PW2%;)uGSxy?(~)IZF6K}+)zxz+RPqKvC)mXz%3kz7< zXJ`2AhVSYCrE72MoTGvVb=9Dr7Q4i%E1}M2*$54LV{Vngg)%OreHMq9Jm;fZ3oJx2 ze2aD7=@3M4|JI+=t`7Z*l1lvTDQvH*X1I8AYa=UXwpuc51ALC2x~I1^G_l>mTEc2Z z#~mla7;JuYEF(#8xY}SI{46=cJ7gxPy5X3k7Fb*2HU7>HF3Y@*_^b)9y39|Faq60M zHA7F$3(H{h%(n%-cxI$l%L89G`vZOY-(~x%=qy7RBUWqg0pk>UNcnjUP+U!m;p5|{ z0w1+9s(ide&h2j)S|@EguQ*hvjL|h-U#nJ40YwSa3oacw7ZAu3N>PrVJ@`y!Jp^Q( zWD{)XAOt1`d}M-Tpz^TMbGHfzB}IyKYd*TtBy$$^1NFg1Jbl+%5|ppXjaKmK4}(-R zdfR?-l-NSlf1B}WLlLC};uE8ZK7TXBUKr5s3fBl>yT>wC zZY9BMA7mZ#teivL7m&spS3ivR+$3eC;XFuL3nYd59L z@3!%Y%)EGAth@-a$x0#`a!Ea@7T6=HZ*q@%WL~cSwC>;e@@tsuFJguet) z+H9Y;*rFs@->mw>E7o5Fw$M>-Qcj(8<89R0q_GaG|3R(l543*jMk(`I`habze9DIR z7vs0KLpI(WtE+a-wP1JlWHEgLRGP5zt6>o5BJ$8JmTnCfnia06SUt$-dSJf0A?x9T z#0*Y-r?ZkKzK!2?VGtIn=sL-g$}w(mgIz7+?LMt~Bs(^EBzBg1CKvGW4yNvXg1_Y^ z=336Pl>0lAnuV{wbR{){wNx1`M;+pN2bjxt^?2O0Wfj;ze{W#@c znWdd3$3G!ja_^@THG5$gm7YuzLRS|uHW(q5toFI28Us^eb8 z@fn9*Rf|M+q)#_;Z5yZCFnlvzqH78z=o@sYEirNqMcq~p{IkNGg~Ch=tK4=1=q1nsy$HUR}@@74VdfU!q-iy#`h1JPZ``u`~#E4?M5FRaVMGlBp zN7etexPWlTR9u}(Y~Z)5=s~E$jaz&Q<=F#(6lmq;?0Zk!&>B-_s1{iLKe14?Q$C4w zUSsumPVU+w0?!q1UCb;b@J- z6x6Z8+kTzUKh;AGQ>R1mJbxR?GS#t( zhrtsbN^Fs^eV+!mwt82a%Hr;}etqJ|%QUUD&ZV(w>4gvRi2V=;AJ{a(VjuFvP`Bw3 z;a2u&VPv9wYL@=_9rRG!Ge2~WGN&88FE?$-_ZpE!D!=D{{g z5?KA!Sf^GW)P0D_i34_(i+$I`iJ2j}t~pfFZHpT|&4DF_%k-~xrZZg(;||{6>wuqH zk3)A9TT++Br!yR-utHPXgv8@shO8C=Ls0XDe{#(^O%xVM1Cq*EQQ3Oyj+x9uiE~^R7{ae-9oKmT7K(m4K#>IWhhV zGw4FJa8HpDtp2kG)uH}tw6WOmS(whw>-)%p-@fmmPqa5qove-j-8$cC1}jSq){-(T zwY#!3RWx>Q^Og6IDOW&M&3tZq`AFaNgG6zREcC3)NMUU)f__n>y0;+QNWa1EdU$zC z#=w0zRni7#zxqipkYfFYhSUGMgDGh>3f?%MAJa_8(yaDBrLLou<9tWu8(sXkW*C#% zBGXTdj>+pMJ`p`;>6(WyMPA}k5WQIFO@*84yvh}{ zN*=X$nMdQkINew!I>@crCkB0I^I%6c@Wv(FxH{|M38 zbX^WXGqvx)Td#Of zn`Qh|ZneW;1*G7{MWJdnMK*5zix&PphTG+2qfF7=!jH-1HYx@>e%_cG9@slCz)qVv zg9XqG-Nw8XxmZbCznWyXNtvGcMr=3T^ppstsxVRc*k7A}^waj8o#T^#vr+;PLb%=0h4G$I{O>WVZj^*Zo>9BMU8rjJlb#ZbUISMa_ z(rjuNLb&rrY;So^Lj|Ag+7c({%kpUEU8J~m^p*r(f0%fu6=|xbc1n|`Nr(N0}q7pNW+&V{|@Mb{YN^d$yfMa zQ_&li)UbdxxM1n?MV)Yf?mCVZ12m(O$Q8^-0L}S455~{|EIt9QLm2}a7A5{5YG%P$ z=`WQ#f28)ZyE~_3Cbj1GGSGJ%jBM(#zOzyuyP&IjX4^k&6)5Cxp&NiOPp>uH1`H&H zz#rtW^bXf)u7$d@KpMeu)f<6^ zO;P@J8n_~W74cgWqRJ{fvNS~1rY^xHgv&KM5#6a!?yI1Un~BweJW!6X_1rrDw*(HH9?r&XLK?_|x>iNZ>?b@9~soAGx`3HdP(;>t~unQ0x z2pau(S@aR0__X54GqWyPi?)K}L|eGVV{dSMMo1IP7yN*TybdM-xbH>lQOc~Qudf%n z|21K>|G{?@m<-p!d^XoKTYr=(jy&Bp4zKBq z)vJG4u)%Di$xk@Np?E@b#GCTFn(aK#CnO?)1T37^n1mZV<|jh-l_~0%(+r+~%Gr$N z5jpWdge-XUQn<-=EGG)iE}~f!6Blz(??-0{6j;?52C(Onzw1|W~q*Ofr z)uQ0V){>;zbufc0`F0Ny84ojk6Dd}?EE5yrnex&?|6cz!oaW_tc&Tr#CJj-AW#y(UK1#YcUhM8tj7kiS6*2G&;WiQG7u;OU z-J4`Nr1mSnQ$D2@I6~sB1vN!M4+pwvyr=zel$haIJxbv0jNB%WTx*3RIt|}^*W}P> zBRMK7*}t+S4SJRlpzSbA*f3TC0nZA~2oIsRsavCcuO)k!JjO9z|1iGKNQP4+ek`B~ zPn3nAeYLEOugW?PZYM?{XTXZSegrmRTHB{lWWrAqBv2aR<7>QM*4x;S8gubOOye$s zYbRbvqfsKVQ2Hsm>(9_?LDh&);3*Jqp%A*f`Gl~Bb-HHBKZrcx;`SJ zT%wT8S6r`EX+Ev1h{myJJyKNAsAqgHtU|!S;?&!BU4{5dP8}%+tIFVhaSvMt^(Ijt zDFLK0DA^!Ef{5t#2vKdkEGoV3aS52Kpi1cc%&EppRmh!afHY3Rois_JUlCAlT|&zC3$f*X|s>*tk3-;1TvWP)E?KPLtw+x)UllGJoHPPla%H`;mS>n2mqz zr(C|#U>*WSEzn`Eo*0;qO;Q97I5c~yS&s+FgGh5YZ^m8O4OypR&L_R${WNPF3{p6W`YlDiUY4VhX!tb*BA22`%W8a^E3%f}4_(3zRo;>*~p*H8(3>+|;~ zHA`GdJ6EHvRsrNCe46VG-5_rgL7!z!=L%wSB0PrJk$erU>(BBGeHp0EQtj#41?gBk)aR@$3wwH@e@XCxM;4^z}FV}9wW2X5Lw zh`;rWwUj<`tO3x3?SUh+${n>Uh*~krrCRTf23!nZ#h)4RwvXhV(R6=&lV`@C@bKq1 zoT{J(%cZVUIAiS|#teCG-MN_#9NnW|_19_g;($<(Hc?8ZEFV>yRjk@{)Lub(NvFLfp^ScCN zS}QUW0b!zai85AmQ!~y9?~?Z7c}KaXbz9FW`*JKwZ1mE&$hB0H%g6i)Uh8u7^Ffg# z*>>^Bf|tWXF-}764fo{!o<(iBTf@z38 zlLO)QS^48+O$Hu*l*`2vO8ZY|f^}@AMeTYvMniqjlYk+SW!Z}VCZ?hYrZ3k^<9jld zq@(=$gx*62Xsm0L@STW?iOPsFtVC{d4&MHiLf7>X5Qp8`N%2h_uNrj_L4$;d*t^%{ z>(oD|@Wt286IGGk+8q$@-S;~V*rZ*~3_+iB+XLF6niVYfuFx9AJGu?_`Iom%MmvD4 ztxn!Y)}nGBL(nq+%?b-c1b@6$Q)Kr$z|L3bQI%^=6YUb$WrK3(jNCZpZ5-c*xJ5OM z&dD_q8asl@H1N531k;6(H>#S4&oeRAFUMb0d!zcC?Zd1}XxGj6P29F3#eS6vAu&a= zN4A;Kr;iAtgEW+UyMDOk>8}EE*9Z9tJ?m*1rBDy6S<*wBVaLu*wlhQPRE)x|m4K$H zHGrO=zgWU2)~Od71HV|9PkEBt>LEmb+9y-Hv4#&!4f0N<1ieY{I+gyZ(j8-kZpljY zLgtb#XjzUNQwRtQqD+W{0y&S)N;&T*>lz2X+=#1R3~7C3tUffsrPzOH9Hc9%xwI$dCQ?7Udz9iW zQ&QJb*|LlBXI^QAvqbhJwNbOVI*kz?F^_77><6n+sSw+0La47=*@G&jN=#5s8uhh! z{JO8rkMltJ7yF2kQ|R)OSuP9uG^y3roAsD)CgSutxh3L!U&bVM|Lj0N;p5!6_At=C zc#Ybh-DQ`}@BD6k;@SS#62)7}9K5^%Z#&}sGVbNG#(i^*n@um2q1(1JM)Te;#a-2| zzQn(53`@TG0x9-=+_D*+d=iTrt6XJxO9QB(Frf9V2fY{kz`kso*SntVu+O)F@RBi0 z;DmarltSGC#w!L5%h<@uKD14{l7P!{s|*%!ecC9CsCC;Ydw!K)Deic7lM(X)_)=@c8VUf$O5UxyM*t%DSB(TF|E8>o{)#?*f^Gq5=a?BCc_lA6 zk45a_2&yy>N$&_4vW}I${o89gX*uWGeO*^F&F75|x|^CGJdwQfz;M*WhbXYq9>;c8 zd-9^;rP_a-tw#TXa({;hA1C&*Q^(jgv8ME-r$1M!|NT`DGbQ0;sl8snmD-k15t2`b zr>-W0hlh8AW(|BbP=gcV;VID=Qi2EnpC3d9mdyDAnlt#RhDA;V%K!%o9}n+QliS>E zd)+_ZMtwQN$j?dW{qtz{_yP%KWvKiXP6z%l-dIK3#DXUoTC2kGOnzh5`@7|H@a-OP zr)>#8bGebfchbYVAR9A{>>@pDPDkhY#NavSyl%z)Fqg&M^y7B$Vt98oq`+4^;sCg#=3?)C&hxzI{QLgA@58>XeJzt!=bY=l#~Amx6K7B+Laru(=H72ILa3-eRzgYKyPvpI~x0skBm@aEyG!3wu9$pRS(P?6AFUZ)W?Y(Jy znf0ND82GQbaW=c+^s)RO-bX)WSBSruj%{YH5tCq(xc9R(;^*${W5<5%p2_gZY~8#t zy56)B5}4Na(g4H#c>mPbXC$r;mToh7Rn_i0(?N!2OW`&?-{hf7Gci4Uy3NYIv&BR` zk`lZtsAEIBVo2g-?$XB*9z#O^TErv2dh0ZLzj9jmdBIT$z3_R^e$ad!k<5X zEC-u%Ru?7*MZ-77MuP3^>d79rpKVQn9j`3TSGTg-<0d)-5I1>ZZ0^F^ckC)&eFOWqNVL6bWfG^UF|#r>~tqi ztANv=^1`#ReAk|R?=vjyGeVcIuaCuuI!-L1f4se0z)1ioR}s<7Uv zHL2jwX_H*jehag;C7Mgq_EueqW%)643#@NTthHxD??~{hD&u)Hct+0=mFmnp;~zgz zcjjhEW?oj4=UnmiH@Reu?2~BspQGDb)wF=EH5$GuXvv*VWpR3-d$TZ%+H=~1(abIb z?no3osLN>hb|@G<@84eq7-35zp##dZ_2X@Fjz0%IoAgs8Bjz%#FJ8QO+dkzw!969| z;F^OrkyAwF68|pfvK;vrn^_B_Z|9emDj<9*H<~t=U(f>F_i9+G-}=fQ{QJ4f5DzC> z#+KMa2%Si=xIHse>o+r`WZe|jP-GGlGTDxme!H?dnMr?Qs8;^`yo-6i{b*z8Fn%#i z;?w$UljoaT-@GyIG+n`f!78+#DgzfIQgP^%K|h#+o2LvjD)nC|nDzTR|Ni>iDTYhb z5C59fGoO;0`jH$c)3EqBc=%LCKrF{oe z=J1>DKkJ{6E{K~us;Efn4PWfiEobBzpDuhM>u^t4$@{&uP0bHvcKyoFcm-cdXV0Bg zS;zHddI7_CYa?**jZ3l+Zfr2hLEE`oE@+YBpzJq&DKr&PnwJsOmO=|?b~0@Umxjhl zOn`$IdC3{4-*i7xD&GY61Q5@ZQhW;J4wcf8KEmr1# zJu%Eh40EY(cun)GM)A4lba4hHWfajj*BPzkAidNxmmAcfF{#27Q_E=OT(>g9w*sq6 zF!Gfpo9@=a;mp#4XK`rZ7%HEX)lBL(?*Sux^1e*tpbZUC^nSnX-GgDk%mw z+qhneTAxU>C!*)y#q}IdFrthxUK^iPyV-SiD!|t!{YrL4US=3sxca|_KoEIJE~Mt= z#Yk8EU84nPFs;REzm%)9G0Y*W@8b^HK1Xb%yW=Xr;u}txvIs-do)N=sRxS^ zMQzUp{<&E#jLpT_(+DNri9JTwt38IN)9l0U7sXDstrZ7?|MaAEY<^L`;!nx66-A{{q=&ybrEJId7-cKNEh8VgJ14@fKLF z8#KupEv|F2njx%rl}gu1-I8klsm?J|tlgGnD3rh-~9Aid>(s zR`k@qpXx;~sNI`7(<)e~IeUKqWbRWu|YUixTPP%%s} zj3+KP)%8krl5P&7&`PC;MF3%7Z+@MBOnIvdBcZ95&?(1l@3-(xF;9(8^ti1=f|0Vi zqfYDV@n;B3Van5|rU9zWtkAu>T87hPHRH|JID_;NON~B4^c(TBl@>Zp%|$u*c6{IC zIjk+7DEl)bcqWc6bLH-pMaz2Q9AvF^N``8%!t%?)X4d(5Mfae4ncq7JC<}|cqz(Vk z&@{pQ+}N!w7&n_!h|6e^bONQf$f6LN*?#SL8*f>HLAmjT>n{M_+z2Hj@ zk-YwA@uZIu@52`CcLZ_6*`nk_$0`9Xf- zZeIQPmFYJf*D#(4Bk=G>llYfq{K=`I9N~xez-3J z$N*<&XAhV`!>J}@WK)#nUs+JDcpnE`f?ZTXvWOj%-#g#)bWe#-*3<#&kXM46Rcb}rN61uJ&8_N|Z z_c*7*x^Xx3JX8yi(d73Fxqr{im1EX2Ioorcl+G&nJnJ+cb!DBiJQ6&W{;FktK)Eo& z_mlpc&b9qpRhik=!PL}D>P^(>!eocPKdw`p3G=b{w7GJ4uwk5Eq;fs4&j33Dt;o2d!_D@ZE=9ATQs|9)+%}VFq zh38sLn@qUpkQTdj7xB%kDX6{onrsWHi(A=~OJH)c=UVUrxDMNHqe}Zkjd}En+ku@25Idc)6BC%2;*R~tZ5X+H`0&Bp&d%fhJ`QM>j5>VjC8)VM zqRNYdNTy5HVPTEy$IhHSeP>WfNvZGElYfxN%7mOdSb zgfR(1=K|+A5AN7ijuj9WriicLvRPeX37fvhUGw6Ye4^W&C>3DXwr9DGc z2(<^=Qy1)M)ey|6Qr}u>83~-kS`HVQ6-|Fr98E}ZDfDfQ9dAt@>`>pnO&_dI?)~;s zsXJ_)u4rBDVOuP1t&c_YhHWm9`qx932VCey_{Il>Z2;BL;~x{t|2$kC%rnfi49r(> z&^9)HlqjSq-Isd~Wa>OGl| zUr}lNiqi0>|`UsU{P>)Dm`>;_`J>tC{_UH2{TNg_@I~&_{+^LK*0Qm-^ z*!dttSRJ;x_Ii18YH6t`)Y9%bU<$)^{&nrXmGxz1oedop_Msp-3SQ0{e|gUNN|c{x z{d~0QpHJ}e&D4~Xfq0ol%1EYK8dllgDp^F;W*G1#j}BFaP1G{m9yzIt$?}2@Q{P{E zj0WkW?ZY>h3aV`D{4f{ecE7?mZIS7Qv-TM3LrD#znrxC?eZZaRen1W=Nv)n-LJD88 znUk5}BZ;ze6Kr{5D`PCEuIwmf&mgR!+Uk3(b?B`%YvVet7|vP}PlHQ}{>uwpYAZkP z_tXks@XC_3;Kxml`gEx7yj>Mq;#?ZR;I%WTvmkk?#zWB9pDAq9O z_SPZ+KkoLgGlO^F4_Jz(Ut(a?AB77P|U;We&QDA8e?`g zcS(Ctf`1+kUu59A_|^`{_c|{8{wB@uMk>X!!+E?YZ_F;74_Wc@KNEKIikU;CCU?Uu z;HNd4l$TSp1>gYz$1!4L2nc}1`%noQNjAW7BGVg?F1wm0FYF7&+5;~PG1TDHo zG3YQTd)^cQk*)VZQbK1{?zQ~xytiV4$Q3ll6N?+T$xjasOWHIvvu^$r9iay_6AL{ z#0y5X$QzVeK{{^JRXe`T3||0a6WgGjj+k4IkA|iD8TS&o*x(^vKi&3zF14*28V3-) zK`}IS?TDNdvfG*GVLk}yAYv~-LCKsS=_<^`5l)gza0QXCYN=?|)_>S}n27OlW;^+P zKU_{&6GJr7tPHgUljrIigJ}4cF7E^1RSL8U>xLi#&8SFC5cw%x9yN4nHzrbErv<;q zSb%OK9GqBVlxJlkX=-;JU`!P-_Ehaku&cIK#6vX}%vbpbCyL|0ud%N)X8p%BeA}W& z@OJC(SVXTTddwaD$}Us?Lvw$Fj4+Dmpj{K;tl!LPn1kTyp?Dfj8ss2%^2|9dkc-@- z93ovyn|OJLD&0&Z66RgAHHZg>rd+|Da}y^ zx`YL9G;FOtY;}TDz3dU zOeuW2ywxTY-OQ@mw>y>iC6anrL;P9i7Qs*3SM>6k8&g_Lo7B?w*|7v&(}jKNAl)7&FTuemh4aToui4m-no=m!OBJ@|17;Os->zBK{F$xSI_3wMLviX9Y3 zRG`7h3h`oZ8Kk~;m8VnumC-t-M0H6GnZQ5R*3ALuiKWcyT?`mX@x1{P=Ny+EMUv#4k#^ z4e9sTQcy0q!b61R4pG{MDQNvW%khOVAY>{UQr+WAiJe*vDD zTnC4>V?E7E&>qyZ(uOy8+>!s+D#ZW)Z!7{K3C8lzA8#Q!*Ms1ZBZ6{Kp0@X6ND~8* zU?RzX78Zv294=pu8*Kmlx%{MlIy5f%r-;A%2-T(UFjA$cKXV9GAqd{TXxw09XLquH z2<<}6{5Lq?RVMqoe2i}gii7D=5z4y_9TIPN#tx)v9m3MgzAQdFOCz&nc-WtoAa%r?Epf$+lMZt0L1rp zAD74x)QhLI(mH8L&lHoGarm5=nS_b#MvNbc|?N*?E`tnzz{|c?P93V2G;0CBO4ZS>1%h zrcl5qs+_;@z5ps*1CUWmH-YBuR$E(Ju!*;8AOq;TXB~_Q9qT_*PQy2;nekzB%P}-_ zh818V{_ARie_lbQfL?_{P$iJQ(=(q>2RD7wvvD<-gI`vx7uk|ynn&uTeZ?v(npq4o za2>z@<_UE;3oy{c^_Lr40CQ#trY=F0AEtmlkmVeHT5bG0!HJi0%I;{$js+o~)P(B%U0esCrm#hYOM3v8^fq$5<2*z%4 zRSGEms=7YEfFS?GeH%PZ9TD)rmQWFLpOS?wKhg%%Yv$2Jj@cUVO#mb%xk1tM=li%B z{tczrXu+VwmKd%&BGC71e7;w@byto+A@s)-IRv09KLD1#baW)!*2VN7(MvDOq)$h} zE@{)^m(!NY)4sH!FV!uV2jL54vw=ob>V!Xih#DfQ9yVkbw(2Y?DftExF53$bZ`^|c z>L&wQ`I6kBuQ>cGqsYJuh|ndkUcG-E;hwi9aQ;>e=SIz)@nQ?SU8z?7T7A8Wg(ye? z`||G>8)R4Yc5Q4jM$x}MJt}Zo0ws?hb{4{R%!ecf8-lBqIaT{m1ttho-x(m~Q?f!= z$F31VML|WtOV}0@fU#jayr?v_Ab8d>QrQFZ^f38qy4>d|p`eZ~rwm2U4CM^h>t+CV z0WnW2m|BomTv^$JOcp@{JevW8@^8IU=dWGDb>aa2pXnzRUmvGFh>y2D==DXax~5E{ zwZKh9EBe5lr56fl@63s3XPt(sGV+!sElPa{*RF;G3d^uT(`F~82i_=zZ3IZ3Ipd3q zP)qJBv2JZ<#ri}kB3id*$HAJs9K~vkNDjh+T9+jt&*+i*flahqW}^YVw=p#M1wgLK z;fx_4L#tURdd&HvOGUr=(gp3REp(uHQGw>={mb?b9=_UvVU3~v)#1e>MG^@IF<*Q4 zV?jxUR;g=o*NnvqYl7+NQL<bsf%lB5uH4I zn438{=ct8MfZ@P}?;{0Q&M}{&My%6=XB$W*hq50@tepuNy!9=;)+u?$@a|gx+=rbo zzYgDCA%gl_jmA6wA;7`MsxStG5}$lyfyM?Z=7=B$a7msE`8MG`jU~I;Q%)a=6-lPd zYUiBU@B<`kSjj@R{Pw^(FyEF@%WJ{kFC9@Wr3ZsSVp6evQDo0;`|O(fJ+qIbqLPe5 zc9W+73W)nu*MFBbNAlgRKgddJpaNRq9XcAysKrr(j+B@@%Su`Ubwt}!c1_~CG_yR; z*Q4evom`ixeI+l}3D(#fO#!(p#(Nz2@67#p$F|;Q%C^ZZ0u7X_T#Ss#v+S|upkk(r zvu5iS4}aQ|4A=9&tRr|s=d{p)0 zpQ(q3MagFCrAe1NEp5a`i|aobsPp$Mt}jGH$*cu;j*}Z%z-YYfCe)TnVn_$V8$_ZH zf=RAw^!yG|%|qitHh85+1aiNtYcLSuw@UO+*(LX0?7`0oUd&>;*fRBm6}}i>+ox_M zo28-c98}`l%&Kn@C*orURo>pXboiO*_H+p=+_o&%*M~@pAktFgb?3#LJ#v3ECR@^q zy0^f~TX$NX&D@ligU5aF5y?mX+EFWez*Cx-Rn0#gMq8(}?T(>Rce0O{5`}D|u0~zP zj$wk$ddxfae|e(Ge>dTp8UK8nB>q*O`dqi19JZN+I@>~#OHB9sxzsPiJw>Y&(dGsv z1aYWjSb)HUEQx@(da-tez?Mx1Wy%?<@0qR-XLQ*6OqZ{dOwlc@`rSsYc6VcCx=jx^ zcs7-IU8J3NwTe^AQ$Ukzyi3mGmJ~viu`ZaeG;ZWHnILJFHzmdffUzzpIr99_X1wmG zsE~&*`e#qU9j<4ph1#s(nqIqNw=ya(6o`qyNxQD(Anraw05j>cVbYcmFJK0RuP{i5b&(tUTe(`3PmDL((PMu_8amX zA6U54vvFM~Kz+zRYV%Zi#B1Kq#t&cVNXT1h`0q8wwk?Kj4xjHaSPCjmBB}{R?X#+1 zc`{c-_b7M7h7eg!r#`)%a*lA8^mVb4dpY$}als6VN)TNRJgdU?_xb%DpFR)}66Dy;HMRCYTVA!vD^hHl*G)oL*=&zzCJ! ztwRd0V%!hePFEa-u%sSH_qj&=upQ+&;`Z+r)-K!8MR>Vf8d|514>c%soP<#9H5;4TCr+Fw|C`Zt z$=8;CYoRS&1-h{q`pOM<2tda|hd==O%^lN7=+SnB^FJnnMd-f2z;#+_Ee0s-UbgYH zbd`F8j(y$^CnhEoTsy^}XI#2U z8X@lE!hdIO(U$L5bbS(Dz#jL~v+UHl$x;m>>l}Js&EB zt{&#){n#i5?b4(EucP`s+ri+e+y61Q*-<{0aHy!@YDqjv zA_N9BWK2QCQ^!7FjPEG;JmMD+;{JWg>{>-hn1 zi!NBa#5r=~Uke@G5(}IQfUIoZ+QY(`04efJm+a*dYQ~e4r$Ns5Tcj8d*4)V%_8UYe zi4;LEiQVWa5Dhe}+=Y;pu3gO@HDmj}eEAap*P)qQ@Q+EtsPK*X82V__C>tA_BWX^; z1Pe-XmYK&PzFmO+i?oMP$n`#x?U36g7-+suq?vySx)GH<3JI)vZU^{f-+r@J4qh(C zssw&lxZQsPQrIwn6qM3|)JuoNeJ-_?x1gXbFDWIZPxo9~oGP8!SY22KcBTP96$FCy z4O{C%*ZmYNW&i>4T9=TN)aylUe@T<6hGcf|^pkDBzrC1Dq5*e>Likn)0J|?#SARVz z4}~HHhd${yjfAg;>n2%-g@sL%RbMH%7fnWDE(4DAFqIe$gV3k7hOX8Jz-VuR3IIXM zs`68>+qU~UwFpnVq3K-bN3Q^79AYb|Xi1ya0MkP;V2IKeR>0k(KRrBJPCCrIKQnBt zfJ0Pm=)r>r5Z{t^?d*Z|ih|;++SZDbka}2s5$P;-34B9aZt|VF2Az8v(1&EY5V%QK zSE7Qt*N+HLNIKy+YV=N^@Q!-N*q-CCh7$wsoau!5(~CanP03(ZR;3~(Z!qs>}esy9`G z7QL1PPnvhjYUUho+};X)an>nXXd>$z^C1EUyi!!voFC`aLUI#qJ>Q{Xg4+b{jU9ON z@Daf7OZ~pPYak73UCqx z(JkKHwKEw60DvCDDNIFP5&zVAFLi51*n$5nQ1BUR00mY7OC5O+m&%Wswf~+!@YG~b zFuT3IwONj0{GT@@9?|&;sPoz_K+P^T%v1wK#ms?s_gRLan~@`ECHEq`1Us_2}LZZ80a4Q0il_4P?%X&j)8%I?jiUYqN*5Lp9e7-X+_afz73f+}(9ytgd0_72x@qAV&I!v1s;Y zVyd_fsy9ymcoHnn@77QV`t?W`$PN2}*|tJ?rUq^&XacMM zBXG!KTGRht$O9DbXjouipdWB=u7l8D;?|v8zGigIA#xcP8i@D^)U^RndxdgX`SN8~ zP_l+d@XUF38aNB&S?IcvzAxgouTo2F@Jwwhq}%Z!ufDu+)?D-oB7tAY`_-U16He?0 zq~n2{VSVS$ooOYei0O~JQ<(%4=hzQ2RlJ)x0Edjc)U24)93KrG83D-Hq;r-%c-?*RV|$mWVw4eq0R0w-%9 zaQ|8=?{5M1GQ}McX=`=T#F=Ct-XN?N(l6W!Dn_?~WwF3mWbGvYCT;*XVQ}$w3?Nnd z&t7jW^>PN0pdfVO_ir-f0>}*c69=i5Gw0{u>H4Nelc(kZC>ai`oF&->f4icm=QOJW zT+z$;@XarTZQz_9x}&pgUkMbDU|^FNUJn3zjAT6nB*T7?_2|GR>bKrCSu!55HkCIV zO!BL2X#dt2x;|Yu+xP|ul;nm}TTLutLXrQ>GQYqsF(I?V$o%_9Qq6$$sJ8q?rU{ay z5=B(WVc^-=OvHLtRe`C(76`C?1tzEXm^Oe`T>z@BwowAq2*`sFwHI;*)_DvgB*n$c zE`&9up_`y|Ql>$9^S!2pph zw{WTVx1~r9FN3u^ys)`G0w5!#Sp#2zGqBbA!_V?$g!Bi=}--r%L*0+b{3zdAa(a~d&9|}1$i0XlgLT)%!b^W$W~^i=aI~3cF74AgK>H? zl_a1R5c?fZD2iaWbhlOqf`-11RrAid6iJy;KOo@jepL~9_owWZm4^2CF1Xs;T@hD5{PV^>FIH<| zjoL5R96pGye%&UAx!AI~S(Up7vcokmEFOu1vF*;rItw6tT?wGjCLw;j)A6bMDM4FU z6?hKTs9lA$;kxPZM9TC>xhh^rtR{v9lS-H$1&SLl{2q?N64RyD^01>GXRjvu*59|T&x zEq@oNA&{K0J0Q^SeY>GIh97)VK@t+L`Tay zKQvV-MZf!*tb=Bu-O-D{0+Q?Hni%W)oHw)>&5v{A6jaS(K20cb69kyuElPn+X(VhN z&8Sguhzt+6(rY12`4}8aFq#7m2=%5|4SSmU+sK`Q62{pHAqd)=aTk9XB3}2y0-#;XUS9$U98J1QC*2K%aw|Ge54q z26^5!T>}WK=-xuJnNn_Iuy((Bv#e&fp-1EDEs~u-(P+|YB5aqQ{#j$oEQKzoVtxLu zTzw%%t+?rYYq7k1Wq3naXf%vXsPe}v5!Bje@aEByOxV5G*3zS4*-OVO59YNKnk3tR z=q;cu&GhN`nH&4TjD2He8ptnocn>--B#Svdakhme$cYHyJV{&jo3CRg|*+weqoV{b13-FzU2^TeI z0f>lT5nRn4d_q0n=gKGS6JW#i@G_JMp*o(}psOvbD6;2PB2Y2T2|GX>*-enC;!*B_ zp2boDP~~IiE!*4a8fhN^GB1;$!9R>U>Jj8f(71JDmmX8%KGfgULHYktan6_rM#OR% zP3UMq?rS}0N9^z}2ndU!0NtAYvXjv(n*VVg(#eE3ApTi0O+)h`3FrZaInYkgN%_(k8@CWY@fuCrUoJa2f?~o^5b?8?1BF@ z_2>UBt;gXBZ(wS-!?OwBhAwZSzK&LRU`>FUubty0RVGmCMSo|zl0vOZ(r`cfufu+v@EqypIQarY%f3@LQc*JIo zbNObDPS=TvN}(GiL01V1EoqiBKbZZTyYelCdft6l$XdWHT)QrYGbls6-()K-GazlW zAnc-!|8-iUzrUII_MmwDaG-gB&ddq@b|IsJGGS@`%v!Zz?4I5G0ms|1Yyb)vcGv%+ zcK^{*%~pZn;*O8olZ%$#FCp= z288J^I8>+m?pl1H8mnUWVB_aDC>DX3=oSNSGqodCAGc_0E)uVaWvcGTNsY;4D(c{+ z<_7OyBJxZECCDjJR~r<;=DhSrm8J6Z0}E{+!e>z3a9atzKA3|2cwtP{E)01KkMsbeCvKnF>f_oC$ z@3!j%gfW3Y841%!4cM4(rKecf#iisq0hwnRNGg`IBMnZNaF=q~?7^OZQ#IVSGhwY! zpuw>jVTf_>rjO+Gjo*FZA)(v9kC3x)Xv!b2##N7E zj>0@2ScYhc^+CS`Eq|Vb3i)A=J3JRwT5+z}j6*Xlz1_8}9bCZ30IV1J&2xTqwC8Mv zWi12Jq&P#(0F*ltY+x%FE$av>wF;qYiEpR&$3By>3 zI%p?vNKQ}GVyCxNhg-M$?S5~mR#hDD<4jBS;GbX4a(3I#xKD+Qfly#Q==#4{4o-{5 z5`+MNfo#dZ?-vglp9xX`1175GNegQ6mjmnvgg5Kr4e!gR5-8=rgz9p)n;a)_=C4gk z=rz54fqkexp8oCL#tM|j{d_XdL|gGi%6_$-cbT2sNqEg zcPc3ch(ONFN>z(Q1&_V&lLpys2c$Nw2Eu2=-yABcv)<+mpK-Z*d7<=_`|hpNtUc;=bv_11|GRKY7mhsf#Krcaz4*99cGAZNuy%4zq<77pLy-Z)i} z-|f;v8-4L8uS!u;pSeRLRa`I^>7Dzo~$VVw=t%8 z2q>bF6TN`X@5cW5GyP~rbvj^sm!IE{8^MI)Wc@SK2T^iV;W-Tp?aF?D{a6Hy01QqC9Kd(%BM|+7U&W(Trab@NikZw1=Sj*EN5XsHDYnYV#i>+veEG^{@D@-6`%lRp2f{_;DJzmcxMx zi-j{)^a0K&hvuJjcuy$#GX3o?*M~M*OCsE(tTF0!xpzu|^cgN_X-l74 z+5-R&pCrRHPr)G&1B^dcDjQwHuZsrP77s;NqC|_h05Ap(knb?X_CSvolD!eJMCod| z_4SzpAZJye6%|tRAO;1A-as?==~yK-Z8?Jm(*}0#eVj)qh-t`&QUt83)x&--Lct(H zX5(sA;FsVF7y|Bo$o~xV?yOC~%RzI*3|0O$czxkB7Z%AtI=hqN5ZMNK@k#TfvmKxx zKsYB!ACMzMm3i&L2J+v&?tVQri@WzV*@W||mPD3p^gBAMlDd-<_<`vHRph1ht{wE* z4Y?GLGw@OXTKdeYTbZW-Y_*z`X3bz}Oh~ck6x{4w9~&)p{``w=Lf?u}ze1Fp&MbLg z;-Ecm>uI%0-X8DEaqV-6M3L&dEvr+bkS0&htn`#hXHK^8C#-E(%zhf+JuLQ`O9NxrPe z`3O7XXijED~J^+T;{f4uWdp7DDw}MWKvKhJ4TR>#axB(Il*} zOsfBz7QH%hl>l?!RJuAN$5+9Jdv;)XYHkViUqJN`yXUU_Fe!U0l>s}- zx=U8q=~JT_)X?P6b0JvarkdGR9nx#EPD||mz|H9#2h=pBtk=)$EjJD0%tGs{Y{2rD z&pXx$SK&uD%OAlc>kKfh>!0TcRe2q|B~c?&_|2KJ!?vE@Ci(`6K|SXFFL;%g+r)h> z6+Fv1rfpIsx}8$Yc&|n7L?vsWixt0mb=(*E*t zuiLK}q(;xLS~j@a8YPEqiOmJ{@rp1mfI7lr)IAPn@vdcz@u2K6+Y{``b(|rVA{etN zInq0>FF8EOr}#}zMSbmynq3JE<`)9%icAi6Et3f|cL1OO4Bu)Or6>4boVEys1&Kt-XUsg5poHqjAc zQ~Y831w$e8kn&BF32AL3EK=$ACMxpdkL+8^+w|%2d$EBz-nRK;jMe_d-E{??k_=0l zb$*G6q^qUsYKNB==pG35C9a7oH0rXGJXRw^s)a@Toq5!X!{*e4y7FG+w03!ABS4T8 zk-|D>CJ*ualcs=gpZ^YqYdvh*kFioN^5*t-#0QUG+M~Q5mWTV%3a`xKiWb1T6v@sf zisFfETUuk|TU;r{N1JXoBar|*sz1u%@1syeQdCH!A=b8VJG^wI)2pI z)|>nxsp%Y>s7Pb@a}LR=S;`%`m-(EaI`hLDYGql68E>-N=R#J={;g|J!2CtnWziKXyL3y;|Tjqm66v@85BwBz-d^(5IoxF}G8uK-lw&*JZb)xu28M`Xa zwH2aByutM^GbU%kd$c@mM$3?%J|;)PvJW~=JxELviCHqcteEidRi2x8LZ@p?S&6@g ziJOF_5&xL(`B+e=DSM{0;=VrCW#`us+vlOJy|@Z`J^SZJ4WHIMY$0K-NG-Wft9>2b zhttL584fYE2A|lok}NH34Bodbu62`Ifxc0k~AM%H6VdZ1*+p@@dBsks*cqZ%)+$MLBkN7jeagiFr-Ctn#Kuv$EKhRe2l zl9RT2V+p(F^(~fCg;aAzL}{`{iB8bATT>(xD1@IORHZJoe#=4RznROnE0%mqi{Dt3-7?553dUtOdXk`8k2)XhdB=i}b0tdJb0#>Yh@BK3 z>oI!vmtb(PG2glyN=ETqwp>%3Bm=ajk4QPOyS6o#2TCW@%vs|5=k2a&MZ&oJp8xFg zX8oe|7y1C^Eu@{TdsE`*RC8oztNL|^M|uNh3M2w}33II@(c19SU>DP>tZ~pQV~PzA zXM=B0;@hfZAUpg+x5Yh0x%cD2GLqNf-(|B;o&(-9Z&&GR>~4)Z1uVB->Bx=@Rogs! zw;Z79F-edp51`($DWR=Es9lX3n7v&C_3fqS!fZReK{uTl=!kL0Jre3VM=+WDQ9b$f z`FJ0;b3MtRuBOKa1%#J{Zp{l_RaOi~ATJ$mbBAMPoBh9H2HVTjUJZs9mgH(hVsI}N zCi+}jwk?akzi^xo&Qo=WE#A3IAV`NH8Nm(V1?o7!4eyYt&8Y6vc%)5p-_Y5yM5)+|=0{q~s>WB##}>W=c{ zw6y-;ZsDcF!0>z&`=a&{Pgj*4@absjcXwKGgi*CIpj=q0g#jbzw@4hco7#>DE`G%8 zR5~RbT)HCrb0mA7Z_px)B^k8*Bqmt$CM2u`tXMHF91v}$Q)Tt{Fg+|-Y{`$DAONvw zXK;Pf_J>chY_?Xrbcn2j*n@_w1y|WssnUX0lxwIHuIcwQS$cK&%Fakgc$m!ri+50FO|?UsscyJzh^f?`DJS+E0zc!>npt_cK$p${@!?j@gXalH{JC0=}e2XnmU&n zdHA38?b=)KKalWl{9Q)umVJ@PtFCOiP0dG?8J7yA_@4-&Oj6P#VNJ8*Z_b{uAhy2Q zXHU;HA5zF)lhveYXy-jr*~Wt(=)e<>N)!u}7rvhnVoc7bR@FA!)mFc;_Q|dSGbnu{ z&}GbZeTsa_aRQh?2FvQtfnqh4YUh#2ni$Qf`sS*dsF4yMcP{sRzpg+{&zLFa zf(O|SbhRgLGCoXhUoV|=^hq8Z9v>tpm-(~cy^@_!$OHD1efK&W4~MDzA^9}V9UUrV zW4GMRbnZIPj9&u58Kk5yS-B38Gxu`ZCfgemkDpURr;E{+(4cEG)amv!NuMeG)Wsxo)zSYH$B(*!bF^9U~YbgtfQB)Nw9;T?)oh) zt~$(*OgOKRG5}D=4{#Q8t8vL|0guurs8vKTkr)jdNzus}`k91|mbqi1Bv&YQ`$=5o z$o*U=*Khk1+d6v=Nxc%N`ogm$fXtc!W|vDBxR3Ev>3;i14~amIgI_NgxPrREV-PqL zG!*{*3ST%K85D^=x8FhgR^1VYy;RVx$0XLh2)?n^T})z6cHD@N zf8o%S2H}%WQ)8XRJs9`%v7don7bB56HY)04+m(N;wv-T>SO?^#Ow z_Ag@j^?wn|VOt*385UT3>}1>S{TPp)uBkMi*M~RHw<3OcUY<0cw45YXa7u-hQHt9dOdbvULLzE9?M;43sVv9~Z;FE+QQ8~k4ge;B~83yh$TA3dtU zeI@5iqIdhQgGww<~~x8xY23<9yJuuc+#4+`5fT`G-l_K()*92Fp+u+}sbzLwTga4#~}F*5eR zu`6fqDgHK&73Z)V7>m8PSA_dRrkJPoS???3x_(z(QRJa8S=jecEoRc-x4L|K&suAq`Vb2?-xR9Eq3{g~xnuq3X6V(U zoRBo}OxfS#>YE$y?iI>`Umb7=04ADdU@tYp3^#hMPNc=`KXlSGisbm`*XOavdeQ}K zvpf%A_k}*N-nIHzym{k?QPCz3yo&Py46AciQ~RvuK2}}B4DORjBEoi76=!^xHbm6i zyv@=JbxAKeV2x=_-^Y@^o@Qb?P@ zg`u^H=~}Zf>ldd-1q9oL)X#c|*3k0j#{QU@xmBG~yqeKxuDXF*BA0~-RT@e;`C0#e z+`V^HQ{mSxNE1*)2_l4Ef)uF%q!UmufP#PsC?Hiq1f&VlyVTIDfOIJ;MLHUK=uL`( z^eWPOZ}Ucf-~H~ayJpt9Yv!Ms^OwtnlXKp(_kQ<&o@ej-*F_z~=Pe3;EMNSYTkN@= zf*d;g3jG$?tQ1~wW$Ne9%X;UQ;Mjz51|8@3lvTwOCwoFBSTM$(&l^YlUowMqoAylT zo*?dN2GhI?UF+z+6_X`?_N=_=VO5eH3}xs$=0G!k`+5@t711%cPP2Yc_R(%+akZ~m zAUjd#tu0R|RQP+6q@($WP1VH5rfXPG*tHEX4S2Lpv}tL4d`;hdEjQHUl^?5C9K0 zR6wx1$`55z!>JOVIzKrCHJBzqKl_Lc#s-oxm>xov7&V<_vRY*i#;+Ly36V_zVG6<# zE<;&KX={QmJ!kc-J(gLoo^$(<$ILU_LThADLt}#7Vl}$}w<7mG-$`!LU!BN4_;_U_2lmDOjLif!-1O0|DVVqUJ~dqL8vN&mtIMC{ z(wu*{q-r6hd!d?+l&vG;Z~pI@f)yqIVDkEArzw#aLW#eJCB@!7oZe^ zZtHm`!jg9^Hbx zO9SU4wMCc1UY$;v?6=syok&cjnrq#7qt&-%8}y6zj9*oHsbA>X_`t^%^q9-jB!|`F zS^K9!Q`eeX*DH9sYvw0h)>M=xY0s?^EfF4#dly&c_G=N{GAkd1Haa8cDh6Fqy^=EB zb(`VeJ!e)-T9?#=*xdQ9G`nrfcn?~{i)z)K$p1lJ6vumFV>P?_mfxp)z9Jn|_Y_We z=iylRXn$i>N+iv!_pWW*Y4{U&6$lH$>>}x+pzT8Jwb7JE-n1 zv`Bg}4~kVP)pI6S==uKgMcfCAloCDmyDHMA*gE(d3UB>V8JQuohT6(!mJsRJ2mLd9 zEnQ73_Y>ac{T75=4J3=4(W(~_J^jcv;ohYaKugO=o zf>tf5{OI)CE98Zsc~8iUt>9DWgI{I_)U?PaUv7?zlu74~c@JxDVNx#^?%r?Gm$i&! z5fSTVE_H-lnC~TTp15B9CT0r80!5sLq?NyUkaFG7pjrY`?{U}V zS?{S(A=kz8BOaC`PC0L*I^mzq-D#zwAA_v8)IyGO4CLPRPjrd+nT5D#FT%F(GHzkJV+J7ko$hn z@swfaRNI?0td(hUWi%KHEV2Nj&`xNHWnX>3RUJ8Inh5FLsiS172*XW(yUCAjO-G+D zDEn%=9;DFDcDDrYY4t%83*C{aUru#rrhg3&U58UL3CJ953%QRD+=Gn;{Gj5wHwuNf z_Q*)_$*mrk{Lt(Rcph{vfKKy}hp?3H43!v9xi@{ic24#4{h?k`=_aNVagw_CB&lNg zYsr-41!U)-PMU9IF)zOQ{hRkJ`*IsALe`1vLZ(A8CENLOffa4%Ji;HXrjpDLio#9S zw!ANgQMj;vmfZjFQHBkrYUK80WM}B0sZ~U7x#s8IMaKp@yXotkVMtr_;_F@mG)!b6 zqvRYr+`PPjWcj`Bq||N8k09uu8Q&?oGHCw!-=s!o;T%1C7_A`r#KeU549>2KD}etZ z>T-uz%CNVh>8~5E(NU{0h~(Z>E8Zo;lK#|CK5@Bf{A|&Zl6QdN5J&3A04Qs`1jJ4T zkCJl}uR)?!!N;tq{`~l!R0MEUi*D}^e(KwXGZR{0djm4q+Ow3h?Y3|P`@zk2l{@la z(;*q%SHB=^_khmk72p`h`w+tio zS7lA7R_Ao6*DO@PeiUe01Cvy2Y9Nd7TdPT|)7?Ukc>Y@Im%r#;cbt{XP2YB*X6m$J zGwrTF9!#4f4?FqBFU50(Ogj7t<#}5>ohIckv$F-nt461(fDn=i=Bjt(rH2U@gR#Tw zFNOp$>qaKnZhupQVUssOmRv~sD#)7l7bMp#U4Xi((Irsgca-XC(V--}CX5w_} zRtu@TNA+eYL(}I=4D8m6vx;!AxWppH`Rg+4v)YuKNSl)^SnPccS=7?$nA6IBkz!uY z=4>Xm+|S0Bc=KoT1%|76qbTjQ`aY~I*1a-u4RinS<&V)4=fk3{(~DYXPl*>*np>wZ zdsq-`?Y>*lUcLKl!v5*(*{1if4JpZnm{i)v>DJSJ*t~~DM2f~1y1gY>>j1{m_hZ6Q zV1P}>7)^B$lx7q0uHR8@`@Uf$gGlAaQ}tf`$CBc%P5HH-^HRf?XO@}g_6E~1A27d7 ziCV2Yo5$It+c0V3uT1$)@_2RLUTZ~%*{5)-kzE+6|FQ~!`fRzK-K7n3ns5X!+-d`V zNmtf$jL&?DlyKO_+-?s z+fTZQx%q2z%w?swpTsa!DDtI`JSg;->w}T<;ZG*N*H=s>S}*LcdQn%Y8=S`4jh2!$ z6-ldIfxk(nycBZDj3UCGw#c=#$O60Pe!;&gw-PG!^3RYJ@}!Oqy= zJ+3-v3x4Grx>`(IMm>;g`?V8fa%2*@Ypoudh1=^zF1)NX-BTw;La(u(xecvl=2+r) z)SkTdq81-P2_@B?c2|!5Yd6Q9gooQplv|JH2BwYK(sFS<#VP`qEzst-01x$BKVPn zx!0y;qaYq=^VxUzwlj>;H$VJP&5nNB*3dD@xj`1&UpVlN=5x!SX+I7i`G!(gV2xG7N@#L~Od zzJ6(8%V&`Q7$`UjlJ07JgS_AP@$e`!;dz$O+~*!kyyD=y;%6H#PUi}RUM@%?tbhLU z4oxG2FEU>bRGXwUH`+DV_M(JuhAN+Y_P<>-lJ=%WsWvxL6?tr7a_UuOO#^>*m>$1r zfPV3aVn^JQ4%IzUOckViR~C#ao50j-tAI7(I_9-d=!Ij?*G?q6Jo1KLRXr&&>~&=C zdzPXlM3xp~tD*4edB53rrfu6f#`TmCHgWzm76swAQ%D>0-5BK)7CwEtx1_8r20?a{ zFX0dPR%^Uu5wlfgi!I{EO9rq6%!D}uf<1Ds(EHq6#uw(B6t%zcrvu0dWV^|u5HZ zT@kS!w$iVJUfbS&*s9&EB(}=?0j9a(B17}=P#x;}G8h_OG{`-rf^PW4o*rs{JaT#F zmv@!B07`V3;&~dCe%V=a2-JmBs5TQ)d;|44`L!uE<3oB3d(qgTIW++#d_T>3(mTS) zL;bPH(tP!VGJ1MEn08ft%0_M1!T6-qNpQDwm~CP>uz7Kkx+)g-fcRdtTdgAhY-Wk4e-%t@WwOZlE#47gkpe?3oDi z`WBc8wPh>Bv-lDBPLpn^>;kAUKlXL1#mGZ6ivawhrU`>djyZ7oj}Q zN=N&w>(uaPK{?T|X!SP@l;#t}kclT{<}E^yrMgh4!CYef>GMNy8gf&+K3!eTd6%CO zE&zzIh9)3Hs#6_oh-D3-{(Pa~cAW#^XO;IFFe2aVzTocD#fjZl2NGH-Md1|WwL_pi z%VqCijkK~cu;`|w-wv&G76Cvyo!!j~&|oU5hHrvEUsX5B{b;IrR{z5GnRz6ex{FZ@ zDb^RUBBpMJ2if)LR3reWKxVu<@?XtO*B4l@64+pqSaJ1t?Fa9OHJJ$&S_LDuc#@WV zgPO4Z8-IS)OZuX=cy+7>Pzf21^toYO&7z-PTFlUBeGm+=}WLB*rcCG1>4#VCxb7( zzo>d*ZwI>{IBGR*pHe1v`oW?n?S@CySy6G%O}{GP7Iphn=;Geyl&ouOQtzB{SlC4y zug?Bgv4s_NQzETL14yS3iz{Qm!$@F>M!A_1_d)3T5S{<#v}W$Sto?cI-8&3V^EB&X zVYdxCMR!#OfZNGF*Z9rz<D=zsrtlMt{-w0b!B8u%bR9|L zlr0Bp-U>B;;-Wf#G&|aH6&?aT>BWdLmQC;9OMaIvw#$n!U3|LuR&u4DMJ)BSs$}_( z1up@SmXOe_BPD+@@9^uSs^Q3{Ri`S{#-#|e(AGaHC)!LDvA@&lT7qlUFEVZlhHRf& zrZ3T}uC)(3$j-*V5a!E`_HIh=P>4G@;^>{NRpQF7!@4XOn>2^#b-2sidCJsjZfPX6 zo8j!4jL3waCGn9YseYNc8Z}%9gP2DoY{eM&1jPLY#^XcF&p$maY0o!Rq0+Ab(y4uwv4mS~;^o#*Gmpt1yF`}?H%3n3bzP}MNl zw*!EQ$w-6wHZ(|4Ja;n=CAJb)m71L_IT;wtQX)!&#hFyS<$CmitB;T4-M-mVgI(uw z^JC@pj;I$LDAA83GH?m8mRsBC5#~Wr2gIx&2x-DHR7o&zTPf8~j`Uv`Ogv%9lF7Y} zAP_&Kj_8tUog8NimxT*u4I*4nB|3y-9}YFvxhUb=j?;9FkHS!U-<8q%3v{<#vn{Y6 z>)cV+HsTlNXFgIH0t3i2sH(5YH^Z?zvWQGgBamR&8X3Q2zpQb^cAidi<8MGhnwveJ zc3l#;;^l@+t*VSf5LvqbkmR;eZKwbi&ySo~H&^y~Ya2vXf(16StT=M4#)4>A#WL9y z_1Y~N^u*qxD>w4g-%!jrNZ}C;6{l-U8jnGS^u+RMcw>EaY)z?O37T^aO?UuUe z;529uQtz_Tsr)qTYuD$=G^mA_UVLsEY(|ufu6z0m#an#i%71Q0HYs$y6^J z@9AO~AAjBok~=j)t6zN#JnHv(pr1rt%PRD}tJrcgK1A+(E7D$?-#BF2$3)GoHw8;v z_qmZEfv;0}6eKi;^;<+t^@E|L5Eoa~cfvQ;)9sor+iTtnNaV<3?bVR$S&kL75}NRL z)D)~g{!u*p2r^5_vgxI4iUmqjw3pswP`LRel6iQ0; z`Af-Qe$O4!JA}i}zNNvw4369|Y0MRD+O#~u+7S^d#>A0F2VkNE){V{^&A&W9_@#Xm zVudQ9Q5^nS9VsDv^v4LhR-~|TMJwWL?{{gL_lUY%QH`wvB1==2)h)-P)EwKCaz2%8 zirs(QP)ZG_A!lN)dt4#4I&rNR*~%CuR2trx{Ci8JjamHs+2Mqwr_T6;S1WJ&lCJml zhr)by@tX)|s$0r7ImWmm>1Yl0sySW_>xmFFr>(F{uyRuBhEgne5fG+25lATMiTKHY zGds!@TPtF&J6Wftq1^D^YW+_5ne^q6wRoigH2)G_PXZl!nCZD89<`A2b<&DR?{ zo-((;+Rrd|CxK7q$$j*Q+2XogOQ76ao^OTd8P!k5CMuN-AyB?Mk`~={0G7gmVniOa z+6`gGX7~S?h-AHpp&3>+B{IEq)hL1qX|a^&WkE>zC@rDY9<@{qYXn@bx~%HjpIg@pzf-ct!{s{LRI^GfHW(;GRD#fl0a;7VVf1f47M0Vt_fSquBG}a^R3 z3m3rzM0c?3_tnF#*r%`iYRVpz9?X3u@t`w3#jiTEu< z1eCM)-{q}sS@u0d`|SR}tFvpE_3?P(vw5WOCSn%f_Tnh3;h;>Aao$M4#cL*OGsT<1 z7aY~C%W{c^=kHTbF;yt3#zJl@25(!@i|@e-4Pr0d=(y&}fuUyUJR>s2@@wS=CDOb) zPbQwE;d4_lsC5HYob`nrd7W~jDE?0l<)z1j`1pQK{4R67qQUXapC(SLTJqRZ_6X5# zqpMqKZdu5JNbQSW{o2YKMQKUj^NV-yqNfk#_RD*MWEV38VoNlBf9rRmU-)*KOl)(9 zUQzHT4_j(+jmKDQ#N0^nFw4ElyC=7-ADwV%J=_W185Xv*7=hkSTHtSH5eAbNYkcyOdVCookM5Pp3H8~hBm!965w z4n_|ftk>%0?Q2QzA{I9z&0c}q_-vlpOo%(9N`H$#ip0=RsHYMl%R3YHWiS7Ex7Z5F znHt*oEK-+NFkDM;Q>;(($CRA?wLWIP9yt$EV2K zg+Yo|8b(75drGniPSURz`?tuvs5y3{MjYIhqrT=mC>SfPyGwix-EkeR`0RTLs2UuO zt(XL}A}no0b)IO+I}5$gm0^EL3cZYGn5;DYBgFF583=ZdRwuAo$^E(5{ct9f<60J} z*)vKqAf7L{T$n%^-SFZ!KayB5VK!|c~aMPNWM z?y`1*Ig0F?LwX;lB3vaOu#n=Wg2rDTMsbIx_wU`KZLXSa_)6S@<5u0jODYun&cEw5 zHK@=2yOy}Y!~MGkG^yeL`EE`&xZ}S|SxFO3`R}{Y5g_XQ&zG5SwaowT-MBJoX)rJ7 zZWztmcwXI5+#9xw1%44X+jKBMMroiaqbup8ovl46o!`7^J7ZG_40!K6s`B?WE1~Eb zI(HFb3%=eY3}YSz5g4o-8<#^TCns%L*1NdxJR58NpC&|Ef0`zcULQ&M_p=;FAx@TH zEiv3*@y8J8BO(9!?|HKwUy$<&F28hju^RPvhT8YvA|%ar959npVCdph717j&j6uTa-61}1g^GEXORkh^=++^TQ&9dfQt6g$u(Hpyyx;zfwuiv46w0) zf`r011;kiQAJz>(;wA+!y-)~~RQYn!IgvL6G@U8FLW_GrOIk$|!|z*NU4pG0Xz8xk z;kY04VMTg?^wtbG?iYnh1MEN(pd3H^B{v%kZ%RMk&D#WZ(*S@G=N$)f6A$}%WiTN@RCh~9rEex78m6)_clrDP$ z{qZJ{QlrPUW3U5k=eGbBqdlvFQ_E8$&1-z_&g||4Vfm?j~m3*tU2a{h?!)W-g0KHdmWZ1ws zJ_`Nz^=lJQ)}QrHnF3;5{H@pOKvxUyUdjj(;xk@2WuX7U;|2E_$vmF%wW7X>ttYEqLia zuGRyAu^Djg4bh?=k-IqE$%aKK5@0U};LTD<{mIw_@)xZbXpnt(h2Xc<()<`)Lz5Xm z0zn^*SfqPqQAW$ak7N44S`kmPYV^B=;IjuskNscQa#J3G`&7YsqD~4I#8rvB><+9dCQ>u+ER^qCs!M5+-Bax1Z~{75R0R)vC(qC z{Byt98iAcj=QGW=S(bkG`6gx_h(l0-E+MF5pJ)CxI#3cGi~w{Q z!{Ho0;Ak{SZ?{jo@kGe^&r3#!L3!5Vc(iU>)^Hwicy?Ma3*z=F0UAojyUiZ<#X>-N zv+HWtb`lEM7l=IQBDRDKfdW+(Z3jlT|{&n?)iyOo<>+w=59-RMZXn$zAz(B zc={gKLz(A`w|kwp(e06KW^4srE-E=oG?Lg@@yZq1Q%6LWq29KyM9g+b^}{r!zk@G` zW})NaoWW=FqqR|qdhvXw6PV3*ym?;|=KSp!`FCaEEE^=1Rgcidg~6vIso*(wwb3u) z`kX=FHa(-~COVWA4Qt%^NeN#roYGJ?Rt6hx{)if9JWLEa598N3lsPoBRL69I0VQSy z8`M^rZl?%xURJebWn{}N9uytD4$t3kAZK1Mf%b^* z;ebQ&5=H*i4bDJ8!gW+sjZiR3?>|p=R_bvNG5D5FJYh)>nEhuy+n_NDQa}s`;1AGJ zm%Wt==4!@$>csHycZ%&zf;)P!7*A?dMF@s&^CfHDzvuI$DZ%a3Ib zv15tQ94;Aw1iE(B`}jw*GO!(NMQk6o(x8Egl3wU%?3+8su&v8i| zy=(=IK%X4NaSjP@gVe83C5z{7Keup6!#psCV=IGc01xweVKD8p)%6e<(oXnWaUD4!OY7}D<3pFV3vcLdH;K6rjFqL6Lx z)R}m|(KP+;F*VN_hiB_GHh)Z16?H;gs-|E%ZlefS-+pb3ZimHw;WQg^7`2uD>xMI* z{`14ngvve`QdZ!?hui-Df-L0=dGHxA*?)qoGeY2_=|sU_;jUc@u*9By$2o6s4aoid zL!iBeG%y13gBrq|C`dBFZgD$0xPZNCXGgF9J<;i8!J_4SWInSby2n!I%$ z-P5(@=8cQ@Mu{&~e){xj*_Ru4fA%rv)>*=SUIJX`VFRQX8CbmXzpQ@y7fZHRzD0j53RKXFq=&! zxOsZJp}ZRW{8{{O5P?+QG#Ir2YC$sqv{ZDZxa~4mD&?4Qy61jD=-8z7C*;&iCL1yw zV9l`>Z7N2tc`%6y0+!Z{?#YZa=MB+NH9kOVu=P0DvXLZgi?DY z7gI}sNYTCI!du2GeXHEh4Jux0pBmm83x$3Q+L~*#)n+pWJJw`twgrHxaF8KP-XZ^7 zC5hwj?#n>tE`QZb0-y^EZ%!l(++(ugcgW8CwFj~~`rqoU0raUdmA{5$+hPr*ea|YU z$fyzQ^^4#LA{B{?0m)1iks0q1W+(|Lw7PGrjnPpRcI)LM)hRwBS2`fs!_+Ia^4SjPTD8p`jF?4kPHcFI8-NBg zh$)LydsGtA(@i_gr`#ZMC5o$4AuSm6zxAvJB_FpB78z|mK{k*UptprglOxO3s}b8v zmNAeJG$ndI0qQl)&l8{0M9Kkh+^pmvB7C$oK#IeAh@a7+oh|dlP8mn6rTP15-3*cjzB=rGiy9WH)?N;QB0fU+2K#t0n z)0*MF@ft^l-;PZImk~^!q1*ApJ|3H++*8c|1rSYMQMiLgr6Y?|8 zA7i-w$e!#!80yOz>M_?<7bX5=_}|>ao>kb*G{Jgnqqk$W(+`eNdokN6z2oaBm}~K{ zZYRE1wmb6ngb`4d)Lxv|3(mH7G+cgH8ht>Ay) zoQrbvzOlM-!iw`Zoif3%ui)%oik>MEq2xISz&fZ-P4`91DWX}=Q|S~rbal_|VjHmy z{yZ#8Jy%XnLqxtWM8+EtQ+5#g%UPd4+Uk7_=y8nl+d=QQ<6|d}MZP~vZ{#MFBqoP& z2tnE{gc<1GxVup9#rc3 zIlfYRk@k1ph&?Q$5=Vu}0wn_*X^u?Nzp|!zj^0{u2YQ8wG^5U*hA1ghpVo@t=3w?d z>w{bA1$EUrQUcKwZYc}jcG0Zqq*(%JG|jfospQ3HHpfuT%}T zkTYc`<8L&YSjtvzVyC6vf!7k%K^B4O6aSbPC%zx+qgc-=SaED(sMNE5#JJ2f!@tHg zhm7YcmOi!%h1&qckIMjCyGd}rQHMGJICY*6eC~0Okh7Pm3U13_RWA?(Yimh;h{rXX ztXh|T!Z83|YHVO{lV)H3MoRpsfg#W>N02J$_I*I!d{lN)nDeBbH~wk6{k-ITUSJ)* zeJL(l&asJZIPn5HogBz3!5vsIAF9V6s}LH@4$8~grT`jzYh9ajCznm!tfQ_QgaVsQO+xw{ z(*7%#@rX6y{4LwpgkNyjX-aSk7kf8&lG*35RV3lR4_lI@U3PEf!i3m7jG z?^xo2tapaDR@;$%YMFJAq9wJMRaq)1!tS+u-hIwh8lhrSmD@y&GY(S2M+D`vKNJj3lqX zl7cn2NEf8p;aqmEzyFPDHYNzK zf*cY3g4O-?3-B&R5!n;li`Se|M%lfK${*?+GkI1rHx+5%;c1DeDBgbb(_5u%(Z*=Q z*X=@@eGC_kS*AGP-=B^YW_h$gSgE(fRBEm*i?ASmE!lH==!Oiw zShe+mpIg4TonUyAxlKYWzz)>rvovkSy>Px5Oy~9v{WL6adHbCVQHJ%kG(y<#-Nr{o zaqp{9eFf$R`YL5!iLu*B48a}lZ?_*REqGjTT+s+BL>{Cp6oUNpXj^6ifL_G6r`z`& z+y2_P7u=QCnX@Em$zpr6H)WrpLe@2tCHI1|SF0<7_}JWwDdQr~{bT$E<%_st{+f%G z5U8i5K>Z?~J!c5}-(Blq%h{*c`;JDq=#5bxn8S5n)c=@6hI3=O&ogiFAi14Y&yRcx z`%h;?+f6c>jAN^)PJbo(D-j1{t{X=+r@y4nPh6t!@60F{Jjz0^=1Eo;kPkFu{%rUP z1>(mM>v@>BnGupkB4#;hu>Q`99ejtf+xN38`3l5+UQ#PPp$o7nfHit7h#D8(<@ZPQ z>w@zs@;(5GM-L>nYJel|;*1)f?VMz#Xv7#4o=;oZg}Eg>v@LaS=<8zFoR6bbP89I1 z1Bo6L?*9y-0f2%I3{e5EYDJ)q3P7&&bo$e3)SgJm+MYO2h#pTte=&ojiSk(7pya%fW(h_61&D{p8Bt(JknHgj%MXqXqN9l;LgU*$KjmVu!Kw(mMv)cU_oG`cF{ zgts{JbPOD%?@qrI)38lYKUO-@Nx*;V7JFZE+mgPzN;u;KuyghAJrb-#V7HNj)bEJS z1ZvNC!!vbSNQt|SW}|lfPY?f@vifd)xB`E1HtN8`l~IVY?JO0U&R{WQwH_XY&NnwD zIzXk3KyekWGvz9Oi_{RusiU>i?&Oo~u2t z)t9U`s7!3;pt-T)n7(H2x)KNU9dK?b2fWLZF~aBUvd`PJ*wj-Lrua?>w5|vN?h-{>)n$#}T<^aX z`wy5OvGWPS3AJYjYJ{d?L#2K4e!f(;RCGSMRySbOLe=-K-pXwh+=+11y+7+>*5tGt z0{z}u!A4d`*DlIXF8Z=-8{?xHsG%Tpl-V2eB6c=k8p}fLGk;Am&YW=1{0OVemS%-W zdNz$RGMT<7bF{cdyQeZWQ}~qLc<{GD(Ejv@&d!t48>Wh#T%H8Y@%V_f^!1~OxC1nr_ZLvyf~ z-zbdpPnh``}X&28+rU z+(4B(*kssnUt6>kd!e$lQt@2n=-q9aMl%f+#x+I#*_X+`J94YkdWe@jJGj=8k$t-K zWDWA~kJ$?FAn?f1)73i;hAsP!+!-zo=0$g&0ruuDWYXXJh-_LM$ zOOn|*9K+KxETS?0dJAz>>K6rzBBz~9ac#1p! z?ji$j{6DHwODuo$Y5x~xt=l}P?i6vsanNvj25{}JY}B2+3c%r_+xGuOa$$u4WX>Xo z^Z?@7CM}`Ywe1UqOqv1``W!*=CkT-FGS|-|8bGzG31p5K(g5*m6ZEtG%gMv_kC*{9 z8VVp9{pp_3c9_vA`{`ku97smtSYESExRhea>!pE@hdQi%IQFOZVZwIphNmFNY{0c= z&hU??K(S-xqaApyXwxZ6tM4A8NTEK!5m=kT;0yvLyk{bewA znvZ3@?r6KrelF|10LZsa5dE_Bb)+*;}2}Iy^0;%WfcH7JueXF2yYaQqD5~kRI;Iq);a~JkgI02DL{~ z88B*Jit?`>b2%mEW!io~#wmEu9%%;dpfl3@mAWL33G6|a%+H~7%p)K>adUC~zLDC} z%f_Pt#9k*W*a8<&_@Q@e#B{wg=#Qvv=F$`lC$sE2d;s?20RH|4LTqvMi;|1+xnGI( z_@Q0*Jda6tzNYpPC0qzHa1KC4e~Xb5AB7x1a_VV_nehV{io}$V&<&#B6l>?}8<>IX zlD+>m!W3)n0?USMfL`{s`#|iF@lq(!BoS=g(tB_D2SPRwI^4Vv?ku&OpWPHLJ_+md z%||%QwFww}1?sxC|u}?A|UD9-`%UGb4VruK2lMihe7VIcdpt z?B<#l!=wUG`}e%y$3l0!9P3ES#q7h6`9?)-luacGdM=0 zCtoCQOK{!pkKO&;)t$dt+K2*OVw@%5L#d{S@t-SQOq0mv(|=2h3M^;TYIOoxm}qjl z!<>$pt-E2(O1!#3^#c0PSMOxGUO#WTlLct4xV|wnIBx5B+X?jAg5wg$+VZFWGizHRd%`f;6y zt7w3bBG@WxcA$A9wt#p^1||l>z>w9+Ope_M1O}X`g8*B**c9yu#86FFk)V9*bZ~9n z*R7{{lQToj!C$a(uV9L|sG5B}(Ui!>PlqtX*-gAhkSG3YjskqEPIyhMw|n92{Nxjdol zP1ifuVQ9p|4>!BmPOQi7*cX9RecNtb;XPrMMA0u5igt zF30wR=Q=G$l$)#dmg%*ba=Nn>Fl7*2Ro;xHW2{Ou%~v=!&5@P#9MoYy4&k@OC@J~^ z?O2&Bvb*2LVT=4kgU|Biwv~`t1_CGz3Rh3gKl<1~ZwZn+Po$8IBC}wNqK{1K4W~Zd zK-sa_8y@pMS19S6D`41GVG-zi0@5x^pK`inS(i17Az&kwK0#LlkZZmSL*IOokbxXKRVxW-0`s z%;@2CUuMb&AB5Q&f*IW~G{p*hTcsk)#EBlokPLVoe48pprO zkgsklkol(>eE6FKGP8Hva4BqP5y;D5KY2z4&zF;-6sjz^2ow0q{nMLD=UyMFA|XUG z_j*5x&?I6u#Of{@591MIp~&A0x`;o1PzmLvq)O^+tbh{7+(yG1%ab?26xxSEhHsZB zbXz4@WIUY$4k5I`M~UDl$JW7CgL7GIk1QaHLrBB?n9PrySprwmvgX>p?;(IX2QAUb z9rs6OWyY{H>+2F9$8xHLwhjREK-UZo<%OV(*_dJmNgQ~}0BQ#cvf?G{zyNM`8J!Ei z+976XhAIfOm_3_Qi%usYq$CtQ$medX&g@-Y;{xbd7pu*m)v75CSBd-+*Pguw~z zN$Q5ZuBz$FibMk%IuOijvVd^VZ?@%ZyrG#DL}d(YB=#KjG?SMAvGM7G%#uW|bljlW zA0-v^G)0)GtBj$5OVp8$k@x|Z6bXq4m($CS zwp{!;Zf9tw;Ui{oQ0(XFr&{EST8i;B%q^b!y0z|*4R)b0)(&TEXl&kli2M)z#8@6K*S&^&*Fqyd?c8Y z_v%WbWZ*&x+(vq^Qkr1)Atyb-tnoe&{Tp-KqJk?Mg+k{~fV+tti~Ayz+n)@ze1%+4 zZ8xcVVZsUYFC*OfWLqe z^R{~2yU)V<3YTtolvi!1wZSScl6k+Q$uD*o#hX?9n2mBJ#s-gb|7PYO^9*+PU-R&! zlyUf@V4c^(a{r+RFTgB61V^jFy0;~9VbFPoEjFXBfb-a^(tsRg*Y3Cw437vt`Cy@F zbbNDZxsa}ry5heFHO;UnXUmP}4uBC`N^-Kyy#a@*XfH)Lf}oj-uolwSXoUx7Y>qiI zK;uO$hD)qmdaZ|6p6<7s4dFtGJ40v<<{S}zPQ>jDwo$Q+~Z#ok36_8Lz zQ@6QHZuG07xoJyO!6{Rw862+UjylwDde+bsex|$4V7q2XzlWvj>>J99x3|KLmVnX4&|2|e;` zT65haoG2GxXwRn(B%R?#s^ThIL_XpR3!;7w$tXQ)5#K7cV+Umcl$~tn`)`L+pl{&y zW@LqQt7RxxF^FhXjb_NCoRWiL)oJooPe=vJ1&N*DAhD8Wavw{&E(Ve;(&pT((s1LOeIf0~wbkC9tXlI#nCxjg9YKQ1@m<=FD}`1~EB5 zPW=>t=tZJ9ZC|VChC-ttpMawQ$cPwAc9@AuRKp5>^V=n&8dzhN3k=!4)mCvbYE>NG z>aZ=WeD(1|oz8Gy?47qT)dc{5rlb@b(52qK#D^e9ls`Q0JWB;rTJnHkSV40VR9ww| zk!F)6dyZa%)6azp-pO&|KQ^`gA-pMc&r<7HMR;>_B*QRYf7bO{57J7>*bcrPrA~7= zuT=uLhhOHeH>bMId8q2P)0WIj{M5|w7`o+@iax;2FsWDvuYcuTq72Wra0c4u%{vks zn4MX%y|%9eV7)*Lk6!6U*$FAgYNs#1Vhty2t4FGVRPpg=Nx8v{}~dJR;~?<*U% zNY$A~;}3NJhurX{0fjnzyYKborlgB^>WKxzRSpQhxh18F+?#Cd9Q_}u;Xb#l^RrQD zPz|6&hXXrUOQL(8jHKBUn*LDMk@9Hci6BPeLl_#S;;Ki}KF8+g zt4{BQ_`Y>T*%B;0SQ0F<0vl{|W~mNw()qnO+K`nJd=+dkJYU~lq@|E3;x$6?D4BFo z#Ym~a=XR2EAjos#*_y=a-aRh2r~w<>=pi6k(r|I4tq@Q+b;dIsf;vM(Hr^b+tL~6~ zB>sQ}pB0@;!!Vt4B1EP^WI9jo%u;)lXhH3&*>B@+b}Boh3@T~e9)x_4W})qmqoOf` zCMwX62-GTk;j8iQm2;WuOTQx5NmJNX@!rR510%Nb3uq#Ge-j;(B`#ij}+oR16DJ*ZHO zmdg6AIP(Zj=FV8sB|c0?+ephN&Wq5?#5V$2uUd1m{ew~osG#wFk~Ck9wr3Tjgl*uD z1wfUO9XzHi|DMvR;l#vn6gt@Ubj!G*3lE<_9ZJK*CwmKr!g^*L69yFmU662%!<7Wp zb8QL0AL~Y}RpH>K12lg8J;+2pR?CqYi*mqsoTaA*Kr|# z(Vc5}?pW9uM&J%b&W5GvTHB?+nNo~kdi<}MSpQPEzEHA&Hn22y74zw9T{2`Sh>6-D zXwnpIdiYn-xEYWMA->QW2>#8>Ade9A26Rb;r7$T6g)am~0g4U6;qt}-Seg4r$JGWw zXKsk)2DNLVssUN<8nA;3WI9<3hIrBlOT~?nWn#$eYY#}B8iB)*5fzST3L6=@T>7l} zO?H`bcP_W@s@FI%z;omfdjns7Vd%S;291s;X(q4|Ck}`*aHnj1fjko;T1;h2obGo{ z0E-Y(kSlsakQvL9hc&DGXSYO8FD#DFOaWrrX7@OMstKWhD7+AdDtiaCkeG6};X2vx z^wsR)2F!w^6}MVquzo1>Zx{i3&x>h_M5Ew}asXF(q1LhM^BGA&plv4BCxRnCTJ9pZ znaL@D!E)J&=T3p+h!GWX8G~z)$boXa#`n7w&hp zdEFTbyw5<>y$NvB^P0E;mHY_g(j<@p9Dmg>!zy=&evgtsbGVN$70aj5002vGsUL6* zAI(xjWL2w5T2kXgKU5K(ASU5 zT|jDTZj%Kx-WExS$%@L#MuCpsTi{1esto0|P`}>~&PBuJXHq!UVlzZ1F{j#y7>4=3(mlWz0AWFp^;L^Whp9W%#CE;PdLZ}p#cjaJV%(G+`}trh3}o#9GGrhf zbVl|)?|C*jFr+d9*kcnywfj%<3qYql>>|t44?*G{)4~w&a+{Neg`9?*V+T;o46!EH z1@GHL!5r3`X|TeyLU#JM(UdG@KLPigZrC00t|k(_R$ey{z^5Fr3^bdyptaSX%dcW( zh0$um=h{S4F0X%x5}FL`y|Yih+4ob+zy)zzY|gYzPMBuy(URODA=!0Bq!aJCREdPx z8ka$n;AZjrR(+Xmh3*98zCH4+&EpzERe2eaBLD`9E{3RqHX=n-hV*e!14|%#_w1j!(}c_T_HI6lNuRu2)0U~8|EW|3k1|G#5jjZax(XTH{GEQ zfj2w=K@Y`Ud&CEc2%^i3ju*7Lzt=O*a6M?in``umm;+f{LJ9~ z1T2Rtz6a{uyyr}>u<%Ex>NBN`sDJ?s@ew-{yb#mI#=hJATD(R}EJV!IK(-)E7wAs@ z0b6_%Zk!2m{T+1W-*7Y&Zp4$w{cInRUhn{YGI=9hr8JUBa#^J+%x&AZAFcrD0AUoX zO2j&BqQl@;%~qHse;r}ESh`9QW2fT5^iPOf{a{GQ1KxLzC27k&?d1>t)M~QExG99zEbhGj_WibU3Oj3}NzX*98_Js)vfHX2t-{3t4 zy=x3UrZ;+=053l{8RbG^O$01(7yeB=as09VXIt5{q7lsZ$giDh+!hHgnz>p{H=qd| zLjRRjc?JKx4+YB?ZXa#1ZqhXl#>eW0ZMHdhi9y+fJCselD*;q7I_b)gF%Sl~Ajk2ix&nN)^~VZ-n{*#8Zuh zslA%`kWZtw0)Z#F26g4VdP`TEs3-3dANG;D1QIi}*yWXPhYy6+E&B1pwg44xG&8af z2_gr+{2^Kw!%kPXFW{jbp(r*?cwxTG+&1*mqYXAWRSWmD0)sac?&LfMca~XKFUYd* zl*YiMs#O_#3L?8Zi?5XA1B&GzssIauxmzUo`2JzyA$T!fjmCk!7QfQDqk^kWZ!R#~ z6@1$ zKBd14h*i>II*Z3)%WEASH0jSd)k7&&bR$}^dkMfTOLiy)!F!JE;+Wl>iBfYWfH9`m zHED&MNn|J8@2gxV`!NzN3fKa=1h0g~LnvVH?nZblmcJvGC(mSs8-JNgB%MK~0Om>h zty@zix45R`LMdP$b0_L3!-wrE^A_UZ*6>^PcRb*?3jKsuVJ)zla+s7Sb^r6vYg;8^ z{+@|pE^Q5c1SOv_wqo^x6)ZKty`g43Xm5D@WPn4=R^|vS^<{U=9#P7xo3lOEosJUP zhKzHTg54E=WBeS#-K5K5rdP(ew{YGS=i+^Keyw*V+BSuF3tuq~O9Cd0-NQFJea{uX zvSj*k;9e1lJYF=y-c|CbFrVIK-ep(}nqKdlDFId_6@O9`YOjGE>W=aCkA`;t9r;MV zJ_liWXIuM_=V7-OUIS&K=@_{LKvcWm)->h26GlzAY1O)D+@KAvU>@uMH9h_ulaC z__2`K!-pU~Jm<$<s>A7?eRV6P15}7FX?9?>1i72-??rhWIdd8G|fu28lVeOXX4u%ni6?yN;QDrEZ+py z@85X_I{ev<=&#wG-j6nZ=TR&CJ#QRbrvne#p{J`|%mpPbDY))Y6 zRq-Krz9lvD{T6taVGGnRX_gOO>xT{Mg3gM^oE{@!8I$wkVSM(4y^6Q}zs$F~XeNSi zQ*{_z4v-XSoMtQMu=k(ff=1Xi>lEdyI5%Xc#AgumDQ)IuEq-UXRnrmlZFe;LFg?GSFR-@y(c?@;y8 z)NV=+xd)x`o+J!AQTPD=^ea37b;Bm>0%K;Q6<}TFjjwn<$lE8xQ6d9)iA*GdT=ruY zaocdLiq|>&932u~+SFy}Q>~tq`=2O2Nc7+C<;&C?aIGV3fnmwvJgub5=C+@y3!3U4 zaWazDBW(xS4n#AQiF{2L!~AW*3dR>@0vP(jrYR2lyfb2gUIbyS3#AO$8+lsOiMA$IQ!zgNqvFKyp5F( z!)5$7L&c>B?NJWkd6i2&4)=aaeNGvQ3gXV`GB4(J`7W^jo|)_B3LqKYH(-@RmCw%>N1 z_+b$;z`h7l9Uah=!|=iWml$$+j@Nt>%nB9aX9kg85GBJF(l)*{Zo8nauuxB<)Mg4k z@%%Ti%lV5FK@7ef`s@EwUF~mwA&}f=|C3dM+!RbSz84U?{D_Mw=nO*WdAL!yFDVTz zZO;H(Be}A&a>3*;O-@3dD-DjYHZ3$+w;ygs( z_={6vYtr#!@H6iNQ-_x6nFl`1(3R+s*qMkD>O44ucVtVr!m2M#_Jv*l>jJhezaV9~u|NNuJY6Ex*4ohO7WS{Nu_tP^6 zb_2&8eDPAHoJOA1-UYz`FYX~K7 z&SV@+A%71IfP$Ak5ah-#9y6Sc;&gKoTE4V@$A=j+n(2&9^Nu^6`5a)PPjG^%%q754Ot2)GyhwT{+y>!pg9B*ouAoYZx861 z{OL+Ytlv%`XK9IKVuEmnARs4B*V+TQECbZly#Tna8&0^5d04mu&2RQkb;x<3hZf+I z&%1u}lTy$s**xK$1S=B>*xp;&7$AGw{g27rh_06dgx z?E%sVHRPU}?F1ZcLPDG`(iBj>lakrTqonxt?ia8ff=bb(FG;qcx;{IU2}hi31O-{j z6_7W@-2qnVOGS!%tt!Z?7hZuNCX((0Qoe;Z6z#FxWMpDns{C#8zJQt#Xwn#j_!!gzXKH z6{Uu;0CPz0Eo;#fczDhoD}Eh<#OK|&?p2m8uvdi2>l-M2C|K8BC%K1Sk7#YlZMmN4 zQBqU8l96#RpPF9z@oI*6mEkJQD58H9p@P`$+svEuu)?7Ys2T|`Fabp8Bh)Nb1YB)i z0}_C4A2?Y-FUoJ7iGsGD#Bc|9nSmjA&4tV2O{zH3ynu>0KnNRS-vhec^kV~{O20M& zpotY_;rUy7nkIoU)c}06Wf;iSF&(Z2O;tbV^GM^P(yhHf{zC+*(SC_mpO)ATa}s{! zF?sd*zC{Fv?H9n1l4h}ugeYpyDgej5U%u$)?}yKc|NNpU91j-aj3r?bZCV~IYz*xE z8dGVL>4*eA@YIPpl`^8&%K(2TPny9uT$g^2N7~>nx?&-_K@`zI#jF9^dtHtUW&oPH z@JcZ96=OCjuY1pM7!_gx@bJ2FCPpu}C!eRGl&x#A-$gc(yX^Nly^KAt%&(0=S#KGM zskVAYk(94VDL$wMOCBIWCcYxKjU=;nT^+Mc4o&g}Wl&weRO*}Zn*t}ObA$;=S!V<$vMV}Yc<9~ld!QYMwOcg@(h zr?5hsUwp*G{Ko0*`zgD`v73F_b)C3HAmiio%0)8*4o&ifYX_p3=UvWuvA*LEm?YW4 zRB6KYEFk9IK#EKx6+9jU3zP?FNKlMZ`N-E?a`*bC30N5gjkuKF&mP850H*~0L1SpD{logao6PQ(o{IySEyr3JZ_3bYM z!~jbuu_U^bjiTVtLKmZHPgdx%N30Kk%Y;ets{!>z5znm`pV5WP+0{nnJktJ;MZ-cO zZ*=2$q)%CYXu*=P0BlReEUD(aetC>%{KXhg5$_|#3EsInNzJ=qna#ldbOZ!fTfdev zATum|Nki|)`?gFbB< zV0cmV`x#hx9xa~3BanBmsVN0LjZ|rL!QFWeZzM#Z5e@?htPLKZohHVP^1xOMc+ThY zp@)5~>K?mn2t*tRxXOHup-_zBEUf1OZ4#~ATDq9u)3r;P3I?{f z*p628p9_Nck}oPQe)0ygP#Yyei63OfS$?wkfhU3^002jAgHg6m=PNy&YTLhaSFY>G z$|R8K%Tu>&-DTt;b`^;2n!V$fsQMiA>Wj!qS?Y_=|J=y>I10R?v~HeB5Xrdd=x?IG zed|4U0nxXu@7AH(Y!vP2V%ha23N#C4C?qS?v^cx}_P<1A`k?8qpQ<%Ub)+sa zn{1ah5fNoJqK!)TkHAC%Yai+s<1P1!`$4ss3|)_=MijuIhXwa=R+Ys*NF;_wy0gE! zX?#aL-=NgaKn)jXwb=;fpCV|ts{^}4fOqj~OBmi;TF`faI$f2TJ%sZD_v`2j20$TEpevt}LKoUYPrahjU2Dm==L!@-1jvj0~=0z zzvTyL?i)@gkUbqt0S=TrU7wpgFq)hF=R8M0)Uk)WjftUFG!t--AYl?8LEd6jimT&K z=MA@1GNtQ{YXQI7l0BgpcFs)jili6%`Lj_XJntrG7A`s3$H~bk2fh|hF7juyi!x(k zhA$nMo-g7)p(qrf*XO&+cQXpD;h=LB^j|zVs{h$9ekTIY%dB-bUoDQTzU}cKUD#W? zjJBNdjaE8Mb5RoiDUfia)asnS++|-m&^fNpCni6fJpRUTm%vNEy##mYLAr?bNs1Xj z;T|7u=-|W`?G&+-FGhMC8YcCXu5Pn_?JkNu zWo-8CZOfV|vlmC^SSNYewL0U~jfH}XlM&wiIH5~({LR|%#0gh?@DNwDg+(7bS(Mk0 z?&G`Ai9XCvk0J6%t!VN7>7t~o&o{al@9nKYeSg{EDXjaUr{@+Dlk^>{GEy0|Iw#D^ z$*Geb|EVD)nZ@9+gF9MzHP!v$7Pe;fx|gbkRQX-uv6J4mGP71qoa>s9XJn~Zrc=j= z_g8DX)~e$Er*{vF3HD#A~ef7fR*T9QTJy^FHGOp4rhk z?B|7dDuN=NmhTT#%tni(S}rQY*nen~#=1Q?j#ABgx?>r=l|V$rpm&^^yeb)h^`>qJ zDN7qKw!-?jA8kE`P3)$gBSaY;3=eqsq*6=nndvDH&gxR1hAzfA=SDxleyA;~ef>$i z%qxT|)%JzqzAXRo$%~<`l+K%A-kL#k$DCDPamB%)zP11NjmD(~jDgzEr1(-5iDnFE zrH~uSvRk4O{Vs~Q-7S1%9CN+8RUqH9O(5U>mfHqx_0P`L4y`Lom{5BTeFSl1NW?m^ zBdaSF`?=+BooxEmRyv;fsEf$N^qgmlNsF?2i+NG)B{KIGtEDyX9CgVTB;_mAj%iU% zN6cI6Z_<=h&PFA<<`JU{9lJLkO-Q;$BGUAf-RqP!5m#KBOFIs<7SfYBT7IyKPY-3} zm27ldEVRXQH}ZtNkoeQ^;$u>IePauCbuEgmFvq{9NG)$<$@rG6W z&(K`F!A4Eu*kdaHmlb0&GbYh#{hc~rnZ;{o21Qa7+J(H@En8?(9V$bi~Yu(~k3O zd#bFk<>MElzv_x)J&hl3vFzT|TW%{5V-iR2ZXF#F2Rg(z&MD+i^co>CjfN+dfoWW;lPYza)9VfxKnfE5gEKyrYjVlHZ{iKcJv2kDe}iYuL`lETe@d&*)#sJj3?|*zwIGrJ9Bj=hF;*d zmh$1O-V&v_^;5LyCYRfm&VZ-%A@Hw!)P5DL#(WKgcrI!}_&H^_46-`FaN|6Fmk_vk zONB}TMTMkI7@5CSY29bBoYui^r+K#{p-&*8sGU6^`~18@9J`J|;|^E$+eKOJNRf18 zvNOZQ#apMuu01$jv#e@O*1adzu6jb(ey9l3;^b{GIc382qk)spcYLC+!Rnk&GpDC- z?dS~z^^_JWs*Q`1J2=h9p7luWLblIbNcSEkxwRVqVMl|L%A(bH9&N_ZI!=5yr-ZTQX-u(- zjacl-;HSnMj>v&-d#C;>(OS~Hq|+MPC?719T>M^?J|4vrb++U;UkpDNpXN4XzR|4V z8xc6b(^Fws^khV4P!9Y##^~eXew9;eCY=U19PJe%uEU)xXKN40^j6XDuGxNKAI^Jh zQ(zWV!;~CULqN*7`N$-Y@o}vWbuJ0hYDEjfGpX>1;P;&f+FbX+SAr5x^0nBq$KR*f zW_s$MPnv13nJKGW7Reg_6JxqsyjPV??ZGxnH+!AOr+PCMZAA@>i24n!d!daX zc3vaAE{{xfFr1dcGqtHR5%+9z*u9W75v+*mWslBG{Txy*5p69E3F{m3$(UnPB7ciL@R&J_dag*0gO3sjj_KWB(PIG$vk0D zYxv@2j%V^S)a*2HjiFtnYU$gH86@LEeVA3woVfY648vY8)O|NpnQ4pBuoI$Th)i^x zF(wc4_mqZAhB5n?}&1;fNLd5pBGhUXHs+|fm9wDS%+n@KFqvo7&psta`-b>B24Z9G#yP%WNR+G)y@&- zh|GHJYcaWMou79V{-@F`f7n8Iy=ubL$zZe3<@P6g1K4JA=4!f0z7|J~_Ac$ePs-KI z?a6qhrH1fBtw%R=nOklLQFMEiGOmw~z(@-@Mv~vKPQ7b5N{Lz@NuWFs30uo`6g%t~ z8Kmg0(C$6`eV^_!OKyD1w$_E);%#1;om7S1+d+GCKy(5?*XDAB=t1e-b6NfN}TfKPB4Ks2oRTjEu_I1im=RaJp9_m;LX|b z8k6=Wm?FimZzodM0%R`Vd7wq_o76#HuB)8GsZT<#RfWO6{DX(3v)_bG!nEFc!Krlh zwZF}J-}h4KU3!yI>zMgQ(YYrhYHyEi&Y?n@afhtr4o0oHe|DHbN|~dhw*sqj7Oh52 zn%0h&-sqbAN@h`LYq!1?w)SMPU!xMlTz&7QSAPd4-3G$NSJ!fQUbEvz>ju3T?Zb)1 zqnWWg{o>{Iw_KW^K1mlaHmdsN$zmd#{2A^o8tN@XN`H&nMDN(^4^df*L?QZ?SgPr! zr;gM1m%F}$Pf|C;Titp?!V^+fA<1))qX<;e-)6Z?btzwVzBh|Ghu<#H!7Wtu|Z0w^o z+L|SSnkOdv$C1UB2g@au@=X=Ekb#H1e+^W7M+}H9t4f(qVadnO3BEA8MvG}F3Z6db zODmK#pFNkz6Q=q$886dz>~=}*Wsp^ZB+IYD(oZm9Z8&7@TW9gL`=ost$XQo2rRb%= zD5t{iR)I-x=bp^A05oIC{K~a}P1X+?OGQMl(B68zM+lYKi@u?V@5??ZQN0RJ#u2YI zUM5G`Bq&*v%jV=xV_j5F7a9=dFA{8JcLrO_2C$#_tv_#+T8DnaUr!-Q8sN>^Pu zW+yA+f$XGb1yYXTkkG$jqHCX!nb7+TugX z)xma^Rsp3~R&1juCB|E#LP}Wf{XHHB5KllpLzlv#Tyc_eeC?9JN;j6S6yEEEBEW6jg8E&z8K6Ku)qw zWsAOec^_f5d|rY*V2=u$vO9RqL{^ry{Yg$zY5L$g4u*(GX{-Lxxhs^fX_pLgU9<7U z`;Mg#y<1v-654yw^dJj|U*0?Qu=9yId7#z(b2X#EQSEC#yIx_NMyg3*36}kUgYl>B z6z^%D*H;YLFuSHlx1)NtoBh)=i{Uc(=v%=-u1Cuy5vYB{&TG5nED@hQJ+B2KkCPQn zMC2x2BVks_DR{PEsn0pt5lOMt%!Jtn?_d~)yZ_qok(3-8Q~k+&mciVI)|^|ldcSqd z*8Sb>3mH}l!$%D8vzC4z>HJbXuX}x5@;PL#);E6jFhwinmyjYNL)Y#H&8?>KyP#ZX zyLXjJJHyGuv+vzF8R#TZUxNKCWzM98PaA3-mqijsCZ(Ot-FPwvnGm$1k6B8wp(~y87KP z)T%;(FU9fjyy!thuJcQ_qZjO&E{;;1^?A?VmH5dtIDqh6bl+9@pf*MK`d7PaHH$>x zU=eUI^z)Ye|NruT!A&5wPI4--*4dE3dAHre70;rSdP;IgG^kDXxB7vL>dG3@H2fm~-PT-nIGPgAVuwp-}gV-^dNb4p7txNNV$Trnq~6H;j!TkUN%> zO!Jo(duqXmG+h%fhpFr>wTGFa4Se9l>*{2nkD4^o&!A?gpU#Nnez2g0Fh@y208C~o zYR|(xOv+J&EN{Rr1rP5z0d%f`(RLqbV)R0IQegkPhoW&(vDFL6ouj0Y{PF$o)u$6i zBix3*<384ltNOc^+%cS$8P`3VtyiYQ?PHWy$-p`6$imh^39SMukQnc-jM^RUEZZF) zY})~wXfB-^iFlU*9dv4H>T}OL0O;c375PKBa)W{!DEs-2`mBM!;Cs42;5KhyU*0cN zGhb6UQ@ZjxcFak{2-)d^ocC2Q{KjfCvQsj=)g^Mf_fSULE?ErJT0r#_HAi#-R4ryf z1=G+C5Yl5gYcpJ2T`NFq;IZwktq&bJXE^P@_Y55@9b#eRHSTgDx$$kUq4ViUAJgb7 z`|4SE;=W>ruTkx0=}MlPM3Lq-UGr7}`?3rppU&#tdZUpXd!Iiw2}vt?huy10n@nEo zop#+7INO6=--C$iq?797j7Z`nxAur}y~Qwzn%zQ7UmUWVfh@Ahq>8EbC6*ejUyu1(DNDdupLN!&5R{vf=1cA9?Nxz=Nj z#jOvKU)f4iwPfeJw<}n?+^7F%z4uS`Bp1tx<)O$*YwY;9x=AM^-{#Tn!O9h1mJMNKzQXsO6j&!|`hmE9F!X!`QWlP7jN zOTR$nJJAW~=!>bZK-C*BP|6ztl%ypLkO(9V7nlTm<}-T(x#f-m`8+zCA73jqv1s2$>7Xo{8ht+QpTQIsC#LsakYhYmwIcQ$=~qrAcGrk~OR!e+ zFMof{r=DF-A`_oATK^;#8B9TRz0dR6evlDW43q0YsNj=4?uNfFgop*OAErQs)I5)N zOW!}BAqaTtQ^m}$tlT?K4!WL}V2S7(b|rxEWG)J&tGQgdH>`B)GS@bEIv_N{@@ zE4o~j=n|gEvK+4fe-TCxTsrC$xxEuC=v(V#STsPMf4b6`vj6zR0G$ID4O8U^RXDA2 zJ+xOG$k2qQl?IGrm3`t;p#}$`OMVw0R8P@qIh>@aeIeBd`11sdLCMtD7AAQ;HlBMe zFZAaq8ct=QE}YdRtp2?@3y#UYKFjG2O302&<(u!^xKs&aw~@u0WGg5kiGmnX&*MQS zq~)sGy|6tS@vybconkOxz1YLLU{`>nX;}GM1F`K$usg>k)Kwx9@6u2O=Uq~l)iNLp z7zK2KMf0EWmL`GHZ(iy|@<2}o0~YYzkv277~-^ zYCg9BhtbfO&jQvlKh$Hx_l#pw9B%vsF7=D)$p!VLAKn6CJ+-a@h>du7Uo@exd{whz zF*$~q2^n8W-x7Vg6GJMRMLv`6yRoX|C$; z0*_7eU7*jY2xj#BZs4_yDLFa85V3B3a{SNHDtx2Ck$Cwv&ogF_2mBA0$HvWBN^T;{ z`yWEv*})WWO0aJJZyahVZl)#QOy8^l2Qy1!pOOECs{B{cP>m~R6ZWrV`iJ5wN0xVL zTpJr_X%{fZSvoCvmiTCW1N^uur~7c;Xf+V*K*TP8eT_9nqvM<0%$E(q zc4((bKnAVD#bgPRiy`b9f@e!R&>9vD;H5r}yq6Vk@w&w5KOO9Rg?3pN%gOwfO~xz* zAV^@jUzneF02VogZ_0EpzR=ZddE4b`<%Jm?LPiI)v2a3bD2XUE#M3!WZN;Jt+Wlj- zFNn5-Avuh=$W9zBZ>0Ok-HMdQs*i0k<%>f3MTZWevz?7f4zyS-L5oExx?YCZ|Ga0G zl7^s(2clc0WC>hZGx literal 0 HcmV?d00001 diff --git a/docs/src/assets/images/search-domain.png b/docs/src/assets/images/search-domain.png new file mode 100644 index 0000000000000000000000000000000000000000..0f75cfffe13483a2d2584b08a345d4c6cedd8653 GIT binary patch literal 94522 zcmeGEXH=8v7d{HdaX<$|EEMS~s3=vcf}uzg=}n}Iw9utXAfONaK5MII-Pn`A)=knF-TFi#2S_>G z3s}ocZRuQV>6mDL33rT=L-{HnpB-b1k2RhpzP{03w;Xw9$tUcjO@85b@WJR3}U@UnnO%_cES z;CRIU{EV~mpSl@lDHQu#nZsb#&KJ?ShbMlW+o9=EOo({Jrv8TtUHKuEBJOhO*Qs%b zo2T@+FWB>4W4c*Id*;$PlPkYYeP~zqe~=QJpqu~UD&(JMQDj0`eqHf`^E~p`chHYw z^HV}vX%e@=(5=@A|BOh&sRc1e>K%_KL+Q7ZduilhqM!DS&=02lF zv7Wykqbrxt0$+&J5U!r^0-RG*RO>3zHV3w!eeZ{C)k4%?fiG zAz;!PUcT)}s;YFv6xO?ae#;!&3}aTL|Mk!XvnD#zEdNC|FY>gXT2JQB`7T_QN}G8{ zvv+0Vce+|f%yrU)Lw0Huhjf}hX|VurKbYm}yEf%WdzLfh7KdD5qeU0e5wkk~C5j_G z-MxLH^)M1<(YnQSD1_Jk2ihRdwV|mrmhVsrP{<|$(RE4_g{%x0M4HsvNA2y-$GA@8N6WNu^{$ab zcg_l>P6TYT`^Ms%8(E^Erx=AFA$(kBS|{8>qepA(dNrq;eOxUnDX0GKsDhoYTSyWx zWD~U1n+Ao-_&@~eu$kdO$L1Y8Ti)e`cj5!0LZ(Pjhb;fXJ)lv<_qJ~AG^})bTYlU4 z(SBz{oBdkLdb=UjwPD(RCWzwd_46}px_bQeQ~^Zm@akk;uV#wq$1(ESG|r6-9C`|j zhl7mYnoH*ynk#hInWnbzqrH_%ig9LZyfOElM%-^%YbI!RMRRElW`T)Y>#d~d>9bn% zr-Y)|C2KIwX_Xc&lOS8-WZlm5kzzgGn)QJY8hV#=HP7bmi~HaWYn?`KaWr}p#`?!Z zESg8g%CrYR_N9swZ+n3wJg4P<&F-yG&x^=LTG)2NX+oe=pZw7QiFY9fx{aR@RcO;Y z*aRBU8-8=GI^-k`gF~iIQqx8Ueg6&-r$t)qH`oRoUo-4NG_-EY8>6-3-Y^}>Dxy7F zCjD+!K$U5vSo(E9Ib4M>>f2m%o>!HLPz|)6E~tAc>z{{|^>iSDpEG`shOGRi>$>i9>{t(zZC zGLA!8m3P4&+A=GAW@88|)K@5n1mp>i0A#4j?68>$4`C0JgRTM%RvQWZlx->T1G~A< z%e(MBTCq82ELwK0aeN=6BR`$wTwG&LX8h$+J#fIK*cTs0Z3F#@9C@=gn+q=h94of@ z{cjgp-+o#F4BN>xOqg9;Ls29Cx|aR|1BVoHE{5Z(MvPGskV(Dg@99GAzLD+HTQ}IW z#`9}#6BPl^{Q(4mDu$i81H4bJCsjV<#=!e4N~>GI^woY;_{wO=B4lbCaS_+(k;f&~ znz;{?kRu zIj??WW?(D~C@6M2*!}4X>*5Y@ae^8@VpoiGlR*$YFc7vh`>o}nooXJWpjmyN%OtXU zM*6eXdi^X9ZGTZf6@<&!(%-IBlO(_QBYvk5Qe0DI>DEG&!nJgv)HKxpXKHALJUjll zk&-IzFd0x^9BY;Hq9<9<uKV|yOILdf0KRJ%GmO*=VxE5t4f5(0E(9<+Rc(z*W zPTByQeaklJ#FZW(0%sbgd9QSiTfnJMh z3bBDG>d-`cp3Zcv(!yD|dHL#bn4J(+Zu6sMU{6TvVl-8@9+JeG+k{>Y6J`W&z2`dY zowcgqUCqh;-~{x*7lj;nR$RpA*5 zq$M@{t>0*b=;S;8UA{aF$Kfi%r~^+Rc$GfzS5ZL!TG$mn8|Q>3z5UPH^)}|8bqsV_ z?RTMHKLWb@pY`_Z`G40jh3FnZ$jU4V1;CEi<>!7~|HKN;`Oi{~pQtSYkcpdZ!LQRG z%5Mvodz3of<-fX0^QbpTNQ*F5!7K1<2?ZS^hkqbI>7xoKD0!`a!}{0lPqOn4lMM0XkjfD$Qr_)$yUqcUk{*1fKg}pmQ!qS#8=u z;!&#G8Kvc4qXN1`x4_;bo#4g4&R>uvsGWZqKs}hZ0XwUX`{Z?Z0FnG^2S|7ACRVpS zCnJw(t^2}TrhkrKPJQrCV?c3l{@)WI(En41kwXCgkR?s>BAWem) zB6Fp^aL=;~T-LNT$yaI4n|h>6xoYOAMrl@<)@dp#zASlE!T!r`{&RT`xI@rZM49fb z<0P^~rSV_elv&^srkoa!Qu0iL<>RtHy=FT14`SDimf$d--a-}F^PN$czqnxTLn2D{zRbCj}AIn7q_z!bqj~yN0iaQetFbk#NCC7v#~zZ<+eT5 zqpS&-d;UPvR+PtL8S3bY?;)Cknt~)J1DHw6pic-VA{9(ovbsu=nLI^aC%7L{rmczAuD4ha|bKOgBw{SMk`cn-!FCy*!Naz2m1_kz;?&!M=6J-Qv&$9Rp8IC zi5j~|ld30*xiSoU-d$XNDaYxP3$DI@>RBg)?`i%~$EA2j?J=`@?Kal6R+4rt zjN)5s({?gXCXCe8!UN`D(j zHKasP2Q?E-UPTiCuFAAr=;8@(%~T@{OKE1xjLHSgM@j3G22#bll8&EJLX8KKXq6p3 zN<}k}Tzrvh{}HFLIw>_h1L8p~^d!8Z;27Hd=FY`&Z^YxiE!myOvm zixFwxeM)I`pKXtIJ@+dky?o1MH^yrs{RR&GgEe@{m3w!WokMu)Xh^@7B+ZjDjhePr zt#E`C89d3^04^9$Ow+dRJED+8`m>LICNelri7_Js_Znu?DRQP4OtM2_<*C#dw$LOZ zDzNh&YU$+z{|u59mt*CO*!1wdNfz?s>vA|bJ#@{yaXN99H@noGywH_Bz1x2;SW+j* z!_28!T>4B+*OPsE@YUYe7w!4&*pW;uENQ2B0@1Ai3ag(x0MNZOkbxk5oHia6-}YM6 zq%_)eMc1F$1Mrnpf4a1^4}RqKF=pE9)(MJpDhIFR$LsgbR9S~+qI9z57OT6sYZ>;P zrYZm~qUq-sj{XRqAjnv`iA{3Ziq72yCRwUb!_-r^w(UnPTI=nUO4kkF-ZP;rLWF$+ zqJd$~jROEiOcOe4UFsCdOu+iYcG<`23agQnR_L}9?i*r0=gW$9XZS*^j(P#TDbtM()0*RTqS%c@oLvg<~^A=ZAl%=#VWQd~vlJgfD)Ah9O4CbT} zl&4S~>_^g6KlgN%yE@J6Wiu>>V705}Lc{y@MPi;c$7j2_22qQSYQRs;Q$vy}j;J*Z zP6v)R(d2LVTom1v;X#}vFk~Kk+Fr{3U){5-p^MR z#!3zBt<2>kWyXW|Ha?uJx5kFu#9zr#T>$K4Ji}|?Zv7SGs9HC(tl&d`GX$+a4ZCSQ zciBNs1b0pEs0|HMnkB;;wA^kgh(h$;o0Lk7x^%lk`y#E7(_>!-oYTEWaQGKDNl+JY z{g@3X3MTbS6Qvx3M^5HFsxb8p9z9n9P>LpLgM4r4D?q*SR`8oeqY8SvSH<_ z!IIFjC8eW7s%s{p;MtH0>qPSkrpTcjV-p4vz6S(^C~!O7c*nNDdvxH%>zY+D%;C$I zZW`+Hw$e8kF5SP>piRRp(;lP~cL$i918DioC20A#&h0hbUARo*N_B@ct8Veq>kwYo zh%60xIGXU0MxBni!-ud9r~d3^LKbV{W}3W~J}E{*UqQf7ExgD2Ok2O~daF(7ySC{V zZ|`^8ocv#hY{IhWVzwISO}ETfs(;f2kL|Cuku50=Gis$6QkknhBOj0hyxfv`#7l|RT_f0uk}d}Tz5uRK1$*WC5wo1Z!jH8IS{slAWPi&j=g zwU3|VW{I&wHBV?a!xzSg$>Ww{0A-OWf3PjRSeK2cR_u>!u%CFMMmW7BM1-pZZ5JI4 z?znlxWbYn4!r^XY2m>o%f(bhJgK|^}9g}$~6j|IyLvK*1sUCLI`UPBd{F+A6IISJ{ z(FWXcL|i4tfoHht>oIB>Yr|R&kvXbn&zP1mfB$`qa7qZTk_%UgT5;P4_^^p% zmH=$D*hn?HlzEz)kQKQbewNFLW0d*q zD<5`kO-jxSxLORi34!VD%3~)JCqv`T7O2cFsiYzPzQDGahaJ>S%6%pSTCVVcLBJR1 z+Au-8mjw=(?2?g!mSZDOQ@WRs5P6Fy)z5!Er8IHaN)oAmRR5)`w>ti&ux# zczm>!{n&n|h;|!?>M5#+|KJev7FN zli|;{TRp&!#70Y`-}Q{}BS7k1N-+Q!*nCQI$~Fv|^5`n)VFE$qgfx_Tn&28fm5P=x z-$1`M=F~_er2jcx-o(jKxkrslQ0qoZF&S-W`9>EF6SSQv>1!R)9j zTPW9h$^3Nwj2XMWHsXdc0R~GfN+15dCK8&9$R; zr}_iz{>VHHht6%QVA8CI&e$7G4m$A!F-Fr74yC9eIfferj_gt{kdrK0MXEm2;-C5v zqKXT2N)jmTR6fCErZ zyJq({sKetJ2{ebxi(#&ib{F8O)$q*R%P9hvbUXK!hw^I2N={f%a#51VDx+ zbJL6a;3wXF%%;01KGTb|J|Sy>Wh9W9g`=begscTR*K=ELXu}%17XQ0YrJBYi-|m^! zh-L6{bQwob-;l>xo3Ht^@6hW_z|0vTsZckjnmv+}>9(m?XPIL*a636A0JZ$TGm%Ep zm*;qI%OSIRU>wtcDFD8F@f)md(>}=Q^bU@n&n|a3+-;amRY@;QsgqroKpX{TRt$0@ zTQi`66iRaH?7;#q=hKguF^FyrbgrmMX99TpGqI$`lMUIJgJiO76r08=Ex1917$yoF zgyQ9IU$hpvOo^EW;Udg*i8- z^^QLr0E+(e7#Az@9(4<|!+o#$R1|%D+-k&c3>8Xk##@i2lZ-|9xJc$?UUN0hHt8*H z^akWm)ZKZkyt;Rk^!@&2hKeE?*Srum>5AX(j1tCMvNWN@m9`uz*2Ygh`P?tZImaw@ z(6u)xA84J4tn{zmG{_=8=^YhNiSZ%rS)i!sod-XQ3>r7Bf)7e2eiDRA#8{Eb>r3Q& zPu!mz$y*&pG(DZ?GfTP&8A4n096_D&KjVbN`)7}~rNyDH@rJ1#DS^KW;qQ_ff)7VC z4!>8Ih%s>O6rql8i@9cqD&4GwtB|h@!8n-C{F&3F+>{*0b2FA2+qAHkS)9wOQpDif z&q2#oeZgahZ<2lQ*`eEy$&2Wn1c`)aijhHWh?#5qb*Pq!R)RV})I$RSK!WQ!MnXh& zxSeD6$VIieNc_k+amV;XXb+N8QgU4uQy#YPH{*N1Yk1!F~2T?9)T%CN|K2)Pa&*s{b@ z`nDl@2&p#2bj`}p-#iB&D=_1Fj8VZsRK@@dSxv5K#=O?2zR9oaX@ER4;7}ZB=jP95 z_T!cUsNGIsj$BPxdu`J^wU-!0I68Cke}^5D_#aJVFU^XjnlmkDlRJ2qtTsTeot(Khx-%rB@4K8`GtM}1yB=sy)} z_vsHHz|xy4gB3sl63K<%=BLk=v9N28X8UGR@LnzC%xGKZvH0>x7`=f5I zNKuFfrR>FrFl8W}%x%+aEW_5{LJs{z2kx7-1)9Uu$u~>96(d7_!=i~8u$dtO-5aJy zXTt<<^cNp}6P>tY&~-m2KIAu)HsNQ)m5bZMx_9zy@&ami87OI1ZPEa+apBk=P2o9f z#N0(Al#5M@uAVJMh<1csgsz!e6u!9M=3-d1G&bspGc2U6LHy@#k2-5$_7o%OT>!M7 z`|SQ;YIMo{GhvC9!pYRr$vkRZ7AN!@Q90-H9G*H zOZhkcDLJ11x^vN=De=s$eR51Nb^2hHoShmWXX*B((pk@?SwKo#q9vFTn>j!YI7;T| zXA@!Mm&)Wpehm(+Z3RN{L+}6-GGjl`n6xc@)E`vhUg|P2Hc_wk?$D7M6YN_H;~Yr8 z33)>y&srV!jR`>hIHJxWP`CYp8~JO>bq?3LNIzH`RC?xLu{}(s6`HGL%ufCx$A9~4%*4*U${0+kXw&KYT7*vrGW?_QD=k~(;RfwmrHE@p zBmJ}y(gMKiL?#pgY5DI$i67cIkxyn-e=%Q7#(8d%n4_e$*e^$Kzn6%(Ny`SceLjSB zbIh-{J=t2v2JgGq9u_g;0vcYC5(=Cf2CB)`Y-I1=2Np8c;rfmtNj(6I;k%P1X3Z<5 zo3-+Pa9M67XJz)ISb1xJYt#Qj!g;I@=`{MbiiSDdvJBdfuj6RX`is$i(Nj6`4bR+c ztf9jCXFFf9mygOSDBV7>kZD==O7Jf-O#vDOWkJ_2$X+A92s(NdI>CRRT!k?Br8D^N11dE`|6xvFz%2gK z8w`hZ8vZJ3gPvIZ%SeLW^Zxt9|CJxS{{Om|@^3Rhp31+b9`ygqPw?AhMz7i~QlDf^ z1b(xxbvObq_TI8G-8Zu<#YoHrfLlZvg&YQ2$^=n{45B*rRCP1Pjr50Uy$*dL#bf#)3fVe>A8UCCz?&C)%DeN7Nr?Gm^=Cowp<(Y z;Vn$HNo$DgqX+TBG|rmE(dizVE+Fi;70dc_J6TdajJi@EsnykNHS`!3IZkb*Nt<(n z;NGxt3dn|bJ^6JZ!_uh?Iu0bKL=L~LN2$5~XG2#jNii-EJn-hS#01k;(|xis~8AW;P5#|KtJbA_$dwp zA5Gh|_k}}9H#s5R3|f#b)cmzrsrBf)Det+17Y0{ClR|HBX3#wj8lR8w-4&%$+vrga z(GZxjEfl11cWBSh05-r~W*XBp1pKef&FQCoOF^%37-ghpPz#Ov>TQu;FJ{b`nULm7 zElE}@JONs5W0TK_rPHw7Kh%ibcaexmx9X)MoB$Q@I=+bWmNB$s7KYq?9{BV9=fsvO zyCZ)}I(S)LM|hot6(XM-#tey+JTWAhgmk|Kt+ScQ2Kjl<|n&vJ9{)I7Ka zx$6+@WlNe0O#*7keE>OLl#(gymjTb`yf|SNb8quCpsKORKWN$bc#0>b ztg`tQU{V1Es$2%5KNoV}+x-9+nr^2JIbOgI(_K=ZxYletj2E-?bQ0;f2oQ-e3CSaOmojX$<@SC&xcmN9%TH?k$p#gCU^?TJ zOW1;(kW%lkSZA~M_Zer;xiHqW5`&^NfXP-}>{js)$~O1xzP9-4qW0^AWzcE4bx#Q}8f$Z;ptYraIHmSbEox>nES6qEv@9I>O7tqmY@Xq6w z4Am%h75t01jR=r{kg0uR)*T|QA*OY9i|Reo>TeGSR0;u7E7rd!WB?~)+|;!vW90-s zY+LF+$Tu6umOxcFkc&-P#_~u{T#VseG>k(d2V+_ir?hU^ZWVQ!raf| zDtLwqHS!0BbZssqB`X8E9Ro$x%Gql;q@#^+)edHHOTOlf3}%tVw#rM%4n}=OE%XkeNOPK%EhV{Tq=`uT72kPB-0iD6B&s#an zNY&#krHu`eK2Zru?aP$K)-w``^#q^7!Q#dKbT$0L5I9YNt2(aJ<$Z;Gq zHvKL%=b++Pc22SPN*-gk#@DNKrk1en(FaX^Szw&hDg&DspMJ6qpg!;``CSNV?Hqgn ztUnLa-JtGDNf>!)8dp_iyvBXS258Ol$^Fl)Ruac-wQZWqLjorqXtr*LA${`PLYRSw z^tSWpn-PsTc!5N5PT-e!Y*Jr!JN1RHgtK>Ph(nHrE4&NC2rK!3ShL5EFO>+ao7THH zDkTBsq0y1z^KGXFKfSp~bg%{H@2bzjOXq_MD^yUvw){PVdH2VM7B_Vmz7{`b;jTxA zU)AB-GRzlF;DekO(&!zj>1@7}I^&G**EjuW?+?w+2tM4in|z)W%}$32o5F)j2Cs&( zSX=nVu95Wfn)o3@O979`7MCH4jxG6idT39bh)~}D8Qr;ukBipPrOtpHGQScT28`^o ztkYDC9rH4tQgQ!%m2kXyNK(yVIY0S$NH!VBgP9`q{;U z;}$71M$}vIQunq9jttE^7J4%x8! z@hba$W?UzuybJg9Zzm{o#k3E|9V4d>spMJrndkEiq?MxVNuTAYG8yWuRrFZS<}-jZ z+LO%2$y15JS1_M90@m9cf}4uxcaDXCSj&KlPa@tRN^ysW%9Y6QGXxm{Q>**?1rY-# zGBKs;B?ET>rQ;jT20+SJ3+Ne1fO0A2M%MF=ECC~Kzq8vBX9EuRmWX%3=2-(o0v4eI z9#e@JAebHjf;nRSD-uY-gacFEz@Qi8eSe?i3=D)%rL@L!8N!;hf==NaeP(F_qZ3p6){!t5c$bJQkB?ifo?`$DMnKea45so99!! z6p9ksKZLFnBu_>vz-GxDUL!9G2kBvCtY@7_v%+?Atm|E;a=HlQ@KQt}sh25t7t7K9 z$HnX8gK+Q8!{sLQZLgT=_d-xP?v$hU_TocPc(nOb&qGb zNgY!_dHHgupYe-N^zdOxjt=fSySa}xruq)xh{R?eZhCo*ZMHHSxJ~{_wEW@j)7}B! zgL&Ki){*9eA>$gMSuQ1pyh6KDMM;2Ngsrs<@_>_}mK{XH^u(lsK@f~(#UJh2vGT$^ zbM)Ypl%UBp0J1Hl($q*!Y}OXn0S=FP+R_J56bn9DL>YUxZ_kosl3x#GLlMhUIoyMX zF>k!rFfln>?M8_6Fe|Lz2X7!T0kb;ER2Yz)`1o1BM_~4bft1nLu7ACu!~u6C3hCZ4 zVIiAbNo{veGHg0)dX_D9_PvT24M5RFwrpVjIGpyIl^g_D0S=Zfv+sQjAadTx8w*2e<>k>%wt6C)xs9o#}d2D*Z@q`3>Vc9M~NTxzXnRU;84 zHw9=fy;`{2L=#&p&6|b;ffctvEbGRL%^di)ZkcK4g$x{ruf(VW%#f*O%j{gm;LH1V ze(f$(jn!bDrf_DpX>FrQMjeatMz3sHY}k^nJj5fIVsn!)RpymONvx22FB#RIzbyB= zOc(xMvGwInBF&2$Z)?<$l(OEF3uAXDLRkEQlXca@FBqI`6YiLT>39c?_~{3yxhO_* zx6FthO6;$d({o#hmVQKAyxL>U@eq^bY~mJL>(Iyv9r)QSI*Pu&pH&tqWntKSC3O0k zMKd=#&y`>K#7f0_kTMl{UajQ>eYqE}~ zvIlQB{|rFdngun(=tGlS5LcoiDkJ>>O8GaiJM?U4IOK8(n6h4-^EJQoh6?_^I#9y> zH-=Z<)?DW>F7zs#36?>vOy%d8Zyoxrllj);U6vHI<_8L#;Mjo2>t>meBb9Jhbj@ge zE-9BCD;eWljP(n0&7PF;mO}#t5sbwC!H~ouBB2w04cBzJ+g~oaK95hyzSLEfQbtOU zJ3_i}S#jN{FrzGHdjSIYS()}Uot*f|$dQy{T7%IWcMm;=VU|v?pqM1SUhM4=DQ9-_ zJV3Dwo%3DWF4_^{a&DtNaF&4~&=N97&g_!QPV9+xP~jJGDKlFUQiA?D1oD5D6k9q| zChoEU*o~1ry(QMn2yeOJCcX8Oum~?wiEh*8P$ABJS&S>gG+Bmz@GhnA?&+h%;@nqh&vKaPAGHy*IdAmB?XQA?SUhB6@b| zw#Ct~q5$hxQLpGsN0y5iZyR5Sp5Ir83)|PZG`Iq`IGwBtHaTDvgWViDY@)Y=DWb)u zB3k&j4O5fW-5FoJEqn59*l;kxNhrR6LNlLzGtI$v#%7!00ikxorKX~Wqu$9T;mIi*$;0BDXTVZ}&x)WH`vwOM)0_U^Oq?9oVY^Df4J_DFDu zCP|o^${n{qL$nga=NiO}D*Pz)z^${d)ChHHtwX~atsDry4Owh7ZG4~>-^`!Si^Nym z<7&8P0oh+@e!|ezi&bf&Xd_hREeN|k#^-cESm<5TbBZ7`!wGKMOJkVr8gX1mo?yW=Ess=j}Vq#jD#5MN$ zO#q_ALeZ5KiXc#ll_V-Rubb)i02&c69U$6G;lth4jhSv5L9xCFIBMY*%q3R`#59LP z{eqrt@!lX?#yH<2ah#3MppVN~QgS;o{}%shU`|H+@UYo#&sBs@=D?&dYG*P<4 zOXj==SaZjq2AC{E3z#{!j`f;JyKMNHmqiC$1#4oxt}QK?;;d$Pd2zCrv+cSBgChOI z-bU33T$Qa&%*p?lF+it4wFs1?nb||KLEEX08Be;C2OpG{F2YbdgWGO*lrjajf<|W# z8J};#v}eP_X@n*Q!kpGe#SYFHQ{EE;;{ht&PriS>J>dF8@bOTYumnBg+iN$`UjXvb z=Eb2!^n82zdle?+ZfDOOCtHKgj9|swaM^A9Ka#8cN%p{23r|YJZ%opH$@3iv01DRxOg#0S*ef7Ydy7tY(y zF)T8+#Wj)rh}F?!)@-{e&x#fA?l-i;*t@{~aVqG#N%W!b{4OCE_@TaGk>qLUfhE@! zs?%*w5flKXVyWKp!q2RgpAVIVi%>g;sQ1V9Qt{jKzk$zkT;nq4nIQ~WOi?<6_sr+r zIW5u~30Zu-It}hY=(rz}`QbEL7v0L(Po6e?PtS@(%HVNXPAhx>yeS6|?;X7Bx1-Bm z<5ku>Q^mA5g4vuP`tK`I@vS;>87G0*EMrxYBVgV@nTvNWW(+=2=~YbWJIyip$^DL| zr|@fB{l+~W&!wDaDQsBY&ZY1Z2A##TA6AxYb(e&>=!4~?%WcNZL=t}NcBzy7O9owz z+QroY#a<3iIH1B$B9J96U@w)=moGhFD8W0f=;UD?8(p5bpK*Woia|qe8K#gg%+a6c zU-zy`_#!LvlSkXjwM4V7BV|l8d57p;yj; ziuEOYdrR1CZy*45+Q^b9%Gq?=BP#q_w}Z*9N$d|wp;eZ06TN9P#9#T%{iHl+F4y&W z&u@;WCYzPMa9%L6S1bz&|sFJ`{&|px~$8w`{-?YiWsE+kX&y6T|1BaP5p0MCNi?m=P#hm4E)=(syr|x<7ooq5bu;AQ;m76*GdkCFcr%w~vWBmE` zpib*JFU6_)u%*5C1E^BQh_hZw@HYg8AE$)o{LP~fPL~az=V#r=!}5vfK%gY^(f&4G%(pk1k?YrrNbw)eu@j~Y*Anj*A0%CT^ixe5Q21j3y+Y8 zsv_#>HN6;2r+i+HWqbeEQtcZvCxA_7Dsyjti$6IaoW=hoOi)cqZkY2<3;&a!D>K4# zp7C!vWHdz{OqYFfPw~Rs`nI9O*44KAa5C?65$lU#SsE~%*3>Dj@duZHVyN+}{e=de z7t8&H+t(RP9}edglmnFYf`(#QPT{^|HcOb0Qe|WbPaNHIx@IQHu>@Lbh}IG_Od)&; z7qHgUMf)R7n>8^__+TMa|I-#!|w3&*sn`&liaLG z$X9+X04RAxh0H;jA2mL?k2=60wm7k%i)X{GmSSkK2;lF_vQ6y`;grj39TMFt4si?1 z-wi0m{-ec(M}z?6;iC_T!F+E9Xs%7Z)&724w~}cPki;@D-=YtmE?xo>m*ymlgmq~7 ze7FNTrlkYMd}RE-y>af{cRrJ#sdjbqn51WWht3Ze=w%M)B(@-ml}s7@OeWsrxeqKV zkF!E`e%_TCXBoAXfbw8r3{pluVqM&0=>-63`IbI3dN~fmuer2hpv>%q^{StJu4dzT zpR=tF{x-uqliFMuZ?d9Cr}N64We@Yt;+7jpC^x@oKxt8_CAJM9#6PX?i+asLqs@aD zmIPy>Gml+ooYfA+@?YbMZ_Mc&9ujSp84O#O_Lv2N^^Jnjyla@IDnTf68N6O^78AdU z;z9E53DV08#0ActX%J8MWJPkyltad=La%e$Mpt?u@8*6!UwtK#^WNMOv!HK%C$&a> zjSQ~zlZ9{XrGElor!uRclR2sDre(cL>IBl!;KxZL)Z=HJT~k0BW)G;`KjX!x^HkiW zj%Gl)R^r7&gVbCZ7ruA&rj<>L>?A<5snYZC0&yDGp?U z=XWGz%_MJ5Mrm$4;@Xh? zJp&iuK%{{TXW~}FyZ!p2?wPM61VvVdW(CjLOrH~Zsxn8p{ZZXnfYsUHBUmGx(E6Ra zjoMbt;k*o?xpw=gw<994qiB}1H}kBRTZmeo$5D{|P@e?xKh$O1$4S1!XW1Se$iW6m zPCR6An?ppY%yw>r!3OB>Zpy1}_4s5!juKT1Z9fPXCMJJb#UkF;tv9Ctz-oUKlvHwF z&|==5zk73jN9zDsqny7|AIf0bZUCtVIn-Z@$pof5#D8vOM83H_mDG7R>F_K8W}1{# zVi)1#G2Dig7=h2=);O;?F`|)kjNwe@8dVGb#}qRR0zxU;+)`O@W}l_}FhAGeItL_A zvQme)x0_UTBqvvnjWF8cj!S-zL^hCWu$90z2dT{_wd`y@ZSjAt-fRz#t??3&UszJP z5#OQIM#9aC8!n$ln=CN4`|nOX%+-s^bA7y7^wQ`*v?f634f$VfCD+Xy?H?}AM0hM+ z1k!uPtSvub@}H3}Ch1^(wMLo@8FGlP>ddjYP!|7|!bdNjQ=jIJ3y zQSX}GHrFOBv8}3iC#R|-j8(V~O|L3K>oa7`9|uHxM3vF8jFz&9W(`SqYwng>ZHm;T zLd|eFYlwX`pvdw*|0Bq!f?j?5nVwBfM>4Pnbxb?Y&Y2xHc*8K47onnI z5_P;kZZMTSM33h?`+Ysdw;bBn??rr}5pvoXrq%#OhxiAqFxWX1Wv!(?vQ-Xggcytf zHkZlOSb%iL*4V|d;Wx-pLUM9m8Qfa96typdwLn_uiOsu~A;%%v(_-~o*O31(LoflV zw=7#UK-jM=Uw?bcYu3YODDRwNCuie11;7KY6w@16yjr2uF8;yMdw+#J+S|I&^N4lY z>GcRAciX~vcD>FG3t#xsqy4Al=MG-tl0Ld`5KIV>bW2wfMh<&2ao&WWe;V>;SKeh3 zYh1^BSicf(^~o50U$QcyTV%H~-h8`Ur57Xl>JYKu{D7l>iM?Y)Lp?hOdbrgoXz`fP zMCY!(u7TasD~%kXtVek{&<$lQ_RAa)f-*LeyyD2}ab8cR znj{?2xjgTHU7|z#t!RJUUM~`4df!|hp0hwLDzd=_5Pv8FPS=tDZr~knLr%cLAcP%yO2I`T8<7kGwHMDJgH5Kz$N%@V*wDu7i+YE>9s zHapg2@de9KYfKq@aSiSbIq&2i00j8UOJ}(X>ACz)2GHK zI$WUPY6Gv=`WRJjBqA!w*-Wd>aH4RbaT{pnvXUOjiBhKpNZg-S=K~uLi(Bbbr}UWW z`=+evXw8k7YBcxXlsvjYeRjR+8Cj*<`=VMHC*4a6_xsdg<0Z+=bzn=SnG1h4fQSK% zqw%IkB6x~n&8Irws}@RKnYk@9TS~UR!v#vHt7k~dU#k{tAvd5NX*@g;xd2e)J8;E@B~t1t*$=$u7RgZczx*S-WaIwG_Szdtq7|p4C%*PUm%&`b;;2eaJ?5y+ zqgk}WLK#1)z`EijYS0M>2uqAs(HD8ipq1Y&SZn5VpPE*(3)FFfrT1H-2r#^@(?L|c z7RX)^Ox{squXFjuFBJeBAeTKbDgX9lgEtM!=?9evj811KJ^} z))q2A4MoPU8j++%Dqy5<)vJp{Kb?mTxo6S9fa|DL;t;w5z6gTK7IQU zZ^-}^*j$_CedfS9(WOgXyKt~qw|=3Et5Xzmo@PhpEHv7?b!4MVRnHg!^NjkKX50nH zm3|lE*Fq7jM#KwL`hO_Ba5M!HzRqSB05rUA&t3^E_DTo-n14f^`aW<2(5u!zp*bhB zzH(4OPMYaDB)0(wGS_ktdW46S+5zMw%4QGA?H9z9Ig6yqU_aNj*d9~Uf3Xt9f|$R( zU@ntUI)Xv2k8@__SpZ{F)yz^jlk8Tbl2&4GDN~p@{f;;wf0!B*u&q{#%=CR?I}@k} zn)9<_hEDa|utI9RX9xnJjp0xbKf}>z!?LA-1>V*z zc<1jS=(&GI^Nx4(WV=sgG>3kp*iAo0jSFf>xsLGLr!rs))iWZq=|^BM+jw5r$9Wr{ z6A3dyb7Gq+7IHp17a1(_tX}ZDVzkmF`_7<(Xm#f#iFT#gJB~x=o?5(Rtfm2d%?{9! z5ofNS3i|GXLD`)G)CXHF_T<8f{!yhH1%(!}dru9z!J2@KAc za14JrNc?bgo~(oXuC6lU!t< zrLXuY|Gc949m1|fSj32RINrJlq&IeUW{8t6kYl07g`s*3L;k_r1hwAGe5h#qH+WP0%ycniXGe@7=vTK_3GseqkXoA&a}f&!FLp^VnW0YKQ) zBme(*6_Y{%w#r(`08oP%0JY->7AD13sP;s}w&U#aZi9yH(Gr6$ZVbDmlQO<1WDMBm z!D|5QPdvWPs4Qt36%pv$ilnlg1i7Yz$g_iNINY;DtCqX|#IK=CSdkG%43K z?6%_(eyoDyricKv4FZ#?KfYt%JF6SJ?=9C$zH3P6#opB#%-p$cMF9RaTS|iMah783 zWMr;;6=$IWD+ghW{n)!(E&DU+2(Ndt5sS`8oPUjE;!Lq#Uf+uo zCpX6+qAug2;?Fmp1Prl_CDIUa8*`n+FrUZ9EXO4n)o4yfj@r)V8gzjMt2lHEf@$?9 z0S$-DwzshXuMq&=?BkPPDTss&bz}r?b{7I9Q*3h$9NT>?XR)@n2F?|GY>XJ_NCJwS z=#j)k;7tt2FEUZ>>3zF{0A9TlyICV<-SN8@@T!T$ide_Kl-q?sN#5UinF|m+0B?MG z@5+CM01RmX$+vwV2e!XeO)37eP*o}Dy*@J?bXLlFOir5QWcxBUa<3WwXg-b|xmhPibMF5l?#;uY?%(%eEm}xgEJe~LB9uKsND{JBV@tNN zlP!BGT7)(u`@Y9m#x`Q2qU;O?V+q;!Y%zxCdRL$I`~5w~a~#ie9MAoa`|j4vdwIQH z*L9uOd7js6tjQtXJJtXl_xt6%uTd9G8OeSqzb(>Oc+Eyf?{rjktdHo^afz&l7fcAF z9a9CMWb`zM=V||@f4U-Ln}|tO*7zEca>|4d>Hz*W#?6UdgsIDKur5*6H)9JIi)3bV6RO8`dE|bJk>@@Mbi@zf!_s0rZ%{@5Ji6?r$WmpBWgN_K8#dh#%9S z4S;o0d3d&dz?pa(aeKyvou^@=%oq7>XNvIz&fj0i-Cd%Nsj z>d^~#9{f2+lC3|jX|6Bz1~yyqkm4Blcay}-90hTZnuKi>R`A}98*aN_Ir2Gtrs4fq zd8DxMly&TftVa`<^G(h1b?3ji{Qfc;Ud{lPgxB=!bHnFv<$YW+yj|{|6DeeIBc)$6 z7C3lO-0zhp=;NC;x-??0V!PEErdhq;nbI5F21etc>sP}38bctFJN1D@4Y98w-%3&aa;ZnC#p2Y9t()Ao)jY(8#wgPQ~>KgwiNt z4^L@N{D6jpuUPC^5uDtOUYFSzCnE#l!MM;@KkIlekN$Z+JNd70v5NK9eq+I%H~!G| z-h|MPv+Hh?5m0XV32Nq^#F`jHGmD zs>j5cZpJsZ1o9JCES>RjT1++VQyS7*tWi#mwe2pxJ@kEzk13KY^v=B(j}>R==C4V{ z_kMg)Sr$tzuMsDXiwaFtg<7ttNKXsxGU;h+cQC^FcTes%HeB-BKM^OKIrD3DS$rc) z&vIScC>Z0czMHrjW3G@ASo?PcBkQ+1h#~U_q}1JD!^Hs1 znOTdtqJd^m81&#i<~?l)%ja6%jk_j$P$)+1Ve6MSZ$PMC{6c#;#JeMpVRDB+!}0cM zhCbUA$8!S)XCRBa=D7z|)7#b`blMagl%B1We|dlciy}-1wf)-4T#!)~`Q>Okw`BCq z!)#qb9G{3Llcs6dDVwNes=KFOOPhg43(@xW7xRiU$(0}b-&l6K^r^R7p!<_Y5YhMbaq8$>u(U+y|_H_m(Z(&A(`HVRS9 zM~OSe<+wV;5KtJngBQRwOK5e#pI}srXtun-A!T(K{!Z~?pK~n-#=xJl zGSdiw$ZpRMN2|1iRFH?e$AU%K1zFIJHypK!d6g9{Wbqu4^LOW)JwZ+u>$Vi-`~*cx z`V4+DEBjPE19F(yow;e%%fX=~F6}WGoV}>P4D0dJ+HeZ}S+54PT}_|vEfKX~o6*v2 zgXnLJ9zxp3XYBCmwlPt;%Po?{sv+aP&Gwd-?`Le-+_0MOl~e|wE!zu5FASVl4;jNp zJoPGQxJ7DI_0I~P@Hcj0KY%`Z8f$NMwtwJT6Uo|V2RT@-UUs5$MT|zP43ikN9@*?F z%2CV0d5XVp^C{a#m`P{PO2NC0>)gWQuUXQr5tH!O`fPjpnbHYe)Mz*6G%p6=F+5mn zv>zWFRp$2bQy5(8=81W?Y*%uW&JC2 zK!ZwYU=Z)Uvn4b2zObPwR!Y16o?Jc9Q5(VjO}m~j8fDwim2YN$J$b^YOrDWe2o(Ne z+%Zl848}}fGiE{YBG!C)QPrFb4P$J@N>txjsT zgbS8~)q!6EFr3tJCHH}9i<-U2iGDrirf~o!O{x39)sThU)rUb3v`Q24yNt4;Em#Wd^A5LhX(o((9?5+R|Cp|AR9%Kr!vP$&0AD4Jd^ap*fm zj1WOD%(b4PJIW-VVJsKaIg%DH?OlvSK&rvRFL|b)wA|>dsuL_G+cPa8UvZaVjk#{v zB4pE^(QX!aoS3d&;xD^Co}B4a8zBHH(-?J`wUk?tUd3p3oG<*lxp^Eo#&x;bumwtP z7F!|o*+#vYo4E62jc!bh8x<>g!TbdTPF%S9KyuiS%dO4zXel%VLJt^cB$fmV33 zwG9p}FwLs4?j1(Z-^;(gKPqMo+0GS9+?c_D`f64`*{N2LSbXmNZ5&$D&XE};Y!ZmC z$>RJcMx{yOKUVW?KDLb-a?+1f)_BvI$VB43Bft2BB$_++hsZyh3gulBsyLp$r z(P2)V45j+F@OXVS1*7w1ZvNT`s-7TP_oQQH6q6I%aq3>iqA3xx+DSsRM^;MD_~gcR zfp4B>7>jheWRS}i2kvR;t2m%TEliZ!pi7-Sn52~w^JEOdFef95aGyQ|j{MK33N4ue z1{zmKjNGGLijy22)@%S@ReccXVEhR$9MmSC90m@nUw*|q2LgekP!a%Z zVSo)~M@&;Iwo)nWl^9$+O2__;_)V$h6rEzt!1BxnKJ2-Jv@~BtAF>gyv#^cKu@)gSZdYkrr$OxQ}s2tz5!gY`p$8)t+ zTGMp{wneR0bKz{`Fle`Z7QC@fLuVSSo*OfEPZmNK{P;4aO~c^}W}$JauEJ7iZ`h?j z>6{$B#a@T%3aVD9^%Sfi#iZk_CTTlT7rx@iKux9jLMw>xrUC(e zdSH?(DVjXxxQu#Mt`zLmnc?x=UvcZ_nEXY8(Sj-N7@7=jP@nzP$j(@3923wW)eG;{sx<% z`0yKK?96@Msmhx3ciF#e`5wN%ET(Zmt58u?3a3~8YS}K9ZL{Ob8~`e`Nv0)}o8?u8 zpBzCLzG|xZbz!T}V_-o`XZKcZJd@drYllNzcTR9j@U(f)>1rI*xN_iN$`ShK&+jT8 zPVG9#Je`#BR3xA8`Q0x%W{1?0o}FFaSlnm|n>%SWHyzmrS?p{>e?4_$!7pFRC9QeC zce6+HCFxO79Fdxky4c`lIbO7zceyCGwFHOT_OO494YyQL>U=kbRrh90D|`QT&8Cv^J9;{TR6P}~G8^34io8kHB94F<8>tr}J7o%PDGj!GBWycd~5hZ4EJ z0ahsQ##!tZhQ3%r3WZqe2(ybjsJ<9Ta=Hr{YB66vaKlONjHA2x;Sdu+$mzrHFN2Q7 zeSQrzBi%xDm)iN?1-#Uet51zEw)u1sA4*R;@CA5dGXWSKEU1tJB2?RG z564<{h#w{uG~B*h%|c6o*REOvn+ zy_O}+>Ci&6WVA1Y$t&0TUY}#q7*E{REgBSzr_`NAFPsz6vLMv#ZFSBFE_|rZq`PE$ zjLFS5Eniur|JjseBS)BVe4amN`Z|F|<^ViIp6!%Vx+p8FWu^wI0Z=6`Masx{`-ZZ=uJ z58yPVf4*X6tacDGXMkGX=jWi?y%f!|N;?HoQ}eakC$Ad4UR$g?wB@zFabxJ`)#0>K zJytd)i)y3Y_|>eh8&gw@^{0X5{IA;6$?uD=XVQhMMnNDcYAm+==1#LVltH;z)K)fv zF_2%ZWBbQvnPGVBG(8N>^y2TZxeBt`RVMvJwm=v-@&4zf@|bK)O)T;~)2v)0k;WpF z;8ginY4siSLM&Myl-3e#$4t}*@@oV6o@>fXpw>yG+T~C^G18x-PUkYzuC)4@TB#be zGIhI+q_(_*bkf2#_M@`zsh*lgB%Bf^z&a=sE*P%W z)$Y+Q1|cve^MU_BY>0vXWjRU0az?QRg1>JxTx29{(7;heIsds(4yjHN0LMgt>6!cN zFn1J&-yjJ7&+0eOY+0g;Y?z~1X?+Q?P$B_*V~;l05vfeB@mWe&`fZyWE9pk37WRBL z0+N*)y@Qef98zMwrFHnq>^pwBYiWi|+VuU=92`)bItDINMGA{a3AWOLGeHde7uspzyjhX3jYzBQ9mF22&moF7tWlWxK zf*hZisPLraLxyU!SYwQ9n{wiWX6y14^!mO{8sCtMe{x*ftLwqXc({0_DM(7~2D~X? zocU#WUq@N{*5UQ@>x)T$#H|U{wyjBlIW5np7;SU~MA0oLif1yDjEC0U(n8g0kLU-= z!A+_H$a^>Yhpys7c}D8?4)|Ez$K#IErMy>NkAu{ngS^7DD`{?C5TL4BuGtBmT0rE%SOcW0Tx<=ZV= z<<8QD%XZHeBXefPg<)|G`2~T`8$8`x(6Y9yT^?pa{GTe+89S{q@+ z)thalONPCIB>zq6{D1aK{r_I#3%lz-Em{A6{R+%wJgA@=Ay0hWS+Uw5&4YkWk4FhV z>-fOYS2PXMy=V6zj_(hrj3LZ|sr*Ap!eG2oxWkmeHcbbrf)&c zanoey^pTfpk#L_E5dRC)xgE%EuZ;R8O(J?Qy?fgP*;?cQ3v@C%P#cwLA06%cfUN z9q(@!%Ky_?UgG{i+z(Be02a5C82exrx80ab#b7)ym|KBPAsVda-+?qXuug*auw5(C zfmj4IFA7ls7Z*fIdE|P|6p;>XdpYiwr>G((7mP~f!D+0T(DAoVUYn};H59Bsf#+EV z%-f?;aW~-gHG%fxO^L-YhT5I0*Ui-50Gk9i1|70=inAmWCTwcY-pFhk#Kn`|^c6L-B>W@2s`|&CO zbBB-7oZ7zzr&WuCH1?;7zquahg-4g}qJ%eViOoqkNnt+8` zk%dPXxJa_o$y?X@Txbn2KMvt|Vl?<(ecyokt95C*Ti7}(`K7|t<*^tS`9-Z(nM~T} zww|XUao08x5v59=eIrK?FtXyxBg(ya*>xW1{H4=i(TDg%wqzOBUk;n|^3BY}d_Ig+-q6^@*cdW=IAT z{{)hXNU-Qel7nVeY0}R%!=|ePtxNlKeG6qFMTl7U*N9j2H-1~E(~=}e4IG+N5n#gc z=r}#_xp^A7HQf%L8(o zR~5!5=mYHvZAtHasZMsQO*v@lR zYc?ZEGoaXbsF8I*r8Wt3)ysD*)}tp6(n^Q?zKD(-192T0{Y~m#7`L*tF{f4L^zeag z#W7J`^K1ygGZPeFC@@sRd3EI%+cZ}zv(9LJ2^ufIMDwFsS_y?iAN1<{A zXXD6G6x;fi9J!&r(Mx7xOBOT^yq?UrCbs%Y{dyCw+#I}VNG7^7eYU+%1FzrJ#C^Qw zWbt=Rep;p%waaD)TUUm%Qdm1mCZ#M5b56PX^D;f1icGW02)g>z*4suT;e<@?Tt$yw zOtamSgb~7q?>9x|^8Mwj{oZc^j`*(4J4&$PkO1@S-Z~d5&EezoWD~B;dOo+o5x8kiOR!+0^?WP1v1ns8Rir)!rX zq#Z6!qrsN-ORFm>q1(S7JW=|?GZRuj@L9LKwt2x~l9l_ZAk|gN|JWK4B3WnlS*jP* z;%r3oZ?CzO>k(I)OTaBmJ-iQf%(twqOAwXb6e~O63Cpqpfcpb8mi% z&koq%%fHS&ZX6XTkq8fXVTHuM?4^i)7P>r}5tX>t=P2Xm` zwGCUEH2{^Ip_9WGN(EIS1k_MrjsV)Zb3_=q-$utZ1&`(!SM*epWF~rdQI6=?GKb_0 zZGRcgr{5z$2r!x6xCn#@p5BG#*qR*8!y42q^=)ATcADU0{E!(gSL65uB^OorD?A0B z-lVRA+ivF&x9v1n4ELaZW|Uq;iL|`rV^;!$N(KJ&?LrD>PfMv#i%viisgyL03>-1= zMIQ}3J-J_nUs#2uXBOuBUi^8;CY7uQ;u)e}= zuQL2~+y@eIejG9p;EHEbuJ2wH%@4$V==&W-cqv(>`WC*DS&uy|hWDVZ_TA5{7YyW~ zQ^w`OQg1eN{=%&M=$>^itN46Hz!L~^QBb_}?&4;Y-N@s}R^(S;vO!DJvA2sxqMXpN zYzo(=G+!nQp~9*|gqtrDL&Jtbb>*J2$17SCJM`HY;LL>|V45B_JK7Mb|4;}{G$xIBL)gE<7_4O!KUUq&zD<1hs&z}Y&U53OAn=z?%+fzmMR=z0UE zgwvf<37Y!0J)9g^!ocraQ)tiu9AX&F57p*_)*!DMzpbtLpI4zW2xcdJaTIXXh=z#tI2Y>O$8p2_ zC|q7MbCJVB{3RGf^?OLrKkkj`CIFv^X^8@9C(R9oL8$2M6`Et7|MeDn3AFkvOnXpt z=@5p};Gj;l-AzUh*lbn=g5(i!-9fHnYA-746GtPlgJgZ82}ga0I? z|NI0WC_~$9A9Q?y&xN-=7YMwx!L%1%;&%b_1|9G^4f8UkjKc3Ri ze$?i#TG^;A>cE!TPq31X8ra%g9R&duLRz`Wy9I6NCv_A^1EP2aARHrOk)okWhyt6> z->U6V7~LU))B->ay7881>n~jiWopEI0{6`r^q3J$Y)UlqKpO4!ND6FC;z%*O?jf_e z5a$05tP>i+`>J!_F^LPf9M@vU0f)``C$f*z^qCBb?efRwAb9OxnYF zDM^vuK+ivVbJl|(9PhtbcAMZ=al6zh@iz?vq_I|zy9<{)aA523&z)#5Y_7+gR0#Tk z8z8JTIyOL`{;;IG6{L%!@SsXysDMI`+iob(&&{k!Kw@p5fi!1(zK?;+&OUp=aKlHK z-N)~LgcSL#NJWdQfSWXUJa9&hAv1dz*kyiw-{CzAEjSKdZIpcvEbk7n} z?*az`Sr@1Nv4aBlpxmds4n_$85om9bkVf8ov;U^Bj#xNUZrvjtS!X&f2cC3@qemHL zzaDyPPQZfdgCe6#{{}pO-VrvJv5B2f5zVN0$S|?Ihtu1^W9{ci;##HQBNp2078lXZ zB$;TSm4gES|3fAn>qsc71M7~x--F`a^0tt9iC2ew@pn#!s|Z%K>&1kz ziSmjxM>HoW22gV7ZWi6r^e~1IY|YXn2M?&bZeyi*h-(^MKWEG5qWq~-CTR|R_{23i zzm@`Y>#1^+$xcDlveFBhAN=mCc0_pOK>A)jsRWrQTD}jS?V`;QYQp+DfK})CqkUx`b5jZuFQ@% zwrhxUNHpxqz`F6xma@(wO`c>Hg{s-_?ayyKBm%;VZY~MEO(M@|L-b}jf9sAxYsLoD zwvEsiH;waMxn1s{e=R4`HI6CDTGmabqvsprBiANlSlm}v?<3xT6OiX?MFKq0<2L2j zUEy6)1`hXjN3OTrn?LPg3Zn3Lm~*%0Gp7V}Rc(9ULMyBnXG;>$srhCF zi3CBn8;jusdv|5ta&Qn~KfAL$yAJ1I;ym`LC~X2L-)Q5PoH(9eE%#s+N`8*QlE)@u zl2l2Vm0}Mqy+jJVFb69ovFn;2JMztxq)h7705{US`S7v)E_?mH*i6G>vd-6} zd&n}ek1$M+b&p~=6R-`&qw(2A4xw;}lRpNj&wa6rsT${Roy)OJv;7J6XqVYIQe<<| zp6Rg)*UU)seFsGxLljfSc%?SUCJM=Rl&;UgHuEF`iLTt3mWR`K>6Pc&NW@`sr>EA- zr4|Lo?im|tI6VtZpVP+!v~9KeB}e69#B4mWdsjf{(t>B|+{Z4~5H|<9i{{zWa`jcf zO8<}3@NFQp2}`F~DOpGKrnXTJ&W)};B2btNcal<{FGU!8ebYNz4}sAv_ruS+t5fu~ zx{s}r^mdfZmSnf+JAF^fEHDUP-=vvFl@Ml51a8Z<1DE$Hc@@(jSwSAC_aE@ynuVkB zrlf-``gVc&GovP2)~b;W8o8=B_?vv+#5#n=K!abzewtSWZEGZ4^kHw)?`9gH&Av0c`4QWnw$jT5zwIxlT;b0!JR0at_jwO$zu%wess%v@ ziO7NJCVknbilF{W^wiX#CGc8-)eeA`f&CTUWVznuV0V9GUN}xRPE={GD*2rlV%(h7 zR@vsyo@B^Kc6`-9Wio~Vd1m#IR&my=-)Jvq*)iN3f!3A{^?>03>;${{!G2H{@KTGmHvKZ( z!gx3PylMCNX@obzvs1DVfFWrqLUeYn0!G0pcHoAaN`{ejuhXWE1PlhtNO^4mx20R} z1f8VL+(E-@t0B3cki5MK=s@IxGZF(}u*|Et8c$H4#5XXafFM(rB7_W)G9n=(;Jj%s z;u$yGGAW|0*NwbqirkNG73K&K>p-*KT#8yi$3iKHHdwzL;Z7**sPOh+ADZZ29vgX% ztgwQ;sHIqa*)vb4j%IB+E^l3hASeGXkd!D$fXIgi=$i>1E)*P5fJVIo4EzaHx^OD% z{Vu4q&RuO8dO~M&G@)()D&favJhiNVp@V1xnQYcv76DM5Lj`!;6cBc9z?~h~w$&%$2<9G=pF%q>Azo zBezSO-IRR9^f<#1ppz**eh$*ztGEGPY;LiLI_Y+f>5^xwkG&NzJltcLNBzY7F_N$j zf1pU`&En>kwl-0%41*$@j+PIGkWW38hp(mdv%_y7$m`2BQn zi!Cu4W*2xb^zFd2x~l(LRhI0P{mQb+`tw`_WiQQxg7*ht9vtsDqlYe<09kONTyHQv zOMuAP;Oz06ijVTjb8GJHMcpVEXv@^*mg;|sPt}@FoN0^{=GGDDz!T5S`eYQC)K1hq zh!nBbI;1aPA{Sh}J4AP=q}tg~(LamkWVC&j#lyN@pT)*Rw_sc4w`wg(`Q}WnYf}e| zb`)tXM6`P9*zRDsiDi)lc#J+=)0V}}KTV*?umuWBd?oO39MIi5{HTq^A0_D4Wnb`r zQm8$_n=ORL7QNW&76{`tRmA-RY7~^-Fn7HSH^MU z7U@@NBV4PDHv%a1YdUSeZ$0v_4f#8`ZZf~mJXHr%GU{UFlq$&yxp*P5h$C=YX7w?XTtH6jcv{-rMfZpDt{ABtEb5u)%1@rD zR2`1anBp%ngrz{XHwHIAF+1cqmu5W7eG@mFwE-ES%07X)0NU`q?%PJkH#Vqq{_5R7 zueaMM)|=cP40QLTJ&Qud^SQI5u(|o$Idw%Qye6ZpRgdYS`F6HSk8VEzK18O^P@l(- zL455F5|i`*FxZuG$|r;ULdZb!A|h~PzdzBN@j`}#%;~YG-kU8O>#>)Ci5sIxIwz+> z3sn+Q1t}tMlF9Z(73W{B>f`Mq?&?{B!XI+fC# zd~=7M-i^y`i@Hjl{lN6TR0xKuXtmwq%{}!&A~*1=@+w(#Jh9F`2O0XBXwiqK&aCSs zVhb{xo?r$(cos6aZMdbsvHg>bNeAw?X-u}xy02M(B3%1jqKj{bu0B@|x9)?NGh&Jl zYXOKf-CQXlbUVq9oh*%+d9AHv?Ts*(M^u^V{zNBt_JxNewF&a z@PYf&dfShSQ z%4fa)NAPxM+OAF4w2O)ZIMCB4m#oz%lKYqdx}ndBe;*5pO16YZ_g!iNhaXim2c1W{{Dey)iM75q)h& z9iLyUaUVW^|MP^A$0*;1fJ*fq(j$W=;dJ*8GCF4sI{aH(me7~EM5M!2cFkU3$c{Y{ zbzCIxi=lAluv_9pWxra}KDA(lEf$xCABP?3)FKKc2P~Tdo93!z)B{IV=6%F7Tf1>m ze%CWpotvgV;JaMn)V^5UCivfzmMweNWm%kM7<+ zn*Ang31hlq6pyau`2oQGXtPS)d;Z{DS0xNLmW7vd{7*KHS} z6T+=Oj^n1+>%JrqN&Rb%7~@=s@v!XDpoy9 zwzECAy*HQgdKtiUy2JxM!4yLo)*WnEc3s{Y9b8%wuxl1N79Mf*$f#lnf7I*Nzf?)qfhV?|Q5v>SiI)rObb0Q8;g{Y^AcLz>F+VWD!)1LN`C_yg2cB zYI;S~h-BHm>Ege#=`BwheDTJiUl#kSqEiwpT;69t_wZnjAg

=b8As)JG=yBvftm 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

j^#20BMOw2_v`zvV#d&GxhP&ZB6geNCR ze&SSKP~K(k`kzTLPp)MFRt@-sQ zm(Z>Ahx-m(IqHX8HNNsI|L-N)_(}ez6hBpnzY$ng7{(EQX5%^+7>)SUbtUVd$&AkH z0tXkQ!*o5rpEJTqm=L*#7oW8+(D=D6Xs>kNFPtKpU)RqeV{N&auT1U_U=6*{CVS>H z-AnH|3yc0$!OTbw9>Y7Wo)i7p5s@U402k%W2Cn5KCb{W z;8z1ie>I=UtrUs)detu(&#MH8;L2~#eS49-#zeQ7M}B=M&CPj;G-Not%+Ky7FZb8P z2`ahuyl5(TG6S{T!IMSEtFHhd_jD3MI;E@o@dthu+kEkfhaqKMg|~8L2rg;10fj_2 ztzQ^F;k-;i)t1%DQBz65UuO}k2LlfKGG_MnwVT6aV}fNg?OIWLlf=LW>NE?+{1yeP zc7*LLD2a2SqSE9yYg8e<6(vKeoeGCK#6V>GzJ#wh3xY%OuH08!0-Rh<^J;EP){e?b zZ&#FF5Ht{1T2n6T;jY)c={XU$j=r%Zj6{a0lBc-p{anryWCnFL9&h}PHZ``c4_djc zEiX-Y88~L1kGSg zF>YQdEULlfchcBm=A1jR{9O6?$W*Aj#&%LN3s>9cYpgjP`cBL89XTccUOo^B!^CZ) zlG@Z9U!U$$gy!Uvdc8aM^PP_L^edpkR3XpgzD;hD%VY}h7r-0e0Z9@9zovBGj4`wE z6U6f$?Y;LlB}wKO_~rb~IdJs+WBK?b{-jp;xp}?GWWYJo-(zCEz7=dy#QUeM%M9$3flo+4hcf3D}8@mvFNHt{fIDW?VvGCX$VnZ%(!--o=OC|1;m_JakVj$_A&vR7d$C7EA3+7*k>Ik)CWx8dg2}@{ zt2rc?+ZE{3ci^@&`t9%E;KV|T|BhnFj(!*LRP~=OL-k^~Z|Czvg(BbZ|AcjTF$DRW zL?eIFS4F6@US&8?pE$&sQsduRa;(32xS*3_NIuUgB*&~`ZZ}_;k@Hh0O=-J=i)}0Vxm_fUFh=21V>@8D+Ly#_YLd-@nFW{NP@ahVvT3M zy%xX6!U@Y6Gu#l4+e%ODY+_aqs-$Z8;X@%N2;io?w68IWI5q0qgU*zMwDI56-!I0` zeIEh$OJQMVvvF1i?!pyAcgpI=Wy*uQRf+xhOsL=Uno@PKOw-Ok<;}eQPoDNVax74K zlZ-e2$@+Qxh|oEN;y-H7Rhf!UCRV}MQp~u((Ip`vB&z_hpwN=u5B~4*fAq?e^`hum zy<>F7X=s1TgSw5q9}LkG$B`b#_LkKBt#!ZX32D;*TS#9G8sJ9#A>#F&t%TL5SA6?2 zBhw=E1~VjiTA}cz6G8F4?XbrU|HUi6RQ05U-AZAGb z*?kMIUnDs8N^6`eQpLzw!YH%*J^y%h`*adAC&sgYVsaPj-~yq@pTK89)0Kn*!Z`M+ zU^rgQuePWiG;e@-7=s<170-fw0XC5ZBdQ�uh*?;v>i>XSCBa&nds>zOoYJq{$=a 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 E0G&|4%>V!Z literal 0 HcmV?d00001 diff --git a/docs/src/assets/images/user-register.png b/docs/src/assets/images/user-register.png new file mode 100644 index 0000000000000000000000000000000000000000..ae948e5745c0c792ac72a6c960f5174556aa3acb GIT binary patch literal 10915 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 literal 0 HcmV?d00001 diff --git a/docs/src/content/docs/en/features/backorder/supported-registrar.mdx b/docs/src/content/docs/en/features/backorder/supported-registrar.mdx index cb205e0..bb00035 100644 --- a/docs/src/content/docs/en/features/backorder/supported-registrar.mdx +++ b/docs/src/content/docs/en/features/backorder/supported-registrar.mdx @@ -1,5 +1,5 @@ --- -title: Supported registrar +title: Supported registrar list --- import {LinkButton} from '@astrojs/starlight/components'; diff --git a/docs/src/content/docs/en/features/index.md b/docs/src/content/docs/en/features/index.md deleted file mode 100644 index 805df41..0000000 --- a/docs/src/content/docs/en/features/index.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Getting started ---- - -On this page, you'll find a step-by-step guide to getting started with Domain Watchdog and exploring its features. - -:::note -Depending on the configuration of the instance on which you're performing these actions, your options may be -limited. -::: - -The sidebar menu on the left allows you to quickly navigate between the pages, which are described below. - -## Create an account - -If your configuration allows, you can create an account directly in the interface. First, click the registration button -and enter an email address and password. -A confirmation email will be sent to you to verify your email address. - -## Search for a domain name - -## Create a Watchlist - -## Create a Connector diff --git a/docs/src/content/docs/en/features/index.mdx b/docs/src/content/docs/en/features/index.mdx new file mode 100644 index 0000000..9d9d92c --- /dev/null +++ b/docs/src/content/docs/en/features/index.mdx @@ -0,0 +1,101 @@ +--- +title: Getting started +description: Step-by-step guide to creating an account, searching domains, tracking changes, and enabling auto-purchase with Connectors. +--- + +import {LinkCard} from '@astrojs/starlight/components'; + +On this page, you'll find a step-by-step guide to getting started with **Domain Watchdog** and exploring its main +features. The sidebar menu on the left allows you to quickly navigate between all documentation sections. + +:::note +Depending on the configuration of the instance on which you're performing these actions, some options may be limited or +hidden. +::: + +--- + +## Create an account + +If your instance allows user registration, you can create an account directly from the interface. + +![User registration](../../../../assets/images/user-register.png) + +1. Click the **Register** button. +2. Enter your **email address** and **password**. +3. A confirmation email will be sent to verify your address. + +After confirming your email, you can log in and start using all available features. + +--- + +## Search for a domain name + +Domain Watchdog uses the **RDAP protocol**, the modern replacement for WHOIS, to retrieve accurate information about +domain names. + +![Search for a domain name](../../../../assets/images/search-domain.png) + +To read the documentation related to domain name search, please click on the link below. + + + +--- + +## Create a Watchlist + +A **Watchlist** is a collection of domain names, triggers, and optionally an API Connector. +It allows you to: +- monitor domain status changes, +- receive notifications (email or webhook: Slack, Mattermost, Discord, etc.), +- optionally auto-purchase a domain when it expires. + +![Create a Watchlist](../../../../assets/images/create-watchlist.png) + +To read the documentation related to the Watchlist, please click on the link below. + + + +### Watchlist notifications + +When a domain changes state, you’ll automatically receive a notification. +You can also export domain events as **iCalendar** feeds. + +--- + +## Create a Connector + +A **Connector** is used to automatically order (backorder) a domain name using its provider’s API. + +![Create a Connector](../../../../assets/images/create-connector.png) + +To read the documentation related to Connector, please click on the link below. + + + +### Supported registrar list + + + +--- + +### Tracking table + +The Tracking table page displays a list of all the domain names you monitor via your Watchlists. +This list is ordered, meaning the domain names are arranged according to their estimated deletion date. + +![Tracking table](../../../../assets/images/tracking-table.png) + +To read the documentation related to the Tracking table, please click on the link below. + + From 4f35d9f8b54b3c957034c82bb50ab337a475e2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 14 Nov 2025 17:20:34 +0100 Subject: [PATCH 113/131] docs: update documentation --- .../docs/en/features/backorder/connector.mdx | 16 +-- docs/src/content/docs/en/features/index.mdx | 22 ++- .../tracking/{watchlist.md => watchlist.mdx} | 3 + .../docs/en/self-hosting/manual-install.mdx | 127 +++++++++--------- 4 files changed, 93 insertions(+), 75 deletions(-) rename docs/src/content/docs/en/features/tracking/{watchlist.md => watchlist.mdx} (94%) diff --git a/docs/src/content/docs/en/features/backorder/connector.mdx b/docs/src/content/docs/en/features/backorder/connector.mdx index 125b106..9a04af3 100644 --- a/docs/src/content/docs/en/features/backorder/connector.mdx +++ b/docs/src/content/docs/en/features/backorder/connector.mdx @@ -2,26 +2,24 @@ title: Connector --- -import {LinkCard} from '@astrojs/starlight/components'; +import {LinkCard, Steps} from '@astrojs/starlight/components'; A Connector allows Domain Watchdog to communicate with an external domain registrar’s API to perform actions such as domain registration. ## Create a Connector + 1. Choose an external API provider from the list of supported registrars. - - - + 2. Enter the required information using the credentials obtained from your provider’s customer area - -:::tip{icon="heart"} -A link allows you to directly access the Provider's page to retrieve this authentication information -::: - + :::tip{icon="heart"} + A link allows you to directly access the Provider's page to retrieve this authentication information + ::: 3. Review and consent to the required terms. As a reminder, you can delete a Connector at any time from your personal space. 4. Click the button to create your Connector. **Congratulations 🎉** + ## Legal considerations diff --git a/docs/src/content/docs/en/features/index.mdx b/docs/src/content/docs/en/features/index.mdx index 9d9d92c..a0c7ab4 100644 --- a/docs/src/content/docs/en/features/index.mdx +++ b/docs/src/content/docs/en/features/index.mdx @@ -3,7 +3,7 @@ title: Getting started description: Step-by-step guide to creating an account, searching domains, tracking changes, and enabling auto-purchase with Connectors. --- -import {LinkCard} from '@astrojs/starlight/components'; +import {LinkCard, Steps} from '@astrojs/starlight/components'; On this page, you'll find a step-by-step guide to getting started with **Domain Watchdog** and exploring its main features. The sidebar menu on the left allows you to quickly navigate between all documentation sections. @@ -21,9 +21,11 @@ If your instance allows user registration, you can create an account directly fr ![User registration](../../../../assets/images/user-register.png) + 1. Click the **Register** button. 2. Enter your **email address** and **password**. 3. A confirmation email will be sent to verify your address. + After confirming your email, you can log in and start using all available features. @@ -36,29 +38,33 @@ domain names. ![Search for a domain name](../../../../assets/images/search-domain.png) +:::tip[Read more] To read the documentation related to domain name search, please click on the link below. +::: --- ## Create a Watchlist -A **Watchlist** is a collection of domain names, triggers, and optionally an API Connector. +A **Watchlist** is a collection of domain names, triggers, and optionally an API Connector. It allows you to: -- monitor domain status changes, -- receive notifications (email or webhook: Slack, Mattermost, Discord, etc.), -- optionally auto-purchase a domain when it expires. +- monitor domain status changes +- receive notifications (email or webhook: Slack, Mattermost, Discord, etc.) +- optionally auto-purchase a domain when it expires ![Create a Watchlist](../../../../assets/images/create-watchlist.png) +:::tip[Read more] To read the documentation related to the Watchlist, please click on the link below. +::: ### Watchlist notifications @@ -73,11 +79,13 @@ A **Connector** is used to automatically order (backorder) a domain name using i ![Create a Connector](../../../../assets/images/create-connector.png) +:::tip[Read more] To read the documentation related to Connector, please click on the link below. +::: ### Supported registrar list @@ -94,8 +102,10 @@ This list is ordered, meaning the domain names are arranged according to their e ![Tracking table](../../../../assets/images/tracking-table.png) +:::tip[Read more] To read the documentation related to the Tracking table, please click on the link below. +::: diff --git a/docs/src/content/docs/en/features/tracking/watchlist.md b/docs/src/content/docs/en/features/tracking/watchlist.mdx similarity index 94% rename from docs/src/content/docs/en/features/tracking/watchlist.md rename to docs/src/content/docs/en/features/tracking/watchlist.mdx index f28a246..b4b8f20 100644 --- a/docs/src/content/docs/en/features/tracking/watchlist.md +++ b/docs/src/content/docs/en/features/tracking/watchlist.mdx @@ -1,6 +1,7 @@ --- title: Watchlist --- +import {Steps} from '@astrojs/starlight/components'; A Watchlist is a list of domain names, triggers and possibly an API connector. They allow you to follow the life of the listed domain names and send you a notification when a change has been detected. @@ -15,11 +16,13 @@ possible to predict in advance which user will win the domain name. The choice i ## Create a Watchlist + 1. Choose a name for your Watchlist and find it more easily 2. Add the domain names you want to follow 3. Select the events for which you want to receive an email notification 4. Optionally add a connector to try to automatically buy a domain name that becomes available 5. Click the button to create your Watchlist. **Congratulations 🎉** + Now, it's your turn to create a Watchlist! diff --git a/docs/src/content/docs/en/self-hosting/manual-install.mdx b/docs/src/content/docs/en/self-hosting/manual-install.mdx index 89b16ec..2d2c8ae 100644 --- a/docs/src/content/docs/en/self-hosting/manual-install.mdx +++ b/docs/src/content/docs/en/self-hosting/manual-install.mdx @@ -2,7 +2,7 @@ title: Manual Install --- -import {LinkCard} from '@astrojs/starlight/components'; +import {LinkCard, Steps} from '@astrojs/starlight/components'; ## Installation @@ -29,59 +29,62 @@ git clone https://github.com/maelgangloff/domain-watchdog.git #### Backend + 1. Install dependencies: -```shell -composer install -``` + ```shell + composer install + ``` 2. Set up your environment variables: -```shell -cp .env .env.local -``` - - + ```shell + cp .env .env.local + ``` + 3. Generate the cryptographic key pair for the JWT signature -```shell -php bin/console lexik:jwt:generate-keypair -``` + ```shell + php bin/console lexik:jwt:generate-keypair + ``` 4. Run database migrations: -```shell -php bin/console doctrine:migrations:migrate -``` + ```shell + php bin/console doctrine:migrations:migrate + ``` 5. Start the Symfony server: -```shell -symfony server:start -``` + ```shell + symfony server:start + ``` 6. Build assets: -```shell -php bin/console assets:install -``` + ```shell + php bin/console assets:install + ``` 7. Don't forget to set up workers to process the [message queue](https://symfony.com/doc/current/messenger.html) + #### Frontend + 1. Install dependencies: -```shell -yarn install -``` + ```shell + yarn install + ``` 2. Generate language files: -```shell -yarn run ttag:po2json -``` + ```shell + yarn run ttag:po2json + ``` 3. Make the final build: -```shell -yarn build -``` + ```shell + yarn build + ``` 4. Add and modify the following files as you wish: -~~~ -public/content/home.md -public/content/privacy.md -public/content/tos.md -public/content/faq.md -public/images/icons-512.png -public/images/banner.png -public/favicon.ico -~~~ + ~~~ + public/content/home.md + public/content/privacy.md + public/content/tos.md + public/content/faq.md + public/images/icons-512.png + public/images/banner.png + public/favicon.ico + ~~~ + ## Update @@ -95,34 +98,38 @@ git pull origin master ### Backend + 1. Install dependencies: -```shell -composer install -``` + ```shell + composer install + ``` 2. Run database migrations: -```shell -php bin/console doctrine:migrations:migrate -``` + ```shell + php bin/console doctrine:migrations:migrate + ``` 3. Clearing the Symfony cache: -```shell -php bin/console cache:clear -``` + ```shell + php bin/console cache:clear + ``` 4. Build assets: -```shell -php bin/console assets:install -``` + ```shell + php bin/console assets:install + ``` + ### Frontend + 1. Install dependencies: -```shell -yarn install -``` + ```shell + yarn install + ``` 2. Generate language files: -```shell -yarn run ttag:po2json -``` + ```shell + yarn run ttag:po2json + ``` 3. Make the final build: -```shell -yarn build -``` + ```shell + yarn build + ``` + From 16a6ea46c190d95bc889b63e064a1e7b863f7f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Fri, 14 Nov 2025 17:29:14 +0100 Subject: [PATCH 114/131] docs: update documentation --- .../docs/en/self-hosting/manual-install.mdx | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/docs/src/content/docs/en/self-hosting/manual-install.mdx b/docs/src/content/docs/en/self-hosting/manual-install.mdx index 2d2c8ae..9b65dfe 100644 --- a/docs/src/content/docs/en/self-hosting/manual-install.mdx +++ b/docs/src/content/docs/en/self-hosting/manual-install.mdx @@ -2,7 +2,7 @@ title: Manual Install --- -import {LinkCard, Steps} from '@astrojs/starlight/components'; +import {FileTree, LinkCard, Steps} from '@astrojs/starlight/components'; ## Installation @@ -30,11 +30,11 @@ git clone https://github.com/maelgangloff/domain-watchdog.git #### Backend -1. Install dependencies: +1. Install dependencies ```shell composer install ``` -2. Set up your environment variables: +2. Set up your environment variables ```shell cp .env .env.local ``` @@ -44,15 +44,15 @@ git clone https://github.com/maelgangloff/domain-watchdog.git ```shell php bin/console lexik:jwt:generate-keypair ``` -4. Run database migrations: +4. Run database migrations ```shell php bin/console doctrine:migrations:migrate ``` -5. Start the Symfony server: +5. Start the Symfony server ```shell symfony server:start ``` -6. Build assets: +6. Build assets ```shell php bin/console assets:install ``` @@ -62,28 +62,30 @@ git clone https://github.com/maelgangloff/domain-watchdog.git #### Frontend -1. Install dependencies: +1. Install dependencies ```shell yarn install ``` -2. Generate language files: +2. Generate language files ```shell yarn run ttag:po2json ``` -3. Make the final build: +3. Make the final build ```shell yarn build ``` -4. Add and modify the following files as you wish: - ~~~ - public/content/home.md - public/content/privacy.md - public/content/tos.md - public/content/faq.md - public/images/icons-512.png - public/images/banner.png - public/favicon.ico - ~~~ +4. Add and modify the following files as you wish + + - public + - content + - home.md + - privacy.md + - tos.md + - faq.md + - icons-512.png + - banner.png + - favicon.ico + ## Update @@ -99,19 +101,19 @@ git pull origin master ### Backend -1. Install dependencies: +1. Install dependencies ```shell composer install ``` -2. Run database migrations: +2. Run database migrations ```shell php bin/console doctrine:migrations:migrate ``` -3. Clearing the Symfony cache: +3. Clearing the Symfony cache ```shell php bin/console cache:clear ``` -4. Build assets: +4. Build assets ```shell php bin/console assets:install ``` @@ -120,15 +122,15 @@ git pull origin master ### Frontend -1. Install dependencies: +1. Install dependencies ```shell yarn install ``` -2. Generate language files: +2. Generate language files ```shell yarn run ttag:po2json ``` -3. Make the final build: +3. Make the final build ```shell yarn build ``` From eb8fcac2b15bb6adc49b4b206e5bc02f8d33087e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 15 Nov 2025 10:59:44 +0100 Subject: [PATCH 115/131] feat: also lock domain update if from user --- docs/astro.config.mjs | 7 +++++++ src/Entity/Domain.php | 2 +- src/State/AutoRegisterDomainProvider.php | 25 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 56aceed..58e1b5c 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -63,6 +63,13 @@ export default defineConfig({ content: 'Domain Watchdog, RDAP, WHOIS, domain monitoring, domain history, domain expiration, domain tracker' }, }, + { + tag: 'meta', + attrs: { + name: 'author', + content: 'Maël Gangloff' + }, + }, { tag: 'meta', attrs: {name: 'twitter:card', content: 'summary'}, diff --git a/src/Entity/Domain.php b/src/Entity/Domain.php index 192cfd9..e39372c 100644 --- a/src/Entity/Domain.php +++ b/src/Entity/Domain.php @@ -68,7 +68,7 @@ use Symfony\Component\Serializer\Attribute\SerializedName; ], ], parameters: [ - 'forced' => new QueryParameter(schema: ['type' => 'boolean'], description: 'Force an RDAP request', required: false), + 'forced' => new QueryParameter(schema: ['type' => 'boolean'], description: 'Force an RDAP request. If an update is already in progress, this parameter is ignored and the stored domain is returned.', required: false), ], ), ], diff --git a/src/State/AutoRegisterDomainProvider.php b/src/State/AutoRegisterDomainProvider.php index 5387160..27a1ebb 100644 --- a/src/State/AutoRegisterDomainProvider.php +++ b/src/State/AutoRegisterDomainProvider.php @@ -22,6 +22,9 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Component\Lock\Key; +use Symfony\Component\Lock\LockFactory; +use Symfony\Component\Lock\SharedLockInterface; use Symfony\Component\Messenger\Exception\ExceptionInterface; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\RateLimiter\RateLimiterFactory; @@ -44,6 +47,7 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface private MessageBusInterface $bus, private RequestStack $requestStack, private EntityManagerInterface $em, + private LockFactory $lockFactory, ) { } @@ -100,6 +104,16 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface } } + $lock = $this->createDomainLock($idnDomain); + + if (!$lock->acquire() && null !== $domain) { + $this->logger->notice('Update of this domain name is locked because it is already in progress', [ + 'ldhName' => $idnDomain, + ]); + + return $domain; + } + $updatedAt = null === $domain ? new \DateTimeImmutable('now') : $domain->getUpdatedAt(); try { @@ -124,6 +138,8 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface $this->em->flush(); return $domain->setExpiresInDays($this->RDAPService->getExpiresInDays($domain)); + } finally { + $lock->release(); } $randomizer = new Randomizer(); @@ -136,4 +152,13 @@ readonly class AutoRegisterDomainProvider implements ProviderInterface return $domain->setExpiresInDays($this->RDAPService->getExpiresInDays($domain)); } + + private function createDomainLock(string $ldhName): SharedLockInterface + { + return $this->lockFactory->createLockFromKey( + new Key('domain_update.'.$ldhName), + ttl: 600, + autoRelease: false + ); + } } From 7c22e037d0a29e3955b9eaf07b80f3388c7e5220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sat, 15 Nov 2025 12:47:58 +0100 Subject: [PATCH 116/131] ci: exclude branch demo-instance --- .github/workflows/publish-docs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index e577819..afd67a2 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -2,7 +2,8 @@ name: Publish Documentation on: push: - paths: ['docs/**'] + paths: [ 'docs/**' ] + branches-ignore: [ demo-instance ] jobs: build: From 9bed601d9c26ce0cc656f5bd7bda27acd0477363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 01:09:23 +0100 Subject: [PATCH 117/131] docs: update add-provider.mdx --- .github/workflows/publish-docs.yml | 2 +- docs/astro.config.mjs | 23 +- docs/package.json | 8 +- docs/src/content/docs/en/acknowledgment.mdx | 11 + .../docs/en/developing/add-provider.md | 3 - .../docs/en/developing/add-provider.mdx | 220 ++++ ...technical-stack.md => technical-stack.mdx} | 0 .../{translation.md => translation.mdx} | 0 .../docs/en/features/backorder/connector.mdx | 2 +- docs/src/content/docs/en/features/index.mdx | 10 +- .../configuration.mdx | 2 +- .../install/docker-compose.mdx} | 4 +- .../install}/manual-install.mdx | 62 +- .../docs/en/install-config/upgrade.mdx | 50 + docs/yarn.lock | 1167 ++++++++++++++++- 15 files changed, 1484 insertions(+), 80 deletions(-) create mode 100644 docs/src/content/docs/en/acknowledgment.mdx delete mode 100644 docs/src/content/docs/en/developing/add-provider.md create mode 100644 docs/src/content/docs/en/developing/add-provider.mdx rename docs/src/content/docs/en/developing/{technical-stack.md => technical-stack.mdx} (100%) rename docs/src/content/docs/en/developing/{translation.md => translation.mdx} (100%) rename docs/src/content/docs/en/{self-hosting => install-config}/configuration.mdx (97%) rename docs/src/content/docs/en/{self-hosting/docker-install.mdx => install-config/install/docker-compose.mdx} (87%) rename docs/src/content/docs/en/{self-hosting => install-config/install}/manual-install.mdx (69%) create mode 100644 docs/src/content/docs/en/install-config/upgrade.mdx diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index afd67a2..84b9df8 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -3,7 +3,7 @@ name: Publish Documentation on: push: paths: [ 'docs/**' ] - branches-ignore: [ demo-instance ] + branches: [ develop ] jobs: build: diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 58e1b5c..7bb8055 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -1,6 +1,8 @@ // @ts-check import {defineConfig} from 'astro/config' import starlight from '@astrojs/starlight' +import starlightLinksValidator from 'starlight-links-validator' +import mermaid from "astro-mermaid" const BASE_URL = 'https://domainwatchdog.eu' @@ -25,8 +27,12 @@ export default defineConfig({ sidebar: [ {label: 'Getting started', slug: 'features'}, { - label: 'Self hosting', - autogenerate: {directory: 'self-hosting'}, + label: 'Installation & Configuration', + items: [ + {label: 'Installation', autogenerate: {directory: 'install-config/install'}}, + {slug: 'install-config/configuration'}, + {slug: 'install-config/upgrade'}, + ] }, { label: 'Features', @@ -44,10 +50,9 @@ export default defineConfig({ {slug: 'developing/translation'}, {label: 'Contributing', autogenerate: {directory: 'developing/contributing'}} ], - collapsed: true }, - {label: 'Legal', autogenerate: {directory: 'legal'}, collapsed: true} - + {label: 'Legal', autogenerate: {directory: 'legal'}, collapsed: true}, + {slug: 'acknowledgment'} ], locales: { en: { @@ -106,7 +111,11 @@ _paq.push(['enableHeartBeatTimer']); s.parentNode.insertBefore(g, s); })();` } - ] - }) + ], + plugins: [starlightLinksValidator({ + errorOnLocalLinks: false + })] + }), + mermaid() ] }) diff --git a/docs/package.json b/docs/package.json index a734948..e8c27e7 100644 --- a/docs/package.json +++ b/docs/package.json @@ -18,6 +18,10 @@ "dependencies": { "@astrojs/starlight": "^0.36.2", "astro": "^5.6.1", - "sharp": "^0.34.2" + "astro-mermaid": "^1.1.0", + "mermaid": "^11.12.1", + "sharp": "^0.34.2", + "starlight-contributor-list": "^0.3.1", + "starlight-links-validator": "^0.19.1" } -} \ No newline at end of file +} diff --git a/docs/src/content/docs/en/acknowledgment.mdx b/docs/src/content/docs/en/acknowledgment.mdx new file mode 100644 index 0000000..473dccb --- /dev/null +++ b/docs/src/content/docs/en/acknowledgment.mdx @@ -0,0 +1,11 @@ +--- +title: Acknowledgment +--- +import { ContributorList } from "starlight-contributor-list" + +## Contributors + +A huge thank-you to everyone who has contributed to this project! +Your ideas, bug reports, code improvements, and translations all help make this project better for everyone. + + diff --git a/docs/src/content/docs/en/developing/add-provider.md b/docs/src/content/docs/en/developing/add-provider.md deleted file mode 100644 index 3e622cd..0000000 --- a/docs/src/content/docs/en/developing/add-provider.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Add a provider ---- diff --git a/docs/src/content/docs/en/developing/add-provider.mdx b/docs/src/content/docs/en/developing/add-provider.mdx new file mode 100644 index 0000000..55b2180 --- /dev/null +++ b/docs/src/content/docs/en/developing/add-provider.mdx @@ -0,0 +1,220 @@ +--- +title: Add a Provider +--- +import {FileTree, Steps, Code, LinkCard} from "@astrojs/starlight/components"; + +This project aims to be compatible with as many registrars as possible, giving users a choice when creating a Connector. + +::::caution +Only registrars with a public and documented API can be offered. Using a registrar's private API is strictly prohibited. +:::: + +Adding a new Provider is straightforward. Simply follow the steps below. + +This guide explains how to add support for a new domain registrar. +You’ll implement both the Backend (Provider logic) and the Frontend (configuration form). + +## Prerequisites + + +1. Read the API documentation of the new Provider and identify the sections related to user authentication and domain name registration. +1. Set up your development environment. + + + +## Backend + +In this section, you’ll implement the logic required to interact with the new Provider’s API. + + + 1. Create a new DTO class to validate user authentication data. + + - src + - Dto.Connector + - DefaultProviderDto.php default DTO, which will also be used + - **MySuperRegistrarProviderDto.php** your new DTO class + + + 1. Add the necessary class properties and assertions. + The DTO class must extend `DefaultProviderDto`. + + Only include properties required for user authentication, domain name registration, and any legally required consents. + + + 1. Create a new Provider class. + + - src + - Service + - Provider + - AbstractProvider.php defines the signature of methods + - **MySuperRegistrarProvider.php** your new Provider + + + 1. The class must extend `AbstractProvider`. + Refer to the existing Providers for implementation examples. + + ::::note + You now need to implement the methods defined in `AbstractProvider`. + + Refer to the official Provider API documentation as needed. + :::: + + 1. Implement the `assertAuthentication` method. + + This method validates user authentication data. + Make a request to the Provider’s API to verify that the user’s credentials are valid. + + The method must return `void` when authentication succeeds. + ::::tip + If an issue occurs, throw an appropriate exception from the `App\Exception\Provider` namespace. + :::: + + + 1. Implement the `getCachedTldList` method. + cacheItemPool->getItem('app.provider.my-super-registrar.supported-tld'); + }`} lang="php" title='MySuperRegistrarProvider.php' mark={['my-super-registrar']} /> + + This method returns the cache entry holding the list of TLDs supported by this Provider. + Even if the API does not currently provide this information, implement the method for future compatibility. + + 1. Implement the `getSupportedTldList` method. + + If the Provider API does not offer a way to retrieve supported TLDs, return an empty array `[]`. + Otherwise, call the API and return the list of supported TLDs. + + + 1. Implement the `isSupported` method (if necessary). + Override `isSupported` **only if** the Provider API cannot list supported TLDs. In that case, return `true` to indicate that all TLDs are potentially valid. + + 1. Implement the `orderDomain` method. + + Follow the Provider's API documentation to implement domain ordering using the required properties. + ::::tip + As with authentication, you may throw generic Provider exceptions in case of an error. + :::: + + + 1. Add your Provider to the `ConnectorProvider` enumeration. + MySuperRegistrarProvider::class, + }; + }`} lang="php" title='src/Config/ConnectorProvider.php' /> + + +**Well done!** 🎉 +You have now completed the Backend implementation. +Let’s continue with the Frontend! 🚀 + +## Frontend + + + 1. Create a form containing the necessary fields for your Provider. + + - assets + - utils + - providers + - forms + - DefaultConnectorFormItems.tsx fields shared by all + - **MySuperRegistrarConnectorForm.tsx** + + + 1. Add the fields corresponding to the DTO you created earlier. + Check existing forms for reference. + If the Provider API does not allow retrieving supported TLDs, display this information as in the other forms. + + 1. Add your Provider to the `ConnectorProvider` enumeration. + The value must exactly match the one defined in PHP. + + + + 1. Add the API terms of service link and the reference to your new form in the `index.ts` configuration file. + = { + // ... + [ConnectorProvider.MY_SUPER_REGISTRAR]: { + tosLink: 'https://...', + form: MySuperRegistrarConnectorForm + } + }`} lang="ts" title='assets/utils/providers/index.ts' /> + + 1. Ensure the interface renders correctly and fix any display issues. + + +**Great job!** 🎉 +Your Frontend implementation is now complete. + +## Testing + + + 1. Add the corresponding test function in the Provider test collection. + getParameter('my_super_registrar_token'); + if (!$token) { + $this->markTestSkipped('Missing My Super Registrar token'); + } + + $this->testGenericProvider(ConnectorProvider::MY_SUPER_REGISTRAR, [ + 'waiveRetractationPeriod' => true, + 'acceptConditions' => true, + 'ownerLegalAge' => true, + 'token' => $token, + ]); + }`} lang="php" title='tests/Service/Provider/AbstractProviderTest.php' /> + + 1. Create a Symfony configuration parameter connecting the environment variable to the credentials. + + 1. Run the tests with PHPUnit: + ```shell + php vendor/bin/phpunit + ``` + 1. Ensure the test passes. + If it fails, fix the implementation accordingly. + Consider enabling code coverage to identify executed sections. + + +That's it! You’ve now finished implementing a new Provider. ✨ diff --git a/docs/src/content/docs/en/developing/technical-stack.md b/docs/src/content/docs/en/developing/technical-stack.mdx similarity index 100% rename from docs/src/content/docs/en/developing/technical-stack.md rename to docs/src/content/docs/en/developing/technical-stack.mdx diff --git a/docs/src/content/docs/en/developing/translation.md b/docs/src/content/docs/en/developing/translation.mdx similarity index 100% rename from docs/src/content/docs/en/developing/translation.md rename to docs/src/content/docs/en/developing/translation.mdx diff --git a/docs/src/content/docs/en/features/backorder/connector.mdx b/docs/src/content/docs/en/features/backorder/connector.mdx index 9a04af3..a139db6 100644 --- a/docs/src/content/docs/en/features/backorder/connector.mdx +++ b/docs/src/content/docs/en/features/backorder/connector.mdx @@ -11,7 +11,7 @@ domain registration. 1. Choose an external API provider from the list of supported registrars. - + 2. Enter the required information using the credentials obtained from your provider’s customer area :::tip{icon="heart"} A link allows you to directly access the Provider's page to retrieve this authentication information diff --git a/docs/src/content/docs/en/features/index.mdx b/docs/src/content/docs/en/features/index.mdx index a0c7ab4..0aacd98 100644 --- a/docs/src/content/docs/en/features/index.mdx +++ b/docs/src/content/docs/en/features/index.mdx @@ -43,7 +43,7 @@ To read the documentation related to domain name search, please click on the lin + href="/en/features/search/domain-search"/> ::: --- @@ -63,7 +63,7 @@ To read the documentation related to the Watchlist, please click on the link bel + href="/en/features/tracking/watchlist"/> ::: ### Watchlist notifications @@ -84,14 +84,14 @@ To read the documentation related to Connector, please click on the link below. + href="/en/features/backorder/connector"/> ::: ### Supported registrar list + href="/en/features/backorder/supported-registrar"/> --- @@ -107,5 +107,5 @@ To read the documentation related to the Tracking table, please click on the lin + href="/en/features/tracking/tracking-table"/> ::: diff --git a/docs/src/content/docs/en/self-hosting/configuration.mdx b/docs/src/content/docs/en/install-config/configuration.mdx similarity index 97% rename from docs/src/content/docs/en/self-hosting/configuration.mdx rename to docs/src/content/docs/en/install-config/configuration.mdx index bc5428e..f5b153d 100644 --- a/docs/src/content/docs/en/self-hosting/configuration.mdx +++ b/docs/src/content/docs/en/install-config/configuration.mdx @@ -4,7 +4,7 @@ title: Configuration import {LinkCard} from '@astrojs/starlight/components'; - + ## Environment variables diff --git a/docs/src/content/docs/en/self-hosting/docker-install.mdx b/docs/src/content/docs/en/install-config/install/docker-compose.mdx similarity index 87% rename from docs/src/content/docs/en/self-hosting/docker-install.mdx rename to docs/src/content/docs/en/install-config/install/docker-compose.mdx index 3bcc323..cb214c2 100644 --- a/docs/src/content/docs/en/self-hosting/docker-install.mdx +++ b/docs/src/content/docs/en/install-config/install/docker-compose.mdx @@ -1,12 +1,12 @@ --- -title: Install with Docker +title: Docker Compose installation --- import {LinkCard} from '@astrojs/starlight/components'; 1. Download the [docker-compose.yml](https://github.com/maelgangloff/domain-watchdog/blob/develop/docker-compose.yml) and modify it as needed 2. Download the [.env](https://github.com/maelgangloff/domain-watchdog/blob/develop/.env) and modify it as needed - + 3. Add static files to customize your instance (under `public/content`) 4. Pull the latest version of the Domain Watchdog image from Docker Hub diff --git a/docs/src/content/docs/en/self-hosting/manual-install.mdx b/docs/src/content/docs/en/install-config/install/manual-install.mdx similarity index 69% rename from docs/src/content/docs/en/self-hosting/manual-install.mdx rename to docs/src/content/docs/en/install-config/install/manual-install.mdx index 9b65dfe..597d1f1 100644 --- a/docs/src/content/docs/en/self-hosting/manual-install.mdx +++ b/docs/src/content/docs/en/install-config/install/manual-install.mdx @@ -1,15 +1,13 @@ --- -title: Manual Install +title: Manual installation --- import {FileTree, LinkCard, Steps} from '@astrojs/starlight/components'; -## Installation - To deploy a Domain Watchdog instance, please refer to the Symfony documentation on [How to deploy a Symfony application](https://symfony.com/doc/current/deployment.html). -### Prerequisites +## Prerequisites - PHP 8.4 or higher - PostgreSQL 16 or higher @@ -19,7 +17,7 @@ It is crucial that the Domain Watchdog instance is placed in a clean environment queried. In particular, the DNS servers and root certificates of the system must be trusted. -### Steps +## Steps Clone the repository: @@ -27,7 +25,7 @@ Clone the repository: git clone https://github.com/maelgangloff/domain-watchdog.git ``` -#### Backend +### Backend 1. Install dependencies @@ -38,7 +36,7 @@ git clone https://github.com/maelgangloff/domain-watchdog.git ```shell cp .env .env.local ``` - + 3. Generate the cryptographic key pair for the JWT signature ```shell @@ -59,7 +57,7 @@ git clone https://github.com/maelgangloff/domain-watchdog.git 7. Don't forget to set up workers to process the [message queue](https://symfony.com/doc/current/messenger.html) -#### Frontend +### Frontend 1. Install dependencies @@ -87,51 +85,3 @@ git clone https://github.com/maelgangloff/domain-watchdog.git - favicon.ico - -## Update - -**Any updates are your responsibility. Make a backup of the data if necessary.** - -Fetch updates from the remote repository: - -```shell -git pull origin master -``` - -### Backend - - -1. Install dependencies - ```shell - composer install - ``` -2. Run database migrations - ```shell - php bin/console doctrine:migrations:migrate - ``` -3. Clearing the Symfony cache - ```shell - php bin/console cache:clear - ``` -4. Build assets - ```shell - php bin/console assets:install - ``` - - -### Frontend - - -1. Install dependencies - ```shell - yarn install - ``` -2. Generate language files - ```shell - yarn run ttag:po2json - ``` -3. Make the final build - ```shell - yarn build - ``` - diff --git a/docs/src/content/docs/en/install-config/upgrade.mdx b/docs/src/content/docs/en/install-config/upgrade.mdx new file mode 100644 index 0000000..87c8b96 --- /dev/null +++ b/docs/src/content/docs/en/install-config/upgrade.mdx @@ -0,0 +1,50 @@ +--- +title: Manual Upgrade +--- +import {Steps} from "@astrojs/starlight/components"; + +**Any updates are your responsibility. Make a backup of the data if necessary.** + +Fetch updates from the remote repository: + +```shell +git pull origin master +``` + +## Backend + + +1. Install dependencies + ```shell + composer install + ``` +2. Run database migrations + ```shell + php bin/console doctrine:migrations:migrate + ``` +3. Clearing the Symfony cache + ```shell + php bin/console cache:clear + ``` +4. Build assets + ```shell + php bin/console assets:install + ``` + + +## Frontend + + +1. Install dependencies + ```shell + yarn install + ``` +2. Generate language files + ```shell + yarn run ttag:po2json + ``` +3. Make the final build + ```shell + yarn build + ``` + diff --git a/docs/yarn.lock b/docs/yarn.lock index 117833b..3a3f52d 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -2,6 +2,29 @@ # yarn lockfile v1 +"@11ty/eleventy-fetch@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@11ty/eleventy-fetch/-/eleventy-fetch-4.0.1.tgz#8431d60d2f2cbb10b8fd71ef661e71ecfe2f8ab6" + integrity sha512-yIiLM5ziBmg86i4TlXpBdcIygJHvh/GgPJyAiFOckO9H4y9cQDM8eIcJCUQ4Mum0NEVui/OjhEut2R08xw0vlQ== + dependencies: + debug "^4.3.4" + flat-cache "^3.0.4" + node-fetch "^2.6.7" + p-queue "^6.6.2" + +"@antfu/install-pkg@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz#78fa036be1a6081b5a77a5cf59f50c7752b6ba26" + integrity sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ== + dependencies: + package-manager-detector "^1.3.0" + tinyexec "^1.0.1" + +"@antfu/utils@^9.2.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-9.3.0.tgz#e05e277f788ac3bec771f57a49fb64546bb32374" + integrity sha512-9hFT4RauhcUzqOE4f1+frMKLZrgNog5b06I7VmZQV1BkvwvqrbC8EBZf3L1eEL2AKb6rNKjER0sEvJiSP1FXEA== + "@astrojs/compiler@^2.12.2": version "2.13.0" resolved "https://registry.yarnpkg.com/@astrojs/compiler/-/compiler-2.13.0.tgz#a40bef3106fff808bd91b41680275a7e28996d63" @@ -150,6 +173,11 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" +"@braintree/sanitize-url@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz#15e19737d946559289b915e5dad3b4c28407735e" + integrity sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw== + "@capsizecss/unpack@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@capsizecss/unpack/-/unpack-3.0.1.tgz#d40cd7fded06110a3d6198dd1e7a9bbcded52880" @@ -157,6 +185,38 @@ dependencies: fontkit "^2.0.2" +"@chevrotain/cst-dts-gen@11.0.3": + version "11.0.3" + resolved "https://registry.yarnpkg.com/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz#5e0863cc57dc45e204ccfee6303225d15d9d4783" + integrity sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ== + dependencies: + "@chevrotain/gast" "11.0.3" + "@chevrotain/types" "11.0.3" + lodash-es "4.17.21" + +"@chevrotain/gast@11.0.3": + version "11.0.3" + resolved "https://registry.yarnpkg.com/@chevrotain/gast/-/gast-11.0.3.tgz#e84d8880323fe8cbe792ef69ce3ffd43a936e818" + integrity sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q== + dependencies: + "@chevrotain/types" "11.0.3" + lodash-es "4.17.21" + +"@chevrotain/regexp-to-ast@11.0.3": + version "11.0.3" + resolved "https://registry.yarnpkg.com/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz#11429a81c74a8e6a829271ce02fc66166d56dcdb" + integrity sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA== + +"@chevrotain/types@11.0.3": + version "11.0.3" + resolved "https://registry.yarnpkg.com/@chevrotain/types/-/types-11.0.3.tgz#f8a03914f7b937f594f56eb89312b3b8f1c91848" + integrity sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ== + +"@chevrotain/utils@11.0.3": + version "11.0.3" + resolved "https://registry.yarnpkg.com/@chevrotain/utils/-/utils-11.0.3.tgz#e39999307b102cff3645ec4f5b3665f5297a2224" + integrity sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ== + "@ctrl/tinycolor@^4.0.4": version "4.2.0" resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz#ba5d0b917303c0b3d3c14c4865cdc6ded25ac05f" @@ -336,6 +396,25 @@ dependencies: "@expressive-code/core" "^0.41.3" +"@iconify/types@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@iconify/types/-/types-2.0.0.tgz#ab0e9ea681d6c8a1214f30cd741fe3a20cc57f57" + integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== + +"@iconify/utils@^3.0.1": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@iconify/utils/-/utils-3.0.2.tgz#9599607f20690cd3e7a5d2d459af0eb81a89dc2b" + integrity sha512-EfJS0rLfVuRuJRn4psJHtK2A9TqVnkxPpHY6lYHiB9+8eSuudsxbwMiavocG45ujOo6FJ+CIRlRnlOGinzkaGQ== + dependencies: + "@antfu/install-pkg" "^1.1.0" + "@antfu/utils" "^9.2.0" + "@iconify/types" "^2.0.0" + debug "^4.4.1" + globals "^15.15.0" + kolorist "^1.8.0" + local-pkg "^1.1.1" + mlly "^1.7.4" + "@img/colour@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@img/colour/-/colour-1.0.0.tgz#d2fabb223455a793bf3bf9c70de3d28526aa8311" @@ -519,6 +598,13 @@ unist-util-visit "^5.0.0" vfile "^6.0.0" +"@mermaid-js/parser@^0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@mermaid-js/parser/-/parser-0.6.3.tgz#3ce92dad2c5d696d29e11e21109c66a7886c824e" + integrity sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA== + dependencies: + langium "3.3.1" + "@oslojs/encoding@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@oslojs/encoding/-/encoding-1.1.0.tgz#55f3d9a597430a01f2a5ef63c6b42f769f9ce34e" @@ -739,6 +825,216 @@ dependencies: tslib "^2.8.0" +"@types/d3-array@*": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.2.tgz#e02151464d02d4a1b44646d0fcdb93faf88fde8c" + integrity sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw== + +"@types/d3-axis@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-3.0.6.tgz#e760e5765b8188b1defa32bc8bb6062f81e4c795" + integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-brush@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.6.tgz#c2f4362b045d472e1b186cdbec329ba52bdaee6c" + integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-chord@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-3.0.6.tgz#1706ca40cf7ea59a0add8f4456efff8f8775793d" + integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-contour@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-3.0.6.tgz#9ada3fa9c4d00e3a5093fed0356c7ab929604231" + integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== + dependencies: + "@types/d3-array" "*" + "@types/geojson" "*" + +"@types/d3-delaunay@*": + version "6.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz#185c1a80cc807fdda2a3fe960f7c11c4a27952e1" + integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== + +"@types/d3-dispatch@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz#ef004d8a128046cfce434d17182f834e44ef95b2" + integrity sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA== + +"@types/d3-drag@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-3.0.7.tgz#b13aba8b2442b4068c9a9e6d1d82f8bcea77fc02" + integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-dsv@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17" + integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== + +"@types/d3-ease@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== + +"@types/d3-fetch@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980" + integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== + dependencies: + "@types/d3-dsv" "*" + +"@types/d3-force@*": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.10.tgz#6dc8fc6e1f35704f3b057090beeeb7ac674bff1a" + integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw== + +"@types/d3-format@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-3.0.4.tgz#b1e4465644ddb3fdf3a263febb240a6cd616de90" + integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== + +"@types/d3-geo@*": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440" + integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== + dependencies: + "@types/geojson" "*" + +"@types/d3-hierarchy@*": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz#6023fb3b2d463229f2d680f9ac4b47466f71f17b" + integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== + +"@types/d3-interpolate@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-path@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.1.tgz#f632b380c3aca1dba8e34aa049bcd6a4af23df8a" + integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== + +"@types/d3-polygon@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz#dfae54a6d35d19e76ac9565bcb32a8e54693189c" + integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== + +"@types/d3-quadtree@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz#d4740b0fe35b1c58b66e1488f4e7ed02952f570f" + integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== + +"@types/d3-random@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-random/-/d3-random-3.0.3.tgz#ed995c71ecb15e0cd31e22d9d5d23942e3300cfb" + integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== + +"@types/d3-scale-chromatic@*": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#dc6d4f9a98376f18ea50bad6c39537f1b5463c39" + integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ== + +"@types/d3-scale@*": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.9.tgz#57a2f707242e6fe1de81ad7bfcccaaf606179afb" + integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== + dependencies: + "@types/d3-time" "*" + +"@types/d3-selection@*": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.11.tgz#bd7a45fc0a8c3167a631675e61bc2ca2b058d4a3" + integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w== + +"@types/d3-shape@*": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.7.tgz#2b7b423dc2dfe69c8c93596e673e37443348c555" + integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg== + dependencies: + "@types/d3-path" "*" + +"@types/d3-time-format@*": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz#d6bc1e6b6a7db69cccfbbdd4c34b70632d9e9db2" + integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== + +"@types/d3-time@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.4.tgz#8472feecd639691450dd8000eb33edd444e1323f" + integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== + +"@types/d3-timer@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== + +"@types/d3-transition@*": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.9.tgz#1136bc57e9ddb3c390dccc9b5ff3b7d2b8d94706" + integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-zoom@*": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz#dccb32d1c56b1e1c6e0f1180d994896f038bc40b" + integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== + dependencies: + "@types/d3-interpolate" "*" + "@types/d3-selection" "*" + +"@types/d3@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@types/d3/-/d3-7.4.3.tgz#d4550a85d08f4978faf0a4c36b848c61eaac07e2" + integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== + dependencies: + "@types/d3-array" "*" + "@types/d3-axis" "*" + "@types/d3-brush" "*" + "@types/d3-chord" "*" + "@types/d3-color" "*" + "@types/d3-contour" "*" + "@types/d3-delaunay" "*" + "@types/d3-dispatch" "*" + "@types/d3-drag" "*" + "@types/d3-dsv" "*" + "@types/d3-ease" "*" + "@types/d3-fetch" "*" + "@types/d3-force" "*" + "@types/d3-format" "*" + "@types/d3-geo" "*" + "@types/d3-hierarchy" "*" + "@types/d3-interpolate" "*" + "@types/d3-path" "*" + "@types/d3-polygon" "*" + "@types/d3-quadtree" "*" + "@types/d3-random" "*" + "@types/d3-scale" "*" + "@types/d3-scale-chromatic" "*" + "@types/d3-selection" "*" + "@types/d3-shape" "*" + "@types/d3-time" "*" + "@types/d3-time-format" "*" + "@types/d3-timer" "*" + "@types/d3-transition" "*" + "@types/d3-zoom" "*" + "@types/debug@^4.0.0": version "4.1.12" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" @@ -765,6 +1061,11 @@ dependencies: "@types/node" "*" +"@types/geojson@*": + version "7946.0.16" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a" + integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== + "@types/hast@^3.0.0", "@types/hast@^3.0.4": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" @@ -813,6 +1114,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== +"@types/picomatch@^3.0.1": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-3.0.2.tgz#27edebec66726b2aabdca71338d129ffe9fffcf9" + integrity sha512-n0i8TD3UDB7paoMMxA3Y65vUncFJXjcUf7lQY7YyKGl6031FNjfsLs6pdLFCy2GNFxItPJG8GvvpbZc2skH7WA== + "@types/sax@^1.2.1": version "1.2.7" resolved "https://registry.yarnpkg.com/@types/sax/-/sax-1.2.7.tgz#ba5fe7df9aa9c89b6dff7688a19023dd2963091d" @@ -820,6 +1126,11 @@ 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" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + "@types/unist@*", "@types/unist@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" @@ -852,6 +1163,13 @@ ansi-align@^3.0.1: dependencies: string-width "^4.1.0" +ansi-escapes@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-7.2.0.tgz#31b25afa3edd3efc09d98c2fee831d460ff06b49" + integrity sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw== + dependencies: + environment "^1.0.0" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -907,6 +1225,15 @@ astro-expressive-code@^0.41.1: dependencies: rehype-expressive-code "^0.41.3" +astro-mermaid@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/astro-mermaid/-/astro-mermaid-1.1.0.tgz#dabed812a444239a0b49c91a46ec217ec6e14358" + integrity sha512-eW5aqOISq2Uf8goCedSl12d0qy8y77A+jRwKxwYc7LvrEN9HiCQuwTGu3zQvi0mB4+ydwaueaYbFUFSCIs2jrA== + dependencies: + import-meta-resolve "^4.2.0" + mdast-util-to-string "^4.0.0" + unist-util-visit "^5.0.0" + astro@^5.6.1: version "5.15.5" resolved "https://registry.yarnpkg.com/astro/-/astro-5.15.5.tgz#b8859795cee410764ae66311ddbbcf8b566fceaf" @@ -987,6 +1314,11 @@ 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== + base-64@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/base-64/-/base-64-1.0.0.tgz#09d0f2084e32a3fd08c2475b973788eee6ae8f4a" @@ -1030,6 +1362,14 @@ boxen@8.0.1: widest-line "^5.0.0" wrap-ansi "^9.0.0" +brace-expansion@^1.1.7: + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + brotli@^1.3.2: version "1.3.3" resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.3.tgz#7365d8cc00f12cf765d2b2c898716bcf4b604d48" @@ -1072,6 +1412,25 @@ character-reference-invalid@^2.0.0: resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== +chevrotain-allstar@~0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz#b7412755f5d83cc139ab65810cdb00d8db40e6ca" + integrity sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw== + dependencies: + lodash-es "^4.17.21" + +chevrotain@~11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/chevrotain/-/chevrotain-11.0.3.tgz#88ffc1fb4b5739c715807eaeedbbf200e202fc1b" + integrity sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw== + dependencies: + "@chevrotain/cst-dts-gen" "11.0.3" + "@chevrotain/gast" "11.0.3" + "@chevrotain/regexp-to-ast" "11.0.3" + "@chevrotain/types" "11.0.3" + "@chevrotain/utils" "11.0.3" + lodash-es "4.17.21" + chokidar@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" @@ -1109,11 +1468,36 @@ comma-separated-tokens@^2.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== +commander@7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w== +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +confbox@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06" + integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w== + +confbox@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.2.2.tgz#8652f53961c74d9e081784beed78555974a9c110" + integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ== + cookie-es@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.2.2.tgz#18ceef9eb513cac1cb6c14bcbf8bdb2679b34821" @@ -1124,6 +1508,20 @@ cookie@^1.0.2: resolved "https://registry.yarnpkg.com/cookie/-/cookie-1.0.2.tgz#27360701532116bd3f1f9416929d176afe1e4610" integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA== +cose-base@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-1.0.3.tgz#650334b41b869578a543358b80cda7e0abe0a60a" + integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== + dependencies: + layout-base "^1.0.0" + +cose-base@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-2.2.0.tgz#1c395c35b6e10bb83f9769ca8b817d614add5c01" + integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== + dependencies: + layout-base "^2.0.0" + crossws@^0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/crossws/-/crossws-0.3.5.tgz#daad331d44148ea6500098bc858869f3a5ab81a6" @@ -1149,7 +1547,310 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -debug@^4.0.0, debug@^4.4.0, debug@^4.4.1: +cytoscape-cose-bilkent@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz#762fa121df9930ffeb51a495d87917c570ac209b" + integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== + dependencies: + cose-base "^1.0.0" + +cytoscape-fcose@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz#e4d6f6490df4fab58ae9cea9e5c3ab8d7472f471" + integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== + dependencies: + cose-base "^2.2.0" + +cytoscape@^3.29.3: + version "3.33.1" + resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.33.1.tgz#449e05d104b760af2912ab76482d24c01cdd4c97" + integrity sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ== + +"d3-array@1 - 2": + version "2.12.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +d3-axis@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322" + integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== + +d3-brush@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c" + integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "3" + d3-transition "3" + +d3-chord@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-3.0.1.tgz#d156d61f485fce8327e6abf339cb41d8cbba6966" + integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== + dependencies: + d3-path "1 - 3" + +"d3-color@1 - 3", d3-color@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +d3-contour@4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-4.0.2.tgz#bb92063bc8c5663acb2422f99c73cbb6c6ae3bcc" + integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA== + dependencies: + d3-array "^3.2.0" + +d3-delaunay@6: + version "6.0.4" + resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-6.0.4.tgz#98169038733a0a5babbeda55054f795bb9e4a58b" + integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== + dependencies: + delaunator "5" + +"d3-dispatch@1 - 3", d3-dispatch@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== + +"d3-drag@2 - 3", d3-drag@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba" + integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== + dependencies: + d3-dispatch "1 - 3" + d3-selection "3" + +"d3-dsv@1 - 3", d3-dsv@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73" + integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== + dependencies: + commander "7" + iconv-lite "0.6" + rw "1" + +"d3-ease@1 - 3", d3-ease@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +d3-fetch@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-3.0.1.tgz#83141bff9856a0edb5e38de89cdcfe63d0a60a22" + integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== + dependencies: + d3-dsv "1 - 3" + +d3-force@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4" + integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== + dependencies: + d3-dispatch "1 - 3" + d3-quadtree "1 - 3" + d3-timer "1 - 3" + +"d3-format@1 - 3", d3-format@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +d3-geo@3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.1.1.tgz#6027cf51246f9b2ebd64f99e01dc7c3364033a4d" + integrity sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q== + dependencies: + d3-array "2.5.0 - 3" + +d3-hierarchy@3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b01cd42c1eed3d46db77a5966cf726f8c09160c6" + integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== + +"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + +d3-polygon@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-3.0.1.tgz#0b45d3dd1c48a29c8e057e6135693ec80bf16398" + integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== + +"d3-quadtree@1 - 3", d3-quadtree@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz#6dca3e8be2b393c9a9d514dabbd80a92deef1a4f" + integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== + +d3-random@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4" + integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== + +d3-sankey@^0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.12.3.tgz#b3c268627bd72e5d80336e8de6acbfec9d15d01d" + integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ== + dependencies: + d3-array "1 - 2" + d3-shape "^1.2.0" + +d3-scale-chromatic@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#34c39da298b23c20e02f1a4b239bd0f22e7f1314" + integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ== + dependencies: + d3-color "1 - 3" + d3-interpolate "1 - 3" + +d3-scale@4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +"d3-selection@2 - 3", d3-selection@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" + integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== + +d3-shape@3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + +d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +"d3-time-format@2 - 4", d3-time-format@4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + +"d3-timer@1 - 3", d3-timer@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + +"d3-transition@2 - 3", d3-transition@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" + +d3-zoom@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3" + integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "2 - 3" + d3-transition "2 - 3" + +d3@^7.9.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/d3/-/d3-7.9.0.tgz#579e7acb3d749caf8860bd1741ae8d371070cd5d" + integrity sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA== + dependencies: + d3-array "3" + d3-axis "3" + d3-brush "3" + d3-chord "3" + d3-color "3" + d3-contour "4" + d3-delaunay "6" + d3-dispatch "3" + d3-drag "3" + d3-dsv "3" + d3-ease "3" + d3-fetch "3" + d3-force "3" + d3-format "3" + d3-geo "3" + d3-hierarchy "3" + d3-interpolate "3" + d3-path "3" + d3-polygon "3" + d3-quadtree "3" + d3-random "3" + d3-scale "4" + d3-scale-chromatic "3" + d3-selection "3" + d3-shape "3" + d3-time "3" + d3-time-format "4" + d3-timer "3" + d3-transition "3" + d3-zoom "3" + +dagre-d3-es@7.0.13: + version "7.0.13" + resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz#acfb4b449f6dcdd48d8ea8081a6d8c59bc8128c3" + integrity sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q== + dependencies: + d3 "^7.9.0" + lodash-es "^4.17.21" + +dayjs@^1.11.18: + version "1.11.19" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.19.tgz#15dc98e854bb43917f12021806af897c58ae2938" + integrity sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw== + +debug@^4.0.0, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1: version "4.4.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== @@ -1168,6 +1869,13 @@ defu@^6.1.4: resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== +delaunator@5: + version "5.0.1" + resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.1.tgz#39032b08053923e924d6094fe2cde1a99cc51278" + integrity sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw== + dependencies: + robust-predicates "^3.0.2" + dequal@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" @@ -1222,6 +1930,13 @@ dlv@^1.1.3: resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== +dompurify@^3.2.5: + version "3.3.0" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.3.0.tgz#aaaadbb83d87e1c2fbb066452416359e5b62ec97" + integrity sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ== + optionalDependencies: + "@types/trusted-types" "^2.0.7" + dset@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.4.tgz#f8eaf5f023f068a036d08cd07dc9ffb7d0065248" @@ -1242,6 +1957,11 @@ entities@^6.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== +environment@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/environment/-/environment-1.1.0.tgz#8e86c66b180f363c7ab311787e0259665f45a9f1" + integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q== + es-module-lexer@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" @@ -1363,6 +2083,11 @@ estree-walker@^3.0.0, estree-walker@^3.0.3: dependencies: "@types/estree" "^1.0.0" +eventemitter3@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + eventemitter3@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" @@ -1378,6 +2103,11 @@ expressive-code@^0.41.3: "@expressive-code/plugin-shiki" "^0.41.3" "@expressive-code/plugin-text-markers" "^0.41.3" +exsolve@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.8.tgz#7f5e34da61cd1116deda5136e62292c096f50613" + integrity sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA== + extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -1393,6 +2123,20 @@ fdir@^6.4.4, fdir@^6.5.0: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== +flat-cache@^3.0.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flatted@^3.2.9: + version "3.3.3" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" + integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== + flattie@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/flattie/-/flattie-1.1.1.tgz#88182235723113667d36217fec55359275d6fe3d" @@ -1421,6 +2165,11 @@ fontkit@^2.0.2, fontkit@^2.0.4: unicode-properties "^1.4.0" unicode-trie "^2.0.0" +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -1436,6 +2185,23 @@ github-slugger@^2.0.0: resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-2.0.0.tgz#52cf2f9279a21eb6c59dd385b410f0c0adda8f1a" integrity sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw== +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^15.15.0: + version "15.15.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.15.0.tgz#7c4761299d41c32b075715a4ce1ede7897ff72a8" + integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg== + h3@^1.15.4: version "1.15.4" resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.4.tgz#022ab3563bbaf2108c25375c40460f3e54a5fe02" @@ -1451,6 +2217,16 @@ h3@^1.15.4: ufo "^1.6.1" uncrypto "^0.1.3" +hachure-fill@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/hachure-fill/-/hachure-fill-0.5.2.tgz#d19bc4cc8750a5962b47fb1300557a85fcf934cc" + integrity sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg== + +has-flag@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-5.0.1.tgz#5483db2ae02a472d1d0691462fc587d1843cd940" + integrity sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA== + hast-util-embedded@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz#be4477780fbbe079cdba22982e357a0de4ba853e" @@ -1723,21 +2499,56 @@ i18next@^23.11.5: dependencies: "@babel/runtime" "^7.23.2" +iconv-lite@0.6: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + import-meta-resolve@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz#08cb85b5bd37ecc8eb1e0f670dc2767002d43734" integrity sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg== +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + inline-style-parser@0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.6.tgz#e6bbb5288a635f6284a6249ce754da55c4bd1ff5" integrity sha512-gtGXVaBdl5mAes3rPcMedEBm12ibjt1kDMFfheul1wUAOVEJW60voNdMVzVkfLN06O7ZaD/rxhfKgtlgtTbMjg== +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + iron-webcrypto@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz#aa60ff2aa10550630f4c0b11fd2442becdb35a6f" integrity sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg== +is-absolute-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-4.0.1.tgz#16e4d487d4fded05cfe0685e53ec86804a5e94dc" + integrity sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A== + is-alphabetical@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" @@ -1797,16 +2608,85 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +katex@^0.16.22: + version "0.16.25" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.25.tgz#61699984277e3bdb3e89e0e446b83cd0a57d87db" + integrity sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q== + dependencies: + commander "^8.3.0" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +khroma@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/khroma/-/khroma-2.1.0.tgz#45f2ce94ce231a437cf5b63c2e886e6eb42bbbb1" + integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw== + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kleur@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + klona@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== +kolorist@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c" + integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== + +langium@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/langium/-/langium-3.3.1.tgz#da745a40d5ad8ee565090fed52eaee643be4e591" + integrity sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w== + dependencies: + chevrotain "~11.0.3" + chevrotain-allstar "~0.3.0" + vscode-languageserver "~9.0.1" + vscode-languageserver-textdocument "~1.0.11" + vscode-uri "~3.0.8" + +layout-base@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-1.0.2.tgz#1291e296883c322a9dd4c5dd82063721b53e26e2" + integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== + +layout-base@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-2.0.1.tgz#d0337913586c90f9c2c075292069f5c2da5dd285" + integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== + +local-pkg@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-1.1.2.tgz#c03d208787126445303f8161619dc701afa4abb5" + integrity sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A== + dependencies: + mlly "^1.7.4" + pkg-types "^2.3.0" + quansync "^0.2.11" + +lodash-es@4.17.21, lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + longest-streak@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" @@ -1843,6 +2723,11 @@ markdown-table@^3.0.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a" integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw== +marked@^16.2.1: + version "16.4.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-16.4.2.tgz#4959a64be6c486f0db7467ead7ce288de54290a3" + integrity sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA== + mdast-util-definitions@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz#c1bb706e5e76bb93f9a09dd7af174002ae69ac24" @@ -1972,7 +2857,7 @@ mdast-util-mdx-expression@^2.0.0: mdast-util-from-markdown "^2.0.0" mdast-util-to-markdown "^2.0.0" -mdast-util-mdx-jsx@^3.0.0: +mdast-util-mdx-jsx@^3.0.0, mdast-util-mdx-jsx@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz#fd04c67a2a7499efb905a8a5c578dddc9fdada0d" integrity sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q== @@ -2063,6 +2948,32 @@ mdn-data@2.12.2: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.12.2.tgz#9ae6c41a9e65adf61318b32bff7b64fbfb13f8cf" integrity sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA== +mermaid@^11.12.1: + version "11.12.1" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-11.12.1.tgz#97445451ce7d0d3740bc2159cb25464bece60b67" + integrity sha512-UlIZrRariB11TY1RtTgUWp65tphtBv4CSq7vyS2ZZ2TgoMjs2nloq+wFqxiwcxlhHUvs7DPGgMjs2aeQxz5h9g== + dependencies: + "@braintree/sanitize-url" "^7.1.1" + "@iconify/utils" "^3.0.1" + "@mermaid-js/parser" "^0.6.3" + "@types/d3" "^7.4.3" + cytoscape "^3.29.3" + cytoscape-cose-bilkent "^4.1.0" + cytoscape-fcose "^2.2.0" + d3 "^7.9.0" + d3-sankey "^0.12.3" + dagre-d3-es "7.0.13" + dayjs "^1.11.18" + dompurify "^3.2.5" + katex "^0.16.22" + khroma "^2.1.0" + lodash-es "^4.17.21" + marked "^16.2.1" + roughjs "^4.6.6" + stylis "^4.3.6" + ts-dedent "^2.2.0" + uuid "^11.1.0" + 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" @@ -2443,6 +3354,23 @@ micromark@^4.0.0: micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mlly@^1.7.4: + version "1.8.0" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.8.0.tgz#e074612b938af8eba1eaf43299cbc89cb72d824e" + integrity sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g== + dependencies: + acorn "^8.15.0" + pathe "^2.0.3" + pkg-types "^1.3.1" + ufo "^1.6.1" + mrmime@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" @@ -2475,6 +3403,13 @@ node-fetch-native@^1.6.7: resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.7.tgz#9d09ca63066cc48423211ed4caf5d70075d76a71" integrity sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q== +node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + node-mock-http@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/node-mock-http/-/node-mock-http-1.0.3.tgz#4e55e093267a3b910cded7354389ce2d02c89e77" @@ -2506,6 +3441,13 @@ ohash@^2.0.0: resolved "https://registry.yarnpkg.com/ohash/-/ohash-2.0.11.tgz#60b11e8cff62ca9dee88d13747a5baa145f5900b" integrity sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ== +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + oniguruma-parser@^0.12.1: version "0.12.1" resolved "https://registry.yarnpkg.com/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz#82ba2208d7a2b69ee344b7efe0ae930c627dcc4a" @@ -2520,6 +3462,11 @@ oniguruma-to-es@^4.3.3: regex "^6.0.1" regex-recursion "^6.0.2" +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + p-limit@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-6.2.0.tgz#c254d22ba6aeef441a3564c5e6c2f2da59268a0f" @@ -2527,6 +3474,14 @@ p-limit@^6.2.0: dependencies: yocto-queue "^1.1.1" +p-queue@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== + dependencies: + eventemitter3 "^4.0.4" + p-timeout "^3.2.0" + p-queue@^8.1.0: version "8.1.1" resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-8.1.1.tgz#dac3e8c57412fffa18fe6c341b141dbb3a16408b" @@ -2535,6 +3490,13 @@ p-queue@^8.1.0: eventemitter3 "^5.0.1" p-timeout "^6.1.2" +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-timeout@^6.1.2: version "6.1.4" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-6.1.4.tgz#418e1f4dd833fa96a2e3f532547dd2abdb08dbc2" @@ -2594,6 +3556,21 @@ parse5@^7.0.0: dependencies: entities "^6.0.0" +path-data-parser@0.1.0, path-data-parser@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/path-data-parser/-/path-data-parser-0.1.0.tgz#8f5ba5cc70fc7becb3dcefaea08e2659aba60b8c" + integrity sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +pathe@^2.0.1, pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== + picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -2609,6 +3586,37 @@ picomatch@^4.0.2, picomatch@^4.0.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== +pkg-types@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df" + integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ== + dependencies: + confbox "^0.1.8" + mlly "^1.7.4" + pathe "^2.0.1" + +pkg-types@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-2.3.0.tgz#037f2c19bd5402966ff6810e32706558cb5b5726" + integrity sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig== + dependencies: + confbox "^0.2.2" + exsolve "^1.0.7" + pathe "^2.0.3" + +points-on-curve@0.2.0, points-on-curve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/points-on-curve/-/points-on-curve-0.2.0.tgz#7dbb98c43791859434284761330fa893cb81b4d1" + integrity sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A== + +points-on-path@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/points-on-path/-/points-on-path-0.2.1.tgz#553202b5424c53bed37135b318858eacff85dd52" + integrity sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g== + dependencies: + path-data-parser "0.1.0" + points-on-curve "0.2.0" + postcss-nested@^6.0.1: version "6.2.0" resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131" @@ -2656,6 +3664,11 @@ 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== +quansync@^0.2.11: + version "0.2.11" + resolved "https://registry.yarnpkg.com/quansync/-/quansync-0.2.11.tgz#f9c3adda2e1272e4f8cf3f1457b04cbdb4ee692a" + integrity sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA== + radix3@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.2.tgz#fd27d2af3896c6bf4bcdfab6427c69c2afc69ec0" @@ -2898,6 +3911,18 @@ retext@^9.0.0: retext-stringify "^4.0.0" unified "^11.0.0" +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +robust-predicates@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" + integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== + rollup@^4.34.9: version "4.53.2" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.53.2.tgz#98e73ee51e119cb9d88b07d026c959522416420a" @@ -2929,6 +3954,26 @@ rollup@^4.34.9: "@rollup/rollup-win32-x64-msvc" "4.53.2" fsevents "~2.3.2" +roughjs@^4.6.6: + version "4.6.6" + resolved "https://registry.yarnpkg.com/roughjs/-/roughjs-4.6.6.tgz#1059f49a5e0c80dee541a005b20cc322b222158b" + integrity sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ== + dependencies: + hachure-fill "^0.5.2" + path-data-parser "^0.1.0" + points-on-curve "^0.2.0" + points-on-path "^0.2.1" + +rw@1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== + +"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.1: version "1.4.3" resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.3.tgz#fcebae3b756cdc8428321805f4b70f16ec0ab5db" @@ -3022,6 +4067,30 @@ 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== +starlight-contributor-list@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/starlight-contributor-list/-/starlight-contributor-list-0.3.1.tgz#7027f2a2897ea9222fd619925cf644aa12935124" + integrity sha512-8F3BcnqeCgvI/OcagJCBsp71/XU9/zDiuSmsgAkWrRTxql0H2bG9Z9VXvmwzB/569QVlAsOwK7StAxDxqG6Myw== + dependencies: + "@11ty/eleventy-fetch" "^4.0.1" + +starlight-links-validator@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/starlight-links-validator/-/starlight-links-validator-0.19.1.tgz#7c3c2f25e988104627c563ffbd27e523735200f1" + integrity sha512-Ermpe7zJG5uRJUqIWflX4VNLozOBX2/N4XvHvyaPQcHsfdN7y81qEd3n56PYdVb3Tj4/6ZFFSfAtiCe78XtBVw== + dependencies: + "@types/picomatch" "^3.0.1" + github-slugger "^2.0.0" + hast-util-from-html "^2.0.3" + hast-util-has-property "^3.0.0" + is-absolute-url "^4.0.1" + kleur "^4.1.5" + mdast-util-mdx-jsx "^3.1.3" + mdast-util-to-string "^4.0.0" + picomatch "^4.0.2" + terminal-link "^5.0.0" + unist-util-visit "^5.0.0" + stream-replace-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/stream-replace-string/-/stream-replace-string-2.0.0.tgz#e49fd584bd1c633613e010bc73b9db49cb5024ad" @@ -3081,6 +4150,32 @@ style-to-object@1.0.12: dependencies: inline-style-parser "0.2.6" +stylis@^4.3.6: + version "4.3.6" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.6.tgz#7c7b97191cb4f195f03ecab7d52f7902ed378320" + integrity sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ== + +supports-color@^10.0.0: + version "10.2.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-10.2.2.tgz#466c2978cc5cd0052d542a0b576461c2b802ebb4" + integrity sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g== + +supports-hyperlinks@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-4.3.0.tgz#bf2081f57031225d2afb0800d89fa46d5ea74419" + integrity sha512-i6sWEzuwadSlcr2mOnb0ktlIl+K5FVxsPXmoPfknDd2gyw4ZBIAZ5coc0NQzYqDdEYXMHy8NaY9rWwa1Q1myiQ== + dependencies: + has-flag "^5.0.1" + supports-color "^10.0.0" + +terminal-link@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-5.0.0.tgz#f0447c8940418ab49b9b9bbc47a4ad2fa8ba81e7" + integrity sha512-qFAy10MTMwjzjU8U16YS4YoZD+NQLHzLssFMNqgravjbvIPNiqkGFR4yjhJfmY9R5OFU7+yHxc6y+uGHkKwLRA== + dependencies: + ansi-escapes "^7.0.0" + supports-hyperlinks "^4.1.0" + tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" @@ -3099,6 +4194,11 @@ tinyglobby@^0.2.13, tinyglobby@^0.2.14: fdir "^6.5.0" picomatch "^4.0.3" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + trim-lines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" @@ -3109,6 +4209,11 @@ trough@^2.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== +ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + tsconfck@^3.1.6: version "3.1.6" resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.6.tgz#da1f0b10d82237ac23422374b3fce1edb23c3ead" @@ -3277,6 +4382,11 @@ util-deprecate@^1.0.2: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +uuid@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== + vfile-location@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3" @@ -3320,11 +4430,59 @@ vitefu@^1.1.1: resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-1.1.1.tgz#c39b7e4c91bf2f6c590fb96e0758f394dff5795b" integrity sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ== +vscode-jsonrpc@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz#f43dfa35fb51e763d17cd94dcca0c9458f35abf9" + integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== + +vscode-languageserver-protocol@3.17.5: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz#864a8b8f390835572f4e13bd9f8313d0e3ac4bea" + integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== + dependencies: + vscode-jsonrpc "8.2.0" + vscode-languageserver-types "3.17.5" + +vscode-languageserver-textdocument@~1.0.11: + version "1.0.12" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631" + integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA== + +vscode-languageserver-types@3.17.5: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a" + integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== + +vscode-languageserver@~9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz#500aef82097eb94df90d008678b0b6b5f474015b" + integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g== + dependencies: + vscode-languageserver-protocol "3.17.5" + +vscode-uri@~3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" + integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== + web-namespaces@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-pm-runs@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.1.0.tgz#35ccf7b1a0fce87bd8b92a478c9d045785d3bf35" @@ -3346,6 +4504,11 @@ wrap-ansi@^9.0.0: string-width "^7.0.0" strip-ansi "^7.1.0" +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + xxhash-wasm@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz#ffe7f0b98220a4afac171e3fb9b6d1f8771f015e" From 88bd52e1336d09aff67e77f988b2b4b4aebca132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 01:23:11 +0100 Subject: [PATCH 118/131] docs: add page description --- docs/src/content/docs/en/developing/add-provider.mdx | 1 + .../content/docs/en/developing/contributing/code-of-conduct.md | 1 + .../src/content/docs/en/developing/contributing/pull-requests.md | 1 + docs/src/content/docs/en/developing/technical-stack.mdx | 1 + docs/src/content/docs/en/developing/translation.mdx | 1 + docs/src/content/docs/en/features/backorder/connector.mdx | 1 + .../content/docs/en/features/backorder/supported-registrar.mdx | 1 + docs/src/content/docs/en/features/search/domain-search.md | 1 + docs/src/content/docs/en/features/tracking/watchlist.mdx | 1 + docs/src/content/docs/en/install-config/configuration.mdx | 1 + .../content/docs/en/install-config/install/docker-compose.mdx | 1 + .../content/docs/en/install-config/install/manual-install.mdx | 1 + docs/src/content/docs/en/install-config/upgrade.mdx | 1 + docs/src/content/docs/en/legal/license.md | 1 + docs/src/content/docs/en/legal/security.md | 1 + 15 files changed, 15 insertions(+) diff --git a/docs/src/content/docs/en/developing/add-provider.mdx b/docs/src/content/docs/en/developing/add-provider.mdx index 55b2180..4b3a2ae 100644 --- a/docs/src/content/docs/en/developing/add-provider.mdx +++ b/docs/src/content/docs/en/developing/add-provider.mdx @@ -1,5 +1,6 @@ --- title: Add a Provider +description: Step-by-step guide to adding a new Provider, with backend, frontend, and testing instructions to integrate a registrar into the project. --- import {FileTree, Steps, Code, LinkCard} from "@astrojs/starlight/components"; diff --git a/docs/src/content/docs/en/developing/contributing/code-of-conduct.md b/docs/src/content/docs/en/developing/contributing/code-of-conduct.md index f221f61..e66d86f 100644 --- a/docs/src/content/docs/en/developing/contributing/code-of-conduct.md +++ b/docs/src/content/docs/en/developing/contributing/code-of-conduct.md @@ -1,5 +1,6 @@ --- title: Code of Conduct +description: Code of conduct outlining community standards and guidelines for respectful collaboration within the project. --- ## Our Pledge diff --git a/docs/src/content/docs/en/developing/contributing/pull-requests.md b/docs/src/content/docs/en/developing/contributing/pull-requests.md index bfd1aa5..6506fc7 100644 --- a/docs/src/content/docs/en/developing/contributing/pull-requests.md +++ b/docs/src/content/docs/en/developing/contributing/pull-requests.md @@ -1,5 +1,6 @@ --- title: Pull Requests +description: Instructions for submitting pull requests. --- When you want to propose a change to the source code, you will need to create a Pull Request on this project's GitHub diff --git a/docs/src/content/docs/en/developing/technical-stack.mdx b/docs/src/content/docs/en/developing/technical-stack.mdx index 72a9676..927c8e0 100644 --- a/docs/src/content/docs/en/developing/technical-stack.mdx +++ b/docs/src/content/docs/en/developing/technical-stack.mdx @@ -1,5 +1,6 @@ --- title: Technical stack +description: Overview of the project's technical stack, including frameworks, languages, and architecture used throughout the system. --- This page lists the main technologies used in the project, with links to their documentation. Specific version diff --git a/docs/src/content/docs/en/developing/translation.mdx b/docs/src/content/docs/en/developing/translation.mdx index aa5ac8b..06ee323 100644 --- a/docs/src/content/docs/en/developing/translation.mdx +++ b/docs/src/content/docs/en/developing/translation.mdx @@ -1,5 +1,6 @@ --- title: Translation +description: This project is available in several languages, the current translation status is available here. --- The project is translated into several languages to allow as many people as possible to easily understand the interface. diff --git a/docs/src/content/docs/en/features/backorder/connector.mdx b/docs/src/content/docs/en/features/backorder/connector.mdx index a139db6..8cce9cb 100644 --- a/docs/src/content/docs/en/features/backorder/connector.mdx +++ b/docs/src/content/docs/en/features/backorder/connector.mdx @@ -1,5 +1,6 @@ --- title: Connector +description: Learn how the Backorder Connector works, its flow, requirements, and how it integrates with registrar APIs for domain backordering. --- import {LinkCard, Steps} from '@astrojs/starlight/components'; diff --git a/docs/src/content/docs/en/features/backorder/supported-registrar.mdx b/docs/src/content/docs/en/features/backorder/supported-registrar.mdx index bb00035..36003b1 100644 --- a/docs/src/content/docs/en/features/backorder/supported-registrar.mdx +++ b/docs/src/content/docs/en/features/backorder/supported-registrar.mdx @@ -1,5 +1,6 @@ --- title: Supported registrar list +description: List of registrars supported for domain backorders, with details on compatibility. --- import {LinkButton} from '@astrojs/starlight/components'; diff --git a/docs/src/content/docs/en/features/search/domain-search.md b/docs/src/content/docs/en/features/search/domain-search.md index f009cc9..77fd0bd 100644 --- a/docs/src/content/docs/en/features/search/domain-search.md +++ b/docs/src/content/docs/en/features/search/domain-search.md @@ -1,5 +1,6 @@ --- title: Domain search +description: Domain search feature overview --- :::tip[Did you know?] diff --git a/docs/src/content/docs/en/features/tracking/watchlist.mdx b/docs/src/content/docs/en/features/tracking/watchlist.mdx index b4b8f20..547f46a 100644 --- a/docs/src/content/docs/en/features/tracking/watchlist.mdx +++ b/docs/src/content/docs/en/features/tracking/watchlist.mdx @@ -1,5 +1,6 @@ --- title: Watchlist +description: Learn how the domain watchlist works, enabling users to monitor domains and receive updates on changes. --- import {Steps} from '@astrojs/starlight/components'; diff --git a/docs/src/content/docs/en/install-config/configuration.mdx b/docs/src/content/docs/en/install-config/configuration.mdx index f5b153d..6867b1a 100644 --- a/docs/src/content/docs/en/install-config/configuration.mdx +++ b/docs/src/content/docs/en/install-config/configuration.mdx @@ -1,5 +1,6 @@ --- title: Configuration +description: Configuration guide explaining environment variables and settings required to run and customize the project. --- import {LinkCard} from '@astrojs/starlight/components'; diff --git a/docs/src/content/docs/en/install-config/install/docker-compose.mdx b/docs/src/content/docs/en/install-config/install/docker-compose.mdx index cb214c2..c9e7911 100644 --- a/docs/src/content/docs/en/install-config/install/docker-compose.mdx +++ b/docs/src/content/docs/en/install-config/install/docker-compose.mdx @@ -1,5 +1,6 @@ --- title: Docker Compose installation +description: Guide to installing the project using Docker Compose, with setup steps, and deployment notes. --- import {LinkCard} from '@astrojs/starlight/components'; diff --git a/docs/src/content/docs/en/install-config/install/manual-install.mdx b/docs/src/content/docs/en/install-config/install/manual-install.mdx index 597d1f1..ab0fd60 100644 --- a/docs/src/content/docs/en/install-config/install/manual-install.mdx +++ b/docs/src/content/docs/en/install-config/install/manual-install.mdx @@ -1,5 +1,6 @@ --- title: Manual installation +description: Manual installation guide with system requirements, dependencies, and step-by-step instructions to install the project from source. --- import {FileTree, LinkCard, Steps} from '@astrojs/starlight/components'; diff --git a/docs/src/content/docs/en/install-config/upgrade.mdx b/docs/src/content/docs/en/install-config/upgrade.mdx index 87c8b96..e379bab 100644 --- a/docs/src/content/docs/en/install-config/upgrade.mdx +++ b/docs/src/content/docs/en/install-config/upgrade.mdx @@ -1,5 +1,6 @@ --- title: Manual Upgrade +description: Upgrade guide explaining how to safely update the project, including migrations, and versioning details. --- import {Steps} from "@astrojs/starlight/components"; diff --git a/docs/src/content/docs/en/legal/license.md b/docs/src/content/docs/en/legal/license.md index 4c68920..bc05ed1 100644 --- a/docs/src/content/docs/en/legal/license.md +++ b/docs/src/content/docs/en/legal/license.md @@ -1,5 +1,6 @@ --- title: License +description: Licensing information detailing usage rights, redistribution terms, and legal conditions for contributing and using the project. --- This entire project is licensed under [*GNU Affero General Public License v3.0 or later*](https://www.gnu.org/licenses/agpl-3.0.txt). diff --git a/docs/src/content/docs/en/legal/security.md b/docs/src/content/docs/en/legal/security.md index c90859c..f0bacd8 100644 --- a/docs/src/content/docs/en/legal/security.md +++ b/docs/src/content/docs/en/legal/security.md @@ -1,5 +1,6 @@ --- title: Security policy +description: Security policy describing vulnerability reporting, and guidelines to keep the project secure. --- ## Reporting a Vulnerability From 88c14e1cff750aacf0b2337a62237bb597d4c4ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 00:41:10 +0000 Subject: [PATCH 119/131] Translated using Weblate (French) Currently translated at 100.0% (302 of 302 strings) --- translations/fr.po | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/translations/fr.po b/translations/fr.po index 806af7a..88e88ab 100644 --- a/translations/fr.po +++ b/translations/fr.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2025-11-02 12:54+0000\n" +"PO-Revision-Date: 2025-11-16 00:42+0000\n" "Last-Translator: Maël Gangloff \n" "Language-Team: French \n" @@ -9,7 +9,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.13.2\n" +"X-Generator: Weblate 5.14.3\n" #: assets/App.tsx:161 msgid "TOS" @@ -1687,16 +1687,12 @@ msgid "It indicates the organization that will pay for the ordered product" msgstr "Il indique l'organisation qui paiera le produit commandé" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 -#, fuzzy -#| msgid "" -#| "Retreive an API key and whitelist this instance's IP address on " -#| "Namecheap's website" msgid "" "Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" msgstr "" -"Récupérez une clé API et ajoutez l'adresse IP de cette instance à la liste " -"blanche sur le site Web de Namecheap" +"Récupérer une clé API et inscrire l'adresse IP de cette instance sur la " +"liste blanche du site web de Namecheap" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:19 #: assets/utils/providers/forms/NamecomConnectorForm.tsx:25 From d9e24bc46a2b9d1ba11e2b3f7c3efb1b280c0963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 00:41:47 +0000 Subject: [PATCH 120/131] Translated using Weblate (German) Currently translated at 100.0% (302 of 302 strings) --- translations/de.po | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/translations/de.po b/translations/de.po index 3ffadc7..fb01d33 100644 --- a/translations/de.po +++ b/translations/de.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2025-11-02 12:54+0000\n" +"PO-Revision-Date: 2025-11-16 00:42+0000\n" "Last-Translator: Maël Gangloff \n" "Language-Team: German \n" @@ -8,7 +8,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.2\n" +"X-Generator: Weblate 5.14.3\n" #: assets/App.tsx:161 msgid "TOS" @@ -1688,16 +1688,12 @@ msgid "It indicates the organization that will pay for the ordered product" msgstr "Es gibt die Organisation an, die für das bestellte Produkt bezahlt" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 -#, fuzzy -#| msgid "" -#| "Retreive an API key and whitelist this instance's IP address on " -#| "Namecheap's website" msgid "" "Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" msgstr "" "Rufen Sie einen API-Schlüssel ab und setzen Sie die IP-Adresse dieser " -"Instanz auf die Whitelist der Website von Namecheap" +"Instanz auf der Namecheap-Website auf die Whitelist" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:19 #: assets/utils/providers/forms/NamecomConnectorForm.tsx:25 From 5bf2c2d9cbfb73c782e6a601e8431631d53dd4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 00:42:09 +0000 Subject: [PATCH 121/131] Translated using Weblate (Swedish) Currently translated at 100.0% (302 of 302 strings) --- translations/sv.po | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/translations/sv.po b/translations/sv.po index 60db79e..906ec7b 100644 --- a/translations/sv.po +++ b/translations/sv.po @@ -1,14 +1,14 @@ msgid "" msgstr "" -"PO-Revision-Date: 2025-11-02 12:54+0000\n" +"PO-Revision-Date: 2025-11-16 00:42+0000\n" "Last-Translator: Maël Gangloff \n" -"Language-Team: Swedish \n" +"Language-Team: Swedish \n" "Language: sv\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.13.2\n" +"X-Generator: Weblate 5.14.3\n" #: assets/App.tsx:161 msgid "TOS" @@ -1642,10 +1642,6 @@ msgid "It indicates the organization that will pay for the ordered product" msgstr "Den anger vilken organisation som betalar för den beställda produkten" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 -#, fuzzy -#| msgid "" -#| "Retreive an API key and whitelist this instance's IP address on " -#| "Namecheap's website" msgid "" "Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" From 7d8436f138fc6b08f521a25d8a98a51c442099ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 12:41:15 +0100 Subject: [PATCH 122/131] docs: update README.md --- INSTALL.md | 121 ----------------------------------------------------- README.md | 77 +++++++--------------------------- 2 files changed, 14 insertions(+), 184 deletions(-) delete mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index 740e8b4..0000000 --- a/INSTALL.md +++ /dev/null @@ -1,121 +0,0 @@ -# Installation and Update - -## Installation - -To deploy a Domain Watchdog instance, please refer to the Symfony documentation -on [How to deploy a Symfony application](https://symfony.com/doc/current/deployment.html). - -### Prerequisites - -- PHP 8.4 or higher -- PostgreSQL 16 or higher - -In order to retrieve information about domain names, Domain Watchdog will query the RDAP server responsible for the TLD. -It is crucial that the Domain Watchdog instance is placed in a clean environment from which these servers can be -queried. -In particular, the DNS servers and root certificates of the system must be trusted. - -### Steps - -Clone the repository: - -```shell -git clone https://github.com/maelgangloff/domain-watchdog.git - ``` - -#### Backend - -1. Install dependencies: - ```shell - composer install - ``` -2. Set up your environment variables: - ```shell - cp .env .env.local - ``` -3. Generate the cryptographic key pair for the JWT signature - ```shell - php bin/console lexik:jwt:generate-keypair - ``` -4. Run database migrations: - ```shell - php bin/console doctrine:migrations:migrate - ``` -5. Start the Symfony server: - ```shell - symfony server:start - ``` -6. Build assets: - ```shell - php bin/console assets:install - ``` -7. Don't forget to set up workers to process the [message queue](https://symfony.com/doc/current/messenger.html) - -#### Frontend - -1. Install dependencies: - ```shell - yarn install - ``` -2. Generate language files: - ```shell - yarn run ttag:po2json - ``` -3. Make the final build: - ```shell - yarn build - ``` -4. Add and modify the following files as you wish: - ~~~ - public/content/home.md - public/content/privacy.md - public/content/tos.md - public/content/faq.md - public/images/icons-512.png - public/images/banner.png - public/favicon.ico - ~~~ - -## Update - -**Any updates are your responsibility. Make a backup of the data if necessary.** - -Fetch updates from the remote repository: - -```shell -git pull origin master - ``` - -### Backend - -1. Install dependencies: - ```shell - composer install - ``` -2. Run database migrations: - ```shell - php bin/console doctrine:migrations:migrate - ``` -3. Clearing the Symfony cache: - ```shell - php bin/console cache:clear - ``` -4. Build assets: - ```shell - php bin/console assets:install - ``` - -### Frontend - -1. Install dependencies: - ```shell - yarn install - ``` -2. Generate language files: - ```shell - yarn run ttag:po2json - ``` -3. Make the final build: - ```shell - yarn build - ``` diff --git a/README.md b/README.md index 576f20c..aa90fa9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@

Your companion in the quest for domain names 🔍
domainwatchdog.eu »


-Domain Watchdog is an app that uses RDAP to collect publicly available info about domains, track their history, and purchase them. +Domain Watchdog is an app that uses RDAP to collect publicly available info about domains, track their history, and +purchase them. For more information please check out [the documentation](https://domainwatchdog.eu) ! ## Why use it? @@ -20,7 +21,7 @@ detailed history of events (ownership changes, renewals, etc.) is not feasible w ## Install > [!TIP] -> For more details on the installation procedure, please refer to the documentation. +> For more details on the installation procedure, please refer to [the documentation](https://domainwatchdog.eu). ### Docker Deployment @@ -42,55 +43,20 @@ docker compose up By default, the container listens on http://localhost:8080, but you can configure this in environment variables. -## Features +## Development and contributions -### Auto-purchase domain +See [the documentation](https://domainwatchdog.eu) for information on setting up a development environment and making +your contributions. +To add a new provider, a [dedicated page](https://domainwatchdog.eu/en/developing/add-provider/) is available. -A connector is a way to order a domain name. It is important to mention that this project does not act as a payment -intermediary. -Indeed, the user's credentials are directly used to enable the purchase via the provider's API. To this end, the user -gives his consent to define the legal framework in which the use of his account with the provider's API will be made. +## Security -The table below lists the supported API connector providers: +Please see [SECURITY.md](./SECURITY.md). -| Provider | Supported | -|:--------------------------------------------------------------------------:|:----------------:| -| [OVH](https://api.ovh.com) | **Yes** | -| [GANDI](https://api.gandi.net/docs/domains/) | **Yes** | -| [NAMECHEAP](https://www.namecheap.com/support/api/methods/domains/create/) | **Yes** | -| [AUTODNS](https://cloud.autodns.com/) | **Yes** | -| [NAME.COM](https://www.name.com/en-en/api-docs/) | **Yes** | -| Custom EPP Server | **EXPERIMENTAL** | +## License -If a domain has expired and a connector is linked to the Watchlist, then Domain Watchdog will try to order it via the -connector provider's API. - -Note: If the same domain name is present on several Watchlists, it is not possible to predict in advance which user will -win the domain name. The choice is left to chance. - -### Monitoring - -![Watchlist Diagram](https://github.com/user-attachments/assets/c3454572-3ac5-4b39-bc5e-6b7cf72fab92) - - -A watchlist is a list of domain names, triggers and possibly an API connector. - -They allow you to follow the life of the listed domain names and send you a notification when a change has been -detected. - -A notification to the user is sent when a new event occurs on one of the domain names in the Watchlist. This can be an -email or a chat via Webhook (Slack, Mattermost, Discord, ...). An iCalendar export of domain events is possible. - -### RDAP search - -The latest version of the WHOIS protocol was standardized in 2004 by RFC 3912.[^1] This protocol allows anyone to -retrieve key information concerning a domain name, an IP address, or an entity registered with a registry. - -ICANN launched a global vote in 2023 to propose replacing the WHOIS protocol with RDAP. As a result, registries and -registrars will no longer be required to support WHOIS from 2025 (*WHOIS Sunset Date*).[^2] - -Domain Watchdog uses the RDAP protocol, which will soon be the new standard for retrieving information concerning domain -names. +This source code of this project is licensed under *GNU Affero General Public License v3.0 or later*. +Contributions are welcome as long as they do not contravene the Code of Conduct. ## Disclaimer @@ -100,20 +66,5 @@ names. caching system, etc. > * Please note that this project is NOT affiliated IN ANY WAY with the API Providers used to order domain names. > * The project installers are responsible for the use of their own instance. -> * Under no circumstances will the owner of this project be held responsible for other cases over which he has no control. - -## Useful documentation - -> [!NOTE] -> - [RFC 7482 : Registration Data Access Protocol (RDAP) Query Format](https://datatracker.ietf.org/doc/html/rfc7482) -> - [RFC 7483 : JSON Responses for the Registration Data Access Protocol (RDAP)](https://datatracker.ietf.org/doc/html/rfc7483) -> - [RFC 7484 : Finding the Authoritative Registration Data (RDAP) Service](https://datatracker.ietf.org/doc/html/rfc7484) - -## Licensing - -This source code of this project is licensed under *GNU Affero General Public License v3.0 or later*. -Contributions are welcome as long as they do not contravene the Code of Conduct. - -[^1]: RFC 3912 : WHOIS Protocol Specification. (2004). IETF Datatracker. https://datatracker.ietf.org/doc/html/rfc3912 -[^2]: 2023 Global Amendments to the Base gTLD Registry Agreement (RA), Specification 13, and 2013 Registrar -Accreditation Agreement (RAA) - ICANN. (2023). https://www.icann.org/resources/pages/global-amendment-2023-en +> * Under no circumstances will the owner of this project be held responsible for other cases over which he has no + control. From ea1e4e43bd609c9af14159a93b184faab65b1250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 12:42:33 +0100 Subject: [PATCH 123/131] docs: update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa90fa9..8d81db8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ detailed history of events (ownership changes, renewals, etc.) is not feasible w ## Install > [!TIP] -> For more details on the installation procedure, please refer to [the documentation](https://domainwatchdog.eu). +> For more details on the installation procedure, please refer to [the documentation](https://domainwatchdog.eu/en/self-hosting/docker-install/). ### Docker Deployment From 96bbe8a0ed6080e591a94074555bc1662b7de41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 13:44:56 +0100 Subject: [PATCH 124/131] docs: update README.md --- README.md | 2 +- docs/astro.config.mjs | 17 ++++++++++++++--- docs/package.json | 1 + docs/yarn.lock | 12 ++++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8d81db8..c0c1f2b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
Domain Watchdog is an app that uses RDAP to collect publicly available info about domains, track their history, and -purchase them. +purchase them. For more information please check out [the documentation](https://domainwatchdog.eu) ! ## Why use it? diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 7bb8055..5a967d7 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -3,6 +3,7 @@ import {defineConfig} from 'astro/config' import starlight from '@astrojs/starlight' import starlightLinksValidator from 'starlight-links-validator' import mermaid from "astro-mermaid" +import starlightCoolerCredit from "starlight-cooler-credit" const BASE_URL = 'https://domainwatchdog.eu' @@ -112,9 +113,19 @@ _paq.push(['enableHeartBeatTimer']); })();` } ], - plugins: [starlightLinksValidator({ - errorOnLocalLinks: false - })] + plugins: [ + starlightLinksValidator({ + errorOnLocalLinks: false + }), + starlightCoolerCredit({ + credit: { + title: '', + href: 'https://maelgangloff.fr', + description: 'Maintained with ♡ by Maël Gangloff & contributors' + }, + showImage: false + }) + ] }), mermaid() ] diff --git a/docs/package.json b/docs/package.json index e8c27e7..246445d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -22,6 +22,7 @@ "mermaid": "^11.12.1", "sharp": "^0.34.2", "starlight-contributor-list": "^0.3.1", + "starlight-cooler-credit": "^0.4.1", "starlight-links-validator": "^0.19.1" } } diff --git a/docs/yarn.lock b/docs/yarn.lock index 3a3f52d..1e305a5 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1392,6 +1392,11 @@ chalk@^5.3.0: resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== +change-case@^5.4.4: + version "5.4.4" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-5.4.4.tgz#0d52b507d8fb8f204343432381d1a6d7bff97a02" + integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w== + 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" @@ -4074,6 +4079,13 @@ starlight-contributor-list@^0.3.1: dependencies: "@11ty/eleventy-fetch" "^4.0.1" +starlight-cooler-credit@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/starlight-cooler-credit/-/starlight-cooler-credit-0.4.1.tgz#54551a35177143ef13525823aa279bc8d972ee23" + integrity sha512-XXfheeUWSBidS6aJMB1aksn3Zl+kBpMjmuZDFoiHzeCqzjGeTfgYz2AGo/eRNIXOkJlmk4wpUoD29xCtnrmn1A== + dependencies: + change-case "^5.4.4" + starlight-links-validator@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/starlight-links-validator/-/starlight-links-validator-0.19.1.tgz#7c3c2f25e988104627c563ffbd27e523735200f1" From 0de237e33549a3c9d7a5f3f3816bfcc90b8bd583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 13:51:16 +0000 Subject: [PATCH 125/131] Added translation using Weblate (Spanish) --- translations/es.po | 1533 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1533 insertions(+) create mode 100644 translations/es.po diff --git a/translations/es.po b/translations/es.po new file mode 100644 index 0000000..a26f1f4 --- /dev/null +++ b/translations/es.po @@ -0,0 +1,1533 @@ +msgid "" +msgstr "" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: es\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: assets/App.tsx:161 +msgid "TOS" +msgstr "" + +#: assets/App.tsx:162 +msgid "Privacy Policy" +msgstr "" + +#: assets/App.tsx:163 +msgid "FAQ" +msgstr "" + +#: assets/App.tsx:169 +msgid "Documentation" +msgstr "" + +#: assets/App.tsx:177 +msgid "Source code" +msgstr "" + +#: assets/App.tsx:185 +msgid "Submit an issue" +msgstr "" + +#: assets/App.tsx:190 +#, javascript-format +msgid "" +"${ ProjectLink } is an open source project distributed under the ${ " +"LicenseLink } license." +msgstr "" + +#: assets/components/LoginForm.tsx:53 +#: assets/components/RegisterForm.tsx:37 +msgid "Email address" +msgstr "" + +#: assets/components/LoginForm.tsx:55 +#: assets/components/LoginForm.tsx:63 +#: assets/components/RegisterForm.tsx:39 +#: assets/components/RegisterForm.tsx:47 +#: assets/components/search/DomainSearchBar.tsx:28 +#: assets/components/tracking/watchlist/WatchlistForm.tsx:155 +#: assets/components/tracking/watchlist/WatchlistForm.tsx:284 +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:21 +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:32 +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:47 +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:70 +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:11 +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:24 +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:34 +#: assets/utils/providers/forms/EppConnectorForm.tsx:80 +#: assets/utils/providers/forms/EppConnectorForm.tsx:92 +#: assets/utils/providers/forms/EppConnectorForm.tsx:104 +#: assets/utils/providers/forms/EppConnectorForm.tsx:111 +#: assets/utils/providers/forms/EppConnectorForm.tsx:127 +#: assets/utils/providers/forms/EppConnectorForm.tsx:136 +#: assets/utils/providers/forms/EppConnectorForm.tsx:209 +#: assets/utils/providers/forms/EppConnectorForm.tsx:227 +#: assets/utils/providers/forms/EppConnectorForm.tsx:239 +#: assets/utils/providers/forms/GandiConnectorForm.tsx:15 +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:37 +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:51 +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:59 +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:67 +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:74 +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:82 +msgid "Required" +msgstr "" + +#: assets/components/LoginForm.tsx:61 +#: assets/components/RegisterForm.tsx:45 +#: assets/utils/providers/forms/EppConnectorForm.tsx:138 +msgid "Password" +msgstr "" + +#: assets/components/LoginForm.tsx:70 +msgid "Submit" +msgstr "" + +#: assets/components/LoginForm.tsx:74 +msgid "Log in with SSO" +msgstr "" + +#: assets/components/RegisterForm.tsx:54 +#: assets/pages/LoginPage.tsx:60 +msgid "Register" +msgstr "" + +#: assets/components/search/DomainLifecycleSteps.tsx:20 +#: assets/utils/functions/rdapTranslation.ts:41 +msgid "Registration" +msgstr "" + +#: assets/components/search/DomainLifecycleSteps.tsx:24 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:137 +msgid "Active" +msgstr "" + +#: assets/components/search/DomainLifecycleSteps.tsx:29 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:115 +msgid "Auto-Renew Grace Period" +msgstr "" + +#: assets/components/search/DomainLifecycleSteps.tsx:35 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:123 +msgid "Redemption Grace Period" +msgstr "" + +#: assets/components/search/DomainLifecycleSteps.tsx:40 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:131 +msgid "Pending Delete" +msgstr "" + +#: assets/components/search/DomainResult.tsx:57 +msgid "" +"Registry-level protection, ensuring the highest level of security by " +"preventing unauthorized, unwanted, or accidental changes to the domain name " +"at the registry level" +msgstr "" + +#: assets/components/search/DomainResult.tsx:64 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:93 +msgid "Registry Lock" +msgstr "" + +#: assets/components/search/DomainResult.tsx:68 +msgid "" +"Registrar-level protection, safeguarding the domain from unauthorized, " +"unwanted, or accidental changes through registrar controls" +msgstr "" + +#: assets/components/search/DomainResult.tsx:75 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:99 +msgid "Registrar Lock" +msgstr "" + +#: assets/components/search/DomainResult.tsx:79 +msgid "" +"DNSSEC secures DNS by adding cryptographic signatures to DNS records, " +"ensuring authenticity and integrity of responses" +msgstr "" + +#: assets/components/search/DomainResult.tsx:84 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:105 +msgid "DNSSEC" +msgstr "" + +#: assets/components/search/DomainResult.tsx:90 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:219 +msgid "EPP Status Codes" +msgstr "" + +#: assets/components/search/DomainResult.tsx:98 +msgid "Timeline" +msgstr "" + +#: assets/components/search/DomainResult.tsx:105 +msgid "Entities" +msgstr "" + +#: assets/components/search/DomainSearchBar.tsx:31 +#: assets/components/tracking/watchlist/WatchlistForm.tsx:158 +msgid "This domain name does not appear to be valid" +msgstr "" + +#: assets/components/Sider.tsx:31 +msgid "Home" +msgstr "" + +#: assets/components/Sider.tsx:37 +msgid "Search" +msgstr "" + +#: assets/components/Sider.tsx:43 +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:179 +msgid "Domain" +msgstr "" + +#: assets/components/Sider.tsx:44 +msgid "Domain Finder" +msgstr "" + +#: assets/components/Sider.tsx:63 +#: assets/components/Sider.tsx:64 +msgid "Infrastructure" +msgstr "" + +#: assets/components/Sider.tsx:70 +#: assets/pages/StatisticsPage.tsx:112 +#: assets/pages/infrastructure/TldPage.tsx:81 +msgid "TLD" +msgstr "" + +#: assets/components/Sider.tsx:71 +msgid "TLD list" +msgstr "" + +#: assets/components/Sider.tsx:78 +#: assets/components/Sider.tsx:79 +msgid "ICANN list" +msgstr "" + +#: assets/components/Sider.tsx:87 +msgid "Tracking" +msgstr "" + +#: assets/components/Sider.tsx:93 +msgid "My Watchlists" +msgstr "" + +#: assets/components/Sider.tsx:100 +msgid "Tracking table" +msgstr "" + +#: assets/components/Sider.tsx:107 +msgid "My Connectors" +msgstr "" + +#. +#. { +#. key: 'tools', +#. label: t`Tools`, +#. icon: , +#. children: [ +#. { +#. key: '/tools/idn', +#. icon: , +#. label: t`IDN Conversion`, +#. onClick: () => navigate('/') +#. } +#. ] +#. }, +#. +#: assets/components/Sider.tsx:131 +msgid "Statistics" +msgstr "" + +#: assets/components/Sider.tsx:141 +#: assets/pages/UserPage.tsx:17 +msgid "My Account" +msgstr "" + +#: assets/components/Sider.tsx:146 +msgid "Log out" +msgstr "" + +#: assets/components/Sider.tsx:154 +#: assets/pages/LoginPage.tsx:46 +#: assets/pages/LoginPage.tsx:60 +msgid "Log in" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:36 +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:51 +#: assets/utils/functions/rdapTranslation.ts:12 +msgid "Registrar" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:40 +#: assets/utils/providers/forms/EppConnectorForm.tsx:120 +msgid "Authentication" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:45 +msgid "Consent" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:53 +msgid "Choose a registrar" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:86 +msgid "Previous" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:91 +msgid "Next" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:96 +#: assets/components/tracking/watchlist/WatchlistForm.tsx:331 +msgid "Create" +msgstr "" + +#: assets/components/tracking/connector/ConnectorForm.tsx:103 +msgid "" +"This website is neither affiliated with nor sponsored by the registrars " +"mentioned.\n" +"The names and logos of these companies are used for informational purposes " +"only and remain registered trademarks of their respective owners.\n" +"The use of their services via this website is subject to the terms and " +"conditions set by each registrar and is the sole responsibility of the user." +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:19 +msgid "" +"An error occurred while deleting the Connector. Make sure it is not used in " +"any Watchlist" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:35 +#, javascript-format +msgid "Connector ${ connectorName }" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:40 +msgid "Delete the Connector" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:41 +msgid "Are you sure to delete this Connector?" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:43 +#: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:16 +#: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:21 +msgid "Yes" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:44 +#: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:17 +#: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:22 +msgid "No" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:49 +#, javascript-format +msgid "Creation date: ${ createdAt }" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:50 +#, javascript-format +msgid "Used in: ${ watchlistCount } Watchlist" +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:53 +msgid "" +"You can stop using a connector at any time. To delete a connector, you must " +"remove it from each linked Watchlist.\n" +"The creation date corresponds to the date on which you consented to the " +"creation of the connector and on which you declared in particular that you " +"fulfilled the conditions of use of the supplier's API, waived the right of " +"withdrawal and were of the minimum age to consent to these conditions." +msgstr "" + +#: assets/components/tracking/connector/ConnectorsList.tsx:57 +msgid "The Provider’s conditions are accessible by following this hyperlink." +msgstr "" + +#: assets/components/tracking/watchlist/CalendarWatchlistButton.tsx:15 +msgid "QR Code for iCalendar export" +msgstr "" + +#: assets/components/tracking/watchlist/CalendarWatchlistButton.tsx:20 +msgid "Export events to iCalendar format" +msgstr "" + +#: assets/components/tracking/watchlist/CreateWatchlistButton.tsx:33 +#: assets/components/tracking/watchlist/CreateWatchlistButton.tsx:35 +msgid "Create a Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:13 +#: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:21 +msgid "Delete the Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:14 +msgid "Are you sure to delete this Watchlist?" +msgstr "" + +#: assets/components/tracking/watchlist/diagram/ViewDiagramWatchlistButton.tsx:39 +msgid "View the Watchlist Entity Diagram" +msgstr "" + +#: assets/components/tracking/watchlist/diagram/ViewDiagramWatchlistButton.tsx:45 +msgid "Watchlist Entity Diagram" +msgstr "" + +#: assets/components/tracking/watchlist/diagram/watchlistToEdges.tsx:43 +msgid "Registry" +msgstr "" + +#: assets/components/tracking/watchlist/diagram/watchlistToNodes.tsx:41 +#, javascript-format +msgid ".${ tld.tld } Registry" +msgstr "" + +#: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:18 +#: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:26 +msgid "Disable the Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:19 +msgid "Are you sure to disable this Watchlist?" +msgstr "" + +#: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:29 +msgid "Enable the Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:30 +msgid "" +"At least one domain name is in redemption period and will potentially be " +"deleted soon" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:39 +msgid "" +"At least one domain name is pending deletion and will soon become available " +"for registration again" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:147 +msgid "Estimated number of days until WHOIS removal" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:150 +#, javascript-format +msgid "J ${ expiresInDays }" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:156 +msgid "Deletion is imminent" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:185 +msgid "Status" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:191 +msgid "Options" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:197 +msgid "Expiration date" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:211 +msgid "Updated at" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:240 +msgid "No tracked domain names were found, please create your first Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:243 +msgid "Create now" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 +msgid "" +"Please note that this table does not include domain names marked as expired " +"or those with an unknown expiration date" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:254 +msgid "At least one domain name you are tracking requires special attention" +msgstr "" + +#: assets/components/tracking/watchlist/TrackedDomainTable.tsx:260 +msgid "The domain names below are subject to special monitoring" +msgstr "" + +#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:31 +msgid "Edit the Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:46 +msgid "Update a Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistCard.tsx:54 +msgid "This Watchlist is not linked to a Connector." +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistCard.tsx:59 +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:86 +msgid "Watchlist" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistCard.tsx:97 +#: assets/components/tracking/watchlist/WatchlistForm.tsx:191 +msgid "Tracked events" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistCard.tsx:119 +#: assets/components/tracking/watchlist/WatchlistForm.tsx:217 +msgid "Tracked EPP status" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:111 +msgid "Name" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:123 +msgid "Watchlist Name" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:124 +msgid "Naming the Watchlist makes it easier to find in the list below." +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:135 +msgid "At least one domain name" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:146 +msgid "Domain names" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:164 +msgid "Domain name" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:183 +msgid "Add a Domain name" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:193 +msgid "At least one event" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:219 +msgid "At least one EPP status" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:243 +#: assets/components/tracking/watchlist/WatchlistForm.tsx:258 +msgid "Connector" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:253 +msgid "" +"Please make sure the connector information is valid to purchase a domain " +"that may be available soon." +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:275 +msgid "DSN" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:287 +msgid "This DSN does not appear to be valid" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:311 +msgid "Check out this link to the Symfony documentation to help you build the DSN" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:321 +msgid "Add a Webhook" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:331 +msgid "Update" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistForm.tsx:334 +msgid "Reset" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:29 +#, javascript-format +msgid "${ rest.length } more" +msgstr "" + +#: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:82 +msgid "Select one of your available Watchlists" +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:45 +msgid "ID" +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:80 +msgid "" +"An accredited number means that ICANN's contract with the registrar is " +"ongoing." +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:85 +msgid "A reserved number can be used by TLD registries for specific operations." +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:90 +msgid "" +"A terminated number means that ICANN's contract with the registrar has been " +"terminated." +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 +msgid "This page lists ICANN-accredited registrars." +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:102 +msgid "" +"The list is officially published and maintained by the Internet Assigned " +"Numbers Authority (IANA), the organization responsible for managing the " +"Internet's unique identifiers (including numbers, IP addresses, and domain " +"name extensions)." +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:114 +#: assets/utils/functions/rdapTranslation.ts:125 +msgid "Accredited" +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:119 +#: assets/utils/functions/rdapTranslation.ts:126 +msgid "Reserved" +msgstr "" + +#: assets/pages/infrastructure/IcannRegistrarPage.tsx:124 +#: assets/utils/functions/rdapTranslation.ts:124 +msgid "Terminated" +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:88 +msgid "Flag" +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:91 +msgid "Country" +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:98 +msgid "Registry Operator" +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:127 +msgid "" +"Top-level domains sponsored by specific organizations that set rules for " +"registration and use, often related to particular interest groups or " +"industries." +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:132 +msgid "" +"Generic top-level domains open to everyone, not restricted by specific " +"criteria, representing various themes or industries." +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:137 +msgid "" +"Generic top-level domains associated with specific brands, allowing " +"companies to use their own brand names as domains." +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:142 +msgid "" +"Top-level domains based on country codes, identifying websites according to " +"their country of origin." +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:151 +msgid "This page presents all active TLDs in the root zone database." +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:154 +msgid "" +"IANA provides the list of currently active TLDs, regardless of their type, " +"and ICANN provides the list of gTLDs.\n" +"In most cases, the two-letter ccTLD assigned to a country is made in " +"accordance with the ISO 3166-1 standard.\n" +"This data is updated every month. Three HTTP requests are needed for the " +"complete update of TLDs in Domain Watchdog (two requests to IANA and one to " +"ICANN).\n" +"At the same time, the list of root RDAP servers is updated." +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:169 +msgid "Generic Top-Level-Domains" +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:174 +msgid "Country-Code Top-Level-Domains" +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:179 +msgid "Brand Generic Top-Level-Domains" +msgstr "" + +#: assets/pages/infrastructure/TldPage.tsx:184 +msgid "Sponsored Top-Level-Domains" +msgstr "" + +#: assets/pages/LoginPage.tsx:46 +msgid "Create an account" +msgstr "" + +#: assets/pages/NotFoundPage.tsx:10 +msgid "Sorry, the page you visited does not exist." +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:36 +msgid "Found !" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:53 +#, javascript-format +msgid "${ ldhName } added to ${ watchlist.name }" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:70 +msgid "" +"Although the domain exists in my database, it has been deleted from the " +"WHOIS by its registrar." +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:82 +msgid "Add to Watchlist" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:92 +#, javascript-format +msgid "Add ${ domainLdhName } to a Watchlist" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:95 +msgid "Cancel" +msgstr "" + +#: assets/pages/search/DomainSearchPage.tsx:96 +msgid "Add" +msgstr "" + +#: assets/pages/StatisticsPage.tsx:33 +msgid "RDAP queries" +msgstr "" + +#: assets/pages/StatisticsPage.tsx:42 +msgid "Alerts sent" +msgstr "" + +#: assets/pages/StatisticsPage.tsx:56 +msgid "Domain names in database" +msgstr "" + +#: assets/pages/StatisticsPage.tsx:67 +msgid "Tracked domain names" +msgstr "" + +#: assets/pages/StatisticsPage.tsx:81 +msgid "Purchased domain names" +msgstr "" + +#: assets/pages/StatisticsPage.tsx:91 +msgid "" +"This value is based on the status code of the HTTP response from the " +"providers following the domain order." +msgstr "" + +#: assets/pages/StatisticsPage.tsx:95 +msgid "Success rate" +msgstr "" + +#: assets/pages/TextPage.tsx:29 +#, javascript-format +msgid "📝 Please create the /public/content/${ resource } file." +msgstr "" + +#: assets/pages/tracking/ConnectorPage.tsx:22 +msgid "Connector created !" +msgstr "" + +#: assets/pages/tracking/ConnectorPage.tsx:41 +msgid "Create a Connector" +msgstr "" + +#: assets/pages/tracking/WatchlistPage.tsx:42 +msgid "Watchlist created !" +msgstr "" + +#: assets/pages/tracking/WatchlistPage.tsx:53 +msgid "Watchlist updated !" +msgstr "" + +#: assets/pages/UserPage.tsx:19 +#: assets/utils/providers/forms/EppConnectorForm.tsx:129 +#: assets/utils/providers/forms/NamecheapConnectorForm.tsx:10 +#: assets/utils/providers/forms/NamecomConnectorForm.tsx:16 +msgid "Username" +msgstr "" + +#: assets/pages/UserPage.tsx:22 +msgid "Roles" +msgstr "" + +#: assets/utils/functions/DomainToTag.tsx:14 +msgid "The domain name was updated less than a week ago." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:7 +#: assets/utils/providers/forms/EppConnectorForm.tsx:241 +msgid "Registrant" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:8 +#: assets/utils/providers/forms/EppConnectorForm.tsx:251 +msgid "Technical" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:9 +#: assets/utils/providers/forms/EppConnectorForm.tsx:246 +msgid "Administrative" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:10 +msgid "Abuse" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:11 +#: assets/utils/providers/forms/EppConnectorForm.tsx:256 +msgid "Billing" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:13 +#: assets/utils/providers/forms/EppConnectorForm.tsx:266 +msgid "Reseller" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:14 +msgid "Sponsor" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:15 +msgid "Proxy" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:16 +msgid "Notifications" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:17 +msgid "Noc" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:24 +msgid "" +"The entity object instance is the registrant of the registration. In some " +"registries, this is known as a maintainer." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:25 +msgid "The entity object instance is a technical contact for the registration." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:26 +msgid "" +"The entity object instance is an administrative contact for the " +"registration." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:27 +msgid "" +"The entity object instance handles network abuse issues on behalf of the " +"registrant of the registration." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:28 +msgid "" +"The entity object instance handles payment and billing issues on behalf of " +"the registrant of the registration." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:29 +msgid "" +"The entity object instance represents the authority responsible for the " +"registration in the registry." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:30 +msgid "" +"The entity object instance represents a third party through which the " +"registration was conducted (i.e., not the registry or registrar)." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:31 +msgid "" +"The entity object instance represents a domain policy sponsor, such as an " +"ICANN-approved sponsor." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:32 +msgid "" +"The entity object instance represents a proxy for another entity object, " +"such as a registrant." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:33 +msgid "" +"An entity object instance designated to receive notifications about " +"association object instances." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:34 +msgid "" +"The entity object instance handles communications related to a network " +"operations center (NOC)." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:42 +msgid "Reregistration" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:43 +msgid "Changed" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:44 +msgid "Expiration" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:45 +msgid "Deletion" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:46 +msgid "Reinstantiation" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:47 +msgid "Transfer" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:48 +msgid "Locked" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:49 +msgid "Unlocked" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:50 +msgid "Registrar expiration" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:51 +msgid "ENUM validation expiration" +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:58 +msgid "The object instance was initially registered." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:59 +msgid "The object instance was registered subsequently to initial registration." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:60 +msgid "" +"An action noting when the information in the object instance was last " +"changed." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:61 +msgid "" +"The object instance has been removed or will be removed at a predetermined " +"date and time from the registry." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:62 +msgid "" +"The object instance was removed from the registry at a point in time that " +"was not predetermined." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:63 +msgid "" +"The object instance was reregistered after having been removed from the " +"registry." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:64 +msgid "The object instance was transferred from one registrar to another." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:65 +msgid "The object instance was locked." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:66 +msgid "The object instance was unlocked." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:67 +msgid "An action noting the expiration date of the object in the registrar system." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:68 +msgid "" +"Association of phone number represented by this ENUM domain to registrant " +"has expired or will expire at a predetermined date and time." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:72 +#: assets/utils/functions/rdapTranslation.ts:81 +msgid "" +"This is the standard status for a domain, meaning it has no pending " +"operations or prohibitions." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:73 +msgid "" +"This status code indicates that delegation information (name servers) has " +"not been associated with your domain. Your domain is not activated in the " +"DNS and will not resolve." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:74 +msgid "" +"This status code indicates that a request to create your domain has been " +"received and is being processed." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:75 +msgid "" +"This status code indicates that a request to renew your domain has been " +"received and is being processed." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:76 +msgid "" +"This status code indicates that a request to transfer your domain to a new " +"registrar has been received and is being processed." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:77 +msgid "" +"This status code indicates that a request to update your domain has been " +"received and is being processed." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:78 +msgid "" +"This status code may be mixed with redemptionPeriod or pendingRestore. In " +"such case, depending on the status (i.e. redemptionPeriod or " +"pendingRestore) set in the domain name, the corresponding description " +"presented above applies. If this status is not combined with the " +"redemptionPeriod or pendingRestore status, the pendingDelete status code " +"indicates that your domain has been in redemptionPeriod status for 30 days " +"and you have not restored it within that 30-day period. Your domain will " +"remain in this status for several days, after which time your domain will " +"be purged and dropped from the registry database. Once deletion occurs, the " +"domain is available for re-registration in accordance with the registry's " +"policies." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:79 +msgid "" +"This grace period is provided after the initial registration of a domain " +"name. If the registrar deletes the domain name during this period, the " +"registry may provide credit to the registrar for the cost of the " +"registration." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:80 +msgid "" +"This grace period is provided after a domain name registration period " +"expires and is extended (renewed) automatically by the registry. If the " +"registrar deletes the domain name during this period, the registry provides " +"a credit to the registrar for the cost of the renewal." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:82 +msgid "" +"This status code tells your domain's registry to reject requests to delete " +"the domain." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:83 +msgid "" +"This status code tells your domain's registry to not activate your domain " +"in the DNS and as a consequence, it will not resolve. It is an uncommon " +"status that is usually enacted during legal disputes, non-payment, or when " +"your domain is subject to deletion." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:84 +msgid "" +"This status code tells your domain's registry to reject requests to renew " +"your domain. It is an uncommon status that is usually enacted during legal " +"disputes or when your domain is subject to deletion." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:85 +msgid "" +"This status code tells your domain's registry to reject requests to " +"transfer the domain from your current registrar to another." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:86 +msgid "" +"This status code tells your domain's registry to reject requests to update " +"the domain." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:87 +msgid "" +"This status code indicates that your registrar has asked the registry to " +"restore your domain that was in redemptionPeriod status. Your registry will " +"hold the domain in this status while waiting for your registrar to provide " +"required restoration documentation. If your registrar fails to provide " +"documentation to the registry operator within a set time period to confirm " +"the restoration request, the domain will revert to redemptionPeriod status." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:88 +msgid "" +"This status code indicates that your registrar has asked the registry to " +"delete your domain. Your domain will be held in this status for 30 days. " +"After five calendar days following the end of the redemptionPeriod, your " +"domain is purged from the registry database and becomes available for " +"registration." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:89 +msgid "" +"This grace period is provided after a domain name registration period is " +"explicitly extended (renewed) by the registrar. If the registrar deletes " +"the domain name during this period, the registry provides a credit to the " +"registrar for the cost of the renewal." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:90 +msgid "" +"This status code prevents your domain from being deleted. It is an uncommon " +"status that is usually enacted during legal disputes, at your request, or " +"when a redemptionPeriod status is in place." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:91 +msgid "" +"This status code indicates your domain's Registry Operator will not allow " +"your registrar to renew your domain. It is an uncommon status that is " +"usually enacted during legal disputes or when your domain is subject to " +"deletion." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:92 +msgid "" +"This status code prevents your domain from being transferred from your " +"current registrar to another. It is an uncommon status that is usually " +"enacted during legal or other disputes, at your request, or when a " +"redemptionPeriod status is in place." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:93 +msgid "" +"This status code locks your domain preventing it from being updated. It is " +"an uncommon status that is usually enacted during legal disputes, at your " +"request, or when a redemptionPeriod status is in place." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:94 +msgid "" +"This status code is set by your domain's Registry Operator. Your domain is " +"not activated in the DNS." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:95 +msgid "" +"This grace period is provided after the successful transfer of a domain " +"name from one registrar to another. If the new registrar deletes the domain " +"name during this period, the registry provides a credit to the registrar " +"for the cost of the transfer." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:104 +msgid "" +"Signifies that the data of the object instance has been found to be " +"accurate." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:105 +msgid "Renewal or reregistration of the object instance is forbidden." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:106 +msgid "Updates to the object instance are forbidden." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:107 +msgid "Transfers of the registration from one registrar to another are forbidden." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:108 +msgid "Deletion of the registration of the object instance is forbidden." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:109 +msgid "The registration of the object instance has been performed by a third party." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:110 +msgid "" +"The information of the object instance is not designated for public " +"consumption." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:111 +msgid "" +"Some of the information of the object instance has not been made available " +"and has been removed." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:112 +msgid "" +"Some of the information of the object instance has been altered for the " +"purposes of not readily revealing the actual information of the object " +"instance." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:113 +msgid "" +"The object instance is associated with other object instances in the " +"registry." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:114 +msgid "" +"Changes to the object instance cannot be made, including the association of " +"other object instances." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:118 +msgid "" +"The object instance has been allocated administratively (i.e., not for use " +"by the recipient in their own right in operational networks)." +msgstr "" + +#: assets/utils/functions/rdapTranslation.ts:119 +msgid "" +"The object instance has been allocated to an IANA special-purpose address " +"registry." +msgstr "" + +#: assets/utils/functions/showErrorAPI.tsx:18 +#, javascript-format +msgid "Please retry after ${ duration } seconds" +msgstr "" + +#: assets/utils/functions/showErrorAPI.tsx:22 +#: assets/utils/functions/showErrorAPI.tsx:25 +msgid "An error occurred" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:10 +#: assets/utils/providers/forms/NamecomConnectorForm.tsx:11 +msgid "" +"This provider does not provide a list of supported TLD. Please double check " +"if the domain you want to register is supported." +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:16 +msgid "AutoDNS Username" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:19 +msgid "" +"Because of some limitations in API of AutoDNS, we suggest to create an " +"dedicated user for API with limited rights" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:26 +msgid "AutoDNS Password" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:30 +msgid "" +"Attention: AutoDNS do not support 2-Factor Authentication on API Users for " +"automated systems" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:38 +msgid "Owner nic-handle" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:42 +msgid "The nic-handle of the domain name owner" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:44 +msgid "You can get it from this page" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:54 +msgid "Context Value" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:58 +msgid "If you not sure, use the default value 4" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:67 +msgid "Owner confirmation" +msgstr "" + +#: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:74 +msgid "Owner confirms his consent of domain order jobs" +msgstr "" + +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:9 +msgid "API Terms of Service" +msgstr "" + +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:16 +msgid "" +"I have read and accepted the conditions of use of the Provider API, " +"accessible from this hyperlink" +msgstr "" + +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:22 +msgid "Legal age" +msgstr "" + +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:27 +msgid "I am of the minimum age required to consent to these conditions" +msgstr "" + +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:32 +msgid "Withdrawal period" +msgstr "" + +#: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:37 +msgid "" +"I waive my right of withdrawal regarding the purchase of domain names via " +"the Provider's API" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:61 +msgid "" +"This connector is experimental and its implementation has not been fully " +"tested. Please submit an issue for any issues related to it." +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:66 +msgid "The EPP connector is a special type of connector. Be careful." +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:71 +msgid "Server configuration" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:72 +msgid "Protocol" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:76 +msgid "Version" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:88 +msgid "Language" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:101 +msgid "Server" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:121 +msgid "Credentials" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:144 +msgid "TLS client certificate" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:162 +msgid "Private key passphrase (optional)" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:169 +msgid "TLS configuration" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:174 +msgid "Verify peer" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:183 +msgid "Verify peer name" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:192 +msgid "Allow self-signed certificates" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:202 +msgid "Domain configuration" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:204 +msgid "Registration period" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:217 +msgid "Year" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:218 +msgid "Month" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:225 +msgid "Auth-Info Code" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:233 +msgid "NIC Handle" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:261 +msgid "Onsite" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:273 +msgid "Protocol configuration" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:274 +msgid "Services" +msgstr "" + +#: assets/utils/providers/forms/EppConnectorForm.tsx:280 +msgid "Extensions" +msgstr "" + +#: assets/utils/providers/forms/GandiConnectorForm.tsx:10 +msgid "Personal Access Token (PAT)" +msgstr "" + +#: assets/utils/providers/forms/GandiConnectorForm.tsx:13 +msgid "" +"Retrieve a Personal Access Token from your customer account on the " +"Provider's website" +msgstr "" + +#: assets/utils/providers/forms/GandiConnectorForm.tsx:20 +msgid "Organization sharing ID" +msgstr "" + +#: assets/utils/providers/forms/GandiConnectorForm.tsx:24 +msgid "It indicates the organization that will pay for the ordered product" +msgstr "" + +#: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 +msgid "" +"Retrieve an API key and whitelist this instance's IP address on Namecheap's " +"website" +msgstr "" + +#: assets/utils/providers/forms/NamecheapConnectorForm.tsx:19 +#: assets/utils/providers/forms/NamecomConnectorForm.tsx:25 +msgid "API key" +msgstr "" + +#: assets/utils/providers/forms/NamecomConnectorForm.tsx:19 +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:42 +msgid "" +"Retrieve a set of tokens from your customer account on the Provider's " +"website" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:15 +msgid "European Region" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:16 +msgid "United States Region" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:17 +msgid "Canada Region" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:22 +msgid "Europe" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:25 +msgid "The domain is free and at the standard price" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:28 +msgid "" +"The domain is free but can be premium. Its price varies from one domain to " +"another" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:35 +msgid "Application key" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:49 +msgid "Application secret" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:57 +msgid "Consumer key" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:65 +msgid "OVH Endpoint" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:72 +msgid "OVH subsidiary" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:80 +msgid "OVH pricing mode" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:85 +msgid "Confirm pricing mode" +msgstr "" + +#: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:86 +msgid "" +"Are you sure about this setting? This may result in additional charges from " +"the API Provider" +msgstr "" From 20b05510dd86e94283fe0e587238aae42a0e7ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 15:14:11 +0000 Subject: [PATCH 126/131] Translated using Weblate (Spanish) Currently translated at 100.0% (302 of 302 strings) --- translations/es.po | 663 ++++++++++++++++++++++++++++++--------------- 1 file changed, 450 insertions(+), 213 deletions(-) diff --git a/translations/es.po b/translations/es.po index a26f1f4..be80102 100644 --- a/translations/es.po +++ b/translations/es.po @@ -1,35 +1,38 @@ msgid "" msgstr "" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2025-11-16 15:14+0000\n" +"Last-Translator: Maël Gangloff \n" +"Language-Team: Spanish \n" "Language: es\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.14.3\n" #: assets/App.tsx:161 msgid "TOS" -msgstr "" +msgstr "Términos del Servicio" #: assets/App.tsx:162 msgid "Privacy Policy" -msgstr "" +msgstr "Política de privacidad" #: assets/App.tsx:163 msgid "FAQ" -msgstr "" +msgstr "Preguntas Frecuentes" #: assets/App.tsx:169 msgid "Documentation" -msgstr "" +msgstr "Documentación" #: assets/App.tsx:177 msgid "Source code" -msgstr "" +msgstr "Código fuente" #: assets/App.tsx:185 msgid "Submit an issue" -msgstr "" +msgstr "Enviar un problema" #: assets/App.tsx:190 #, javascript-format @@ -37,11 +40,13 @@ msgid "" "${ ProjectLink } is an open source project distributed under the ${ " "LicenseLink } license." msgstr "" +"${ ProjectLink } es un proyecto de código abierto distribuido bajo la " +"licencia ${ LicenseLink }." #: assets/components/LoginForm.tsx:53 #: assets/components/RegisterForm.tsx:37 msgid "Email address" -msgstr "" +msgstr "Dirección de correo electrónico" #: assets/components/LoginForm.tsx:55 #: assets/components/LoginForm.tsx:63 @@ -74,51 +79,51 @@ msgstr "" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:74 #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:82 msgid "Required" -msgstr "" +msgstr "Requerido" #: assets/components/LoginForm.tsx:61 #: assets/components/RegisterForm.tsx:45 #: assets/utils/providers/forms/EppConnectorForm.tsx:138 msgid "Password" -msgstr "" +msgstr "Contraseña" #: assets/components/LoginForm.tsx:70 msgid "Submit" -msgstr "" +msgstr "Enviar" #: assets/components/LoginForm.tsx:74 msgid "Log in with SSO" -msgstr "" +msgstr "Iniciar sesión con SSO" #: assets/components/RegisterForm.tsx:54 #: assets/pages/LoginPage.tsx:60 msgid "Register" -msgstr "" +msgstr "Registro" #: assets/components/search/DomainLifecycleSteps.tsx:20 #: assets/utils/functions/rdapTranslation.ts:41 msgid "Registration" -msgstr "" +msgstr "Registro" #: assets/components/search/DomainLifecycleSteps.tsx:24 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:137 msgid "Active" -msgstr "" +msgstr "Activo" #: assets/components/search/DomainLifecycleSteps.tsx:29 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:115 msgid "Auto-Renew Grace Period" -msgstr "" +msgstr "Período de gracia de autorrenovación" #: assets/components/search/DomainLifecycleSteps.tsx:35 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:123 msgid "Redemption Grace Period" -msgstr "" +msgstr "Período de gracia de redención" #: assets/components/search/DomainLifecycleSteps.tsx:40 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:131 msgid "Pending Delete" -msgstr "" +msgstr "Pendiente de eliminación" #: assets/components/search/DomainResult.tsx:57 msgid "" @@ -126,104 +131,112 @@ msgid "" "preventing unauthorized, unwanted, or accidental changes to the domain name " "at the registry level" msgstr "" +"Protección a nivel de registro, que garantiza el máximo nivel de seguridad " +"al impedir cambios no autorizados, no deseados o accidentales en el nombre " +"de dominio a nivel de registro" #: assets/components/search/DomainResult.tsx:64 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:93 msgid "Registry Lock" -msgstr "" +msgstr "Bloqueo de Registro" #: assets/components/search/DomainResult.tsx:68 msgid "" "Registrar-level protection, safeguarding the domain from unauthorized, " "unwanted, or accidental changes through registrar controls" msgstr "" +"Protección a nivel de registrador, que salvaguarda el dominio contra cambios " +"no autorizados, no deseados o accidentales mediante los controles del " +"registrador" #: assets/components/search/DomainResult.tsx:75 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:99 msgid "Registrar Lock" -msgstr "" +msgstr "Bloqueo de Registrador" #: assets/components/search/DomainResult.tsx:79 msgid "" "DNSSEC secures DNS by adding cryptographic signatures to DNS records, " "ensuring authenticity and integrity of responses" msgstr "" +"DNSSEC protege el DNS añadiendo firmas criptográficas a los registros DNS, " +"garantizando la autenticidad e integridad de las respuestas" #: assets/components/search/DomainResult.tsx:84 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:105 msgid "DNSSEC" -msgstr "" +msgstr "DNSSEC" #: assets/components/search/DomainResult.tsx:90 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:219 msgid "EPP Status Codes" -msgstr "" +msgstr "Códigos de estado EPP" #: assets/components/search/DomainResult.tsx:98 msgid "Timeline" -msgstr "" +msgstr "Cronología" #: assets/components/search/DomainResult.tsx:105 msgid "Entities" -msgstr "" +msgstr "Entidades" #: assets/components/search/DomainSearchBar.tsx:31 #: assets/components/tracking/watchlist/WatchlistForm.tsx:158 msgid "This domain name does not appear to be valid" -msgstr "" +msgstr "Este nombre de dominio no parece ser válido" #: assets/components/Sider.tsx:31 msgid "Home" -msgstr "" +msgstr "Inicio" #: assets/components/Sider.tsx:37 msgid "Search" -msgstr "" +msgstr "Buscar" #: assets/components/Sider.tsx:43 #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:179 msgid "Domain" -msgstr "" +msgstr "Dominio" #: assets/components/Sider.tsx:44 msgid "Domain Finder" -msgstr "" +msgstr "Buscador de dominios" #: assets/components/Sider.tsx:63 #: assets/components/Sider.tsx:64 msgid "Infrastructure" -msgstr "" +msgstr "Infraestructura" #: assets/components/Sider.tsx:70 #: assets/pages/StatisticsPage.tsx:112 #: assets/pages/infrastructure/TldPage.tsx:81 msgid "TLD" -msgstr "" +msgstr "TLD" #: assets/components/Sider.tsx:71 msgid "TLD list" -msgstr "" +msgstr "Lista de TLD" #: assets/components/Sider.tsx:78 #: assets/components/Sider.tsx:79 msgid "ICANN list" -msgstr "" +msgstr "Lista ICANN" #: assets/components/Sider.tsx:87 msgid "Tracking" -msgstr "" +msgstr "Seguimiento" #: assets/components/Sider.tsx:93 msgid "My Watchlists" -msgstr "" +msgstr "Mis Watchlists" #: assets/components/Sider.tsx:100 msgid "Tracking table" -msgstr "" +msgstr "Tabla de seguimiento" #: assets/components/Sider.tsx:107 msgid "My Connectors" -msgstr "" +msgstr "Mis Conectores" #. #. { @@ -242,54 +255,54 @@ msgstr "" #. #: assets/components/Sider.tsx:131 msgid "Statistics" -msgstr "" +msgstr "Estadísticas" #: assets/components/Sider.tsx:141 #: assets/pages/UserPage.tsx:17 msgid "My Account" -msgstr "" +msgstr "Mi cuenta" #: assets/components/Sider.tsx:146 msgid "Log out" -msgstr "" +msgstr "Cerrar sesión" #: assets/components/Sider.tsx:154 #: assets/pages/LoginPage.tsx:46 #: assets/pages/LoginPage.tsx:60 msgid "Log in" -msgstr "" +msgstr "Iniciar sesión" #: assets/components/tracking/connector/ConnectorForm.tsx:36 #: assets/pages/infrastructure/IcannRegistrarPage.tsx:51 #: assets/utils/functions/rdapTranslation.ts:12 msgid "Registrar" -msgstr "" +msgstr "Registrador" #: assets/components/tracking/connector/ConnectorForm.tsx:40 #: assets/utils/providers/forms/EppConnectorForm.tsx:120 msgid "Authentication" -msgstr "" +msgstr "Autenticación" #: assets/components/tracking/connector/ConnectorForm.tsx:45 msgid "Consent" -msgstr "" +msgstr "Consentimiento" #: assets/components/tracking/connector/ConnectorForm.tsx:53 msgid "Choose a registrar" -msgstr "" +msgstr "Elija un registrador" #: assets/components/tracking/connector/ConnectorForm.tsx:86 msgid "Previous" -msgstr "" +msgstr "Antes" #: assets/components/tracking/connector/ConnectorForm.tsx:91 msgid "Next" -msgstr "" +msgstr "Después" #: assets/components/tracking/connector/ConnectorForm.tsx:96 #: assets/components/tracking/watchlist/WatchlistForm.tsx:331 msgid "Create" -msgstr "" +msgstr "Crear" #: assets/components/tracking/connector/ConnectorForm.tsx:103 msgid "" @@ -300,47 +313,56 @@ msgid "" "The use of their services via this website is subject to the terms and " "conditions set by each registrar and is the sole responsibility of the user." msgstr "" +"Este sitio web no está afiliado ni patrocinado por los registradores " +"mencionados.\n" +"Los nombres y logotipos de estas empresas se utilizan únicamente con fines " +"informativos y son marcas registradas de sus respectivos propietarios.\n" +"El uso de sus servicios a través de este sitio web está sujeto a los " +"términos y condiciones establecidos por cada registrador y es " +"responsabilidad exclusiva del usuario." #: assets/components/tracking/connector/ConnectorsList.tsx:19 msgid "" "An error occurred while deleting the Connector. Make sure it is not used in " "any Watchlist" msgstr "" +"Se produjo un error al eliminar el Conector. Asegúrese de que no esté en uso " +"en ninguna Watchlist" #: assets/components/tracking/connector/ConnectorsList.tsx:35 #, javascript-format msgid "Connector ${ connectorName }" -msgstr "" +msgstr "Conector ${ connectorName }" #: assets/components/tracking/connector/ConnectorsList.tsx:40 msgid "Delete the Connector" -msgstr "" +msgstr "Eliminar el Conector" #: assets/components/tracking/connector/ConnectorsList.tsx:41 msgid "Are you sure to delete this Connector?" -msgstr "" +msgstr "¿Estás seguro de eliminar este Conector?" #: assets/components/tracking/connector/ConnectorsList.tsx:43 #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:16 #: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:21 msgid "Yes" -msgstr "" +msgstr "Sí" #: assets/components/tracking/connector/ConnectorsList.tsx:44 #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:17 #: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:22 msgid "No" -msgstr "" +msgstr "No" #: assets/components/tracking/connector/ConnectorsList.tsx:49 #, javascript-format msgid "Creation date: ${ createdAt }" -msgstr "" +msgstr "Fecha de creación: ${ createdAt }" #: assets/components/tracking/connector/ConnectorsList.tsx:50 #, javascript-format msgid "Used in: ${ watchlistCount } Watchlist" -msgstr "" +msgstr "Usado en: ${ watchlistCount } Watchlist" #: assets/components/tracking/connector/ConnectorsList.tsx:53 msgid "" @@ -351,256 +373,286 @@ msgid "" "fulfilled the conditions of use of the supplier's API, waived the right of " "withdrawal and were of the minimum age to consent to these conditions." msgstr "" +"Puedes dejar de usar un conector en cualquier momento. Para eliminar un " +"conector, debes quitarlo de cada Watchlist.\n" +"La fecha de creación corresponde a la fecha en la que usted consintió la " +"creación del Conector y en la que declaró, en particular, que cumplía las " +"condiciones de uso de la API del proveedor, renunciaba al derecho de " +"desistimiento y tenía la edad mínima para consentir dichas condiciones." #: assets/components/tracking/connector/ConnectorsList.tsx:57 msgid "The Provider’s conditions are accessible by following this hyperlink." -msgstr "" +msgstr "Las condiciones del proveedor pueden consultarse siguiendo este enlace." #: assets/components/tracking/watchlist/CalendarWatchlistButton.tsx:15 msgid "QR Code for iCalendar export" -msgstr "" +msgstr "Código QR para exportar a iCalendar" #: assets/components/tracking/watchlist/CalendarWatchlistButton.tsx:20 msgid "Export events to iCalendar format" -msgstr "" +msgstr "Exportar eventos al formato iCalendar" #: assets/components/tracking/watchlist/CreateWatchlistButton.tsx:33 #: assets/components/tracking/watchlist/CreateWatchlistButton.tsx:35 msgid "Create a Watchlist" -msgstr "" +msgstr "Crea una Watchlist" #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:13 #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:21 msgid "Delete the Watchlist" -msgstr "" +msgstr "Eliminar la Watchlist" #: assets/components/tracking/watchlist/DeleteWatchlistButton.tsx:14 msgid "Are you sure to delete this Watchlist?" -msgstr "" +msgstr "¿Estás seguro de que quieres eliminar esta Watchlist?" #: assets/components/tracking/watchlist/diagram/ViewDiagramWatchlistButton.tsx:39 msgid "View the Watchlist Entity Diagram" -msgstr "" +msgstr "Consulte el diagrama de entidad de la Watchlist" #: assets/components/tracking/watchlist/diagram/ViewDiagramWatchlistButton.tsx:45 msgid "Watchlist Entity Diagram" -msgstr "" +msgstr "Diagrama de entidad de la Watchlist" #: assets/components/tracking/watchlist/diagram/watchlistToEdges.tsx:43 msgid "Registry" -msgstr "" +msgstr "Registro" #: assets/components/tracking/watchlist/diagram/watchlistToNodes.tsx:41 #, javascript-format msgid ".${ tld.tld } Registry" -msgstr "" +msgstr ".${ tld.tld } Registro" #: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:18 #: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:26 msgid "Disable the Watchlist" -msgstr "" +msgstr "Desactivar la Watchlist" #: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:19 msgid "Are you sure to disable this Watchlist?" -msgstr "" +msgstr "¿Estás seguro de que quieres desactivar esta Watchlist?" #: assets/components/tracking/watchlist/DisableWatchlistButton.tsx:29 msgid "Enable the Watchlist" -msgstr "" +msgstr "Activar la Watchlist" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:30 msgid "" "At least one domain name is in redemption period and will potentially be " "deleted soon" msgstr "" +"Al menos un dominio se encuentra en período de redención y podría ser " +"eliminado próximamente" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:39 msgid "" "At least one domain name is pending deletion and will soon become available " "for registration again" msgstr "" +"Al menos un nombre de dominio está pendiente de eliminación y pronto volverá " +"a estar disponible para su registro" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:147 msgid "Estimated number of days until WHOIS removal" -msgstr "" +msgstr "Número estimado de días hasta la eliminación de WHOIS" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:150 #, javascript-format msgid "J ${ expiresInDays }" -msgstr "" +msgstr "J ${ expiresInDays }" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:156 msgid "Deletion is imminent" -msgstr "" +msgstr "La eliminación es inminente" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:185 msgid "Status" -msgstr "" +msgstr "Estado" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:191 msgid "Options" -msgstr "" +msgstr "Opciones" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:197 msgid "Expiration date" -msgstr "" +msgstr "Fecha de expiración" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:211 msgid "Updated at" -msgstr "" +msgstr "Actualizado el" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:240 msgid "No tracked domain names were found, please create your first Watchlist" msgstr "" +"No se encontraron nombres de dominio rastreados; por favor, crea tu primera " +"Watchlist" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:243 msgid "Create now" -msgstr "" +msgstr "Crear ahora" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:249 msgid "" "Please note that this table does not include domain names marked as expired " "or those with an unknown expiration date" msgstr "" +"Tenga en cuenta que esta tabla no incluye los nombres de dominio marcados " +"como expirados o aquellos cuya fecha de expiración se desconoce" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:254 msgid "At least one domain name you are tracking requires special attention" msgstr "" +"Al menos uno de los nombres de dominio que estás monitorizando requiere " +"especial atención" #: assets/components/tracking/watchlist/TrackedDomainTable.tsx:260 msgid "The domain names below are subject to special monitoring" msgstr "" +"Los nombres de dominio que aparecen a continuación están sujetos a una " +"supervisión especial" #: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:31 msgid "Edit the Watchlist" -msgstr "" +msgstr "Editar la Watchlist" #: assets/components/tracking/watchlist/UpdateWatchlistButton.tsx:46 msgid "Update a Watchlist" -msgstr "" +msgstr "Actualizar una Watchlist" #: assets/components/tracking/watchlist/WatchlistCard.tsx:54 msgid "This Watchlist is not linked to a Connector." -msgstr "" +msgstr "Esta Watchlist no está vinculada a ningún Conector." #: assets/components/tracking/watchlist/WatchlistCard.tsx:59 #: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:86 msgid "Watchlist" -msgstr "" +msgstr "Watchlist" #: assets/components/tracking/watchlist/WatchlistCard.tsx:97 #: assets/components/tracking/watchlist/WatchlistForm.tsx:191 msgid "Tracked events" -msgstr "" +msgstr "Seguimiento de eventos" #: assets/components/tracking/watchlist/WatchlistCard.tsx:119 #: assets/components/tracking/watchlist/WatchlistForm.tsx:217 msgid "Tracked EPP status" -msgstr "" +msgstr "Seguimiento del estado de EPP" #: assets/components/tracking/watchlist/WatchlistForm.tsx:111 msgid "Name" -msgstr "" +msgstr "Nombre" #: assets/components/tracking/watchlist/WatchlistForm.tsx:123 msgid "Watchlist Name" -msgstr "" +msgstr "Nombre en la Watchlist" #: assets/components/tracking/watchlist/WatchlistForm.tsx:124 msgid "Naming the Watchlist makes it easier to find in the list below." msgstr "" +"Poner un nombre a la Watchlist facilita su localización en la lista " +"siguiente." #: assets/components/tracking/watchlist/WatchlistForm.tsx:135 msgid "At least one domain name" -msgstr "" +msgstr "Al menos un nombre de dominio" #: assets/components/tracking/watchlist/WatchlistForm.tsx:146 msgid "Domain names" -msgstr "" +msgstr "Nombres de dominio" #: assets/components/tracking/watchlist/WatchlistForm.tsx:164 msgid "Domain name" -msgstr "" +msgstr "Nombre de dominio" #: assets/components/tracking/watchlist/WatchlistForm.tsx:183 msgid "Add a Domain name" -msgstr "" +msgstr "Agregar un nombre de dominio" #: assets/components/tracking/watchlist/WatchlistForm.tsx:193 msgid "At least one event" -msgstr "" +msgstr "Al menos un evento" #: assets/components/tracking/watchlist/WatchlistForm.tsx:219 msgid "At least one EPP status" -msgstr "" +msgstr "Al menos un estado EPP" #: assets/components/tracking/watchlist/WatchlistForm.tsx:243 #: assets/components/tracking/watchlist/WatchlistForm.tsx:258 msgid "Connector" -msgstr "" +msgstr "Conector" #: assets/components/tracking/watchlist/WatchlistForm.tsx:253 msgid "" "Please make sure the connector information is valid to purchase a domain " "that may be available soon." msgstr "" +"Asegúrese de que la información del Conector sea válida para comprar un " +"dominio que podría estar disponible próximamente." #: assets/components/tracking/watchlist/WatchlistForm.tsx:275 msgid "DSN" -msgstr "" +msgstr "DSN" #: assets/components/tracking/watchlist/WatchlistForm.tsx:287 msgid "This DSN does not appear to be valid" -msgstr "" +msgstr "Este DSN no parece ser válido" #: assets/components/tracking/watchlist/WatchlistForm.tsx:311 msgid "Check out this link to the Symfony documentation to help you build the DSN" msgstr "" +"Consulta este enlace a la documentación de Symfony para obtener ayuda en la " +"creación del DSN" #: assets/components/tracking/watchlist/WatchlistForm.tsx:321 msgid "Add a Webhook" -msgstr "" +msgstr "Agregar un webhook" #: assets/components/tracking/watchlist/WatchlistForm.tsx:331 msgid "Update" -msgstr "" +msgstr "Actualizar" #: assets/components/tracking/watchlist/WatchlistForm.tsx:334 msgid "Reset" -msgstr "" +msgstr "Reiniciar" #: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:29 #, javascript-format msgid "${ rest.length } more" -msgstr "" +msgstr "${ rest.length } más" #: assets/components/tracking/watchlist/WatchlistSelectionModal.tsx:82 msgid "Select one of your available Watchlists" -msgstr "" +msgstr "Selecciona una de tus Watchlist disponibles" #: assets/pages/infrastructure/IcannRegistrarPage.tsx:45 msgid "ID" -msgstr "" +msgstr "ID" #: assets/pages/infrastructure/IcannRegistrarPage.tsx:80 msgid "" "An accredited number means that ICANN's contract with the registrar is " "ongoing." msgstr "" +"Un número acreditado significa que el contrato de la ICANN con el " +"registrador está vigente." #: assets/pages/infrastructure/IcannRegistrarPage.tsx:85 msgid "A reserved number can be used by TLD registries for specific operations." msgstr "" +"Los Registros de TLD pueden utilizar un número reservado para operaciones " +"específicas." #: assets/pages/infrastructure/IcannRegistrarPage.tsx:90 msgid "" "A terminated number means that ICANN's contract with the registrar has been " "terminated." msgstr "" +"Un número terminado significa que el contrato de ICANN con el Registrador ha " +"sido rescindido." #: assets/pages/infrastructure/IcannRegistrarPage.tsx:99 msgid "This page lists ICANN-accredited registrars." -msgstr "" +msgstr "Esta página enumera los registradores acreditados por la ICANN." #: assets/pages/infrastructure/IcannRegistrarPage.tsx:102 msgid "" @@ -609,33 +661,37 @@ msgid "" "Internet's unique identifiers (including numbers, IP addresses, and domain " "name extensions)." msgstr "" +"La lista es publicada y mantenida oficialmente por la Autoridad de Números " +"Asignados de Internet (IANA), la organización responsable de gestionar los " +"identificadores únicos de Internet " +"(incluidos números, direcciones IP y extensiones de nombres de dominio)." #: assets/pages/infrastructure/IcannRegistrarPage.tsx:114 #: assets/utils/functions/rdapTranslation.ts:125 msgid "Accredited" -msgstr "" +msgstr "Acreditado" #: assets/pages/infrastructure/IcannRegistrarPage.tsx:119 #: assets/utils/functions/rdapTranslation.ts:126 msgid "Reserved" -msgstr "" +msgstr "Reservado" #: assets/pages/infrastructure/IcannRegistrarPage.tsx:124 #: assets/utils/functions/rdapTranslation.ts:124 msgid "Terminated" -msgstr "" +msgstr "Terminado" #: assets/pages/infrastructure/TldPage.tsx:88 msgid "Flag" -msgstr "" +msgstr "Bandera" #: assets/pages/infrastructure/TldPage.tsx:91 msgid "Country" -msgstr "" +msgstr "País" #: assets/pages/infrastructure/TldPage.tsx:98 msgid "Registry Operator" -msgstr "" +msgstr "Operador de registro" #: assets/pages/infrastructure/TldPage.tsx:127 msgid "" @@ -643,28 +699,40 @@ msgid "" "registration and use, often related to particular interest groups or " "industries." msgstr "" +"Dominios de nivel superior patrocinados por organizaciones específicas que " +"establecen reglas para su registro y uso, a menudo relacionadas con grupos " +"de interés o industrias particulares." #: assets/pages/infrastructure/TldPage.tsx:132 msgid "" "Generic top-level domains open to everyone, not restricted by specific " "criteria, representing various themes or industries." msgstr "" +"Dominios genéricos de nivel superior abiertos a todo el mundo, sin " +"restricciones por criterios específicos, que representan diversos temas o " +"industrias." #: assets/pages/infrastructure/TldPage.tsx:137 msgid "" "Generic top-level domains associated with specific brands, allowing " "companies to use their own brand names as domains." msgstr "" +"Dominios genéricos de nivel superior asociados a marcas específicas, que " +"permiten a las empresas utilizar sus propios nombres de marca como dominios." #: assets/pages/infrastructure/TldPage.tsx:142 msgid "" "Top-level domains based on country codes, identifying websites according to " "their country of origin." msgstr "" +"Dominios de nivel superior basados en códigos de país, que identifican los " +"sitios web según su país de origen." #: assets/pages/infrastructure/TldPage.tsx:151 msgid "This page presents all active TLDs in the root zone database." msgstr "" +"Esta página presenta todos los TLD activos en la base de datos de la zona " +"raíz." #: assets/pages/infrastructure/TldPage.tsx:154 msgid "" @@ -677,331 +745,376 @@ msgid "" "ICANN).\n" "At the same time, the list of root RDAP servers is updated." msgstr "" +"La IANA proporciona la lista de TLD actualmente activos, independientemente " +"de su tipo, e ICANN proporciona la lista de gTLD.\n" +" En la mayoría de los casos, el ccTLD de dos letras asignado a un país se " +"crea de acuerdo con la norma ISO 3166-1.\n" +" Estos datos se actualizan mensualmente. Se necesitan tres solicitudes HTTP " +"para la actualización completa de los TLD en Domain Watchdog " +"(dos solicitudes a IANA y una a ICANN).\n" +" Al mismo tiempo, se actualiza la lista de servidores RDAP raíz." #: assets/pages/infrastructure/TldPage.tsx:169 msgid "Generic Top-Level-Domains" -msgstr "" +msgstr "Dominios genéricos de nivel superior" #: assets/pages/infrastructure/TldPage.tsx:174 msgid "Country-Code Top-Level-Domains" -msgstr "" +msgstr "Dominios de nivel superior de código de país" #: assets/pages/infrastructure/TldPage.tsx:179 msgid "Brand Generic Top-Level-Domains" -msgstr "" +msgstr "Dominios de nivel superior genéricos de marca" #: assets/pages/infrastructure/TldPage.tsx:184 msgid "Sponsored Top-Level-Domains" -msgstr "" +msgstr "Dominios de nivel superior patrocinados" #: assets/pages/LoginPage.tsx:46 msgid "Create an account" -msgstr "" +msgstr "Crea una cuenta" #: assets/pages/NotFoundPage.tsx:10 msgid "Sorry, the page you visited does not exist." -msgstr "" +msgstr "Lo sentimos, la página que intentó visitar no existe." #: assets/pages/search/DomainSearchPage.tsx:36 msgid "Found !" -msgstr "" +msgstr "Encontró !" #: assets/pages/search/DomainSearchPage.tsx:53 #, javascript-format msgid "${ ldhName } added to ${ watchlist.name }" -msgstr "" +msgstr "${ ldhName } añadido a ${ watchlist.name }" #: assets/pages/search/DomainSearchPage.tsx:70 msgid "" "Although the domain exists in my database, it has been deleted from the " "WHOIS by its registrar." msgstr "" +"Aunque el dominio existe en mi base de datos, ha sido borrado del WHOIS por " +"su registrador." #: assets/pages/search/DomainSearchPage.tsx:82 msgid "Add to Watchlist" -msgstr "" +msgstr "Añadir a la Watchlist" #: assets/pages/search/DomainSearchPage.tsx:92 #, javascript-format msgid "Add ${ domainLdhName } to a Watchlist" -msgstr "" +msgstr "Agregar ${ domainLdhName } a una Watchlist" #: assets/pages/search/DomainSearchPage.tsx:95 msgid "Cancel" -msgstr "" +msgstr "Cancelar" #: assets/pages/search/DomainSearchPage.tsx:96 msgid "Add" -msgstr "" +msgstr "Agregar" #: assets/pages/StatisticsPage.tsx:33 msgid "RDAP queries" -msgstr "" +msgstr "Consultas RDAP" #: assets/pages/StatisticsPage.tsx:42 msgid "Alerts sent" -msgstr "" +msgstr "Alertas enviadas" #: assets/pages/StatisticsPage.tsx:56 msgid "Domain names in database" -msgstr "" +msgstr "Nombres de dominio en la base de datos" #: assets/pages/StatisticsPage.tsx:67 msgid "Tracked domain names" -msgstr "" +msgstr "Nombres de dominio rastreados" #: assets/pages/StatisticsPage.tsx:81 msgid "Purchased domain names" -msgstr "" +msgstr "Nombres de dominio comprados" #: assets/pages/StatisticsPage.tsx:91 msgid "" "This value is based on the status code of the HTTP response from the " "providers following the domain order." msgstr "" +"Este valor se basa en el código de estado de la respuesta HTTP de los " +"proveedores, siguiendo el orden del dominio." #: assets/pages/StatisticsPage.tsx:95 msgid "Success rate" -msgstr "" +msgstr "Tasa de éxito" #: assets/pages/TextPage.tsx:29 #, javascript-format msgid "📝 Please create the /public/content/${ resource } file." -msgstr "" +msgstr "📝 Por favor, cree el archivo /public/content/${ resource }." #: assets/pages/tracking/ConnectorPage.tsx:22 msgid "Connector created !" -msgstr "" +msgstr "¡Conector creado!" #: assets/pages/tracking/ConnectorPage.tsx:41 msgid "Create a Connector" -msgstr "" +msgstr "Crear un Conector" #: assets/pages/tracking/WatchlistPage.tsx:42 msgid "Watchlist created !" -msgstr "" +msgstr "¡Watchlist creada!" #: assets/pages/tracking/WatchlistPage.tsx:53 msgid "Watchlist updated !" -msgstr "" +msgstr "¡Watchlist actualizada!" #: assets/pages/UserPage.tsx:19 #: assets/utils/providers/forms/EppConnectorForm.tsx:129 #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:10 #: assets/utils/providers/forms/NamecomConnectorForm.tsx:16 msgid "Username" -msgstr "" +msgstr "Nombre de usuario" #: assets/pages/UserPage.tsx:22 msgid "Roles" -msgstr "" +msgstr "Roles" #: assets/utils/functions/DomainToTag.tsx:14 msgid "The domain name was updated less than a week ago." -msgstr "" +msgstr "El nombre de dominio se actualizó hace menos de una semana." #: assets/utils/functions/rdapTranslation.ts:7 #: assets/utils/providers/forms/EppConnectorForm.tsx:241 msgid "Registrant" -msgstr "" +msgstr "Registrante" #: assets/utils/functions/rdapTranslation.ts:8 #: assets/utils/providers/forms/EppConnectorForm.tsx:251 msgid "Technical" -msgstr "" +msgstr "Técnico" #: assets/utils/functions/rdapTranslation.ts:9 #: assets/utils/providers/forms/EppConnectorForm.tsx:246 msgid "Administrative" -msgstr "" +msgstr "Administrativo" #: assets/utils/functions/rdapTranslation.ts:10 msgid "Abuse" -msgstr "" +msgstr "Abuso" #: assets/utils/functions/rdapTranslation.ts:11 #: assets/utils/providers/forms/EppConnectorForm.tsx:256 msgid "Billing" -msgstr "" +msgstr "Facturación" #: assets/utils/functions/rdapTranslation.ts:13 #: assets/utils/providers/forms/EppConnectorForm.tsx:266 msgid "Reseller" -msgstr "" +msgstr "Revendedor" #: assets/utils/functions/rdapTranslation.ts:14 msgid "Sponsor" -msgstr "" +msgstr "Patrocinador" #: assets/utils/functions/rdapTranslation.ts:15 msgid "Proxy" -msgstr "" +msgstr "Proxy" #: assets/utils/functions/rdapTranslation.ts:16 msgid "Notifications" -msgstr "" +msgstr "Notificaciones" #: assets/utils/functions/rdapTranslation.ts:17 msgid "Noc" -msgstr "" +msgstr "Noc" #: assets/utils/functions/rdapTranslation.ts:24 msgid "" "The entity object instance is the registrant of the registration. In some " "registries, this is known as a maintainer." msgstr "" +"La instancia del objeto de entidad es el registrante del registro. En " +"algunos registros, se le conoce como mantenedor." #: assets/utils/functions/rdapTranslation.ts:25 msgid "The entity object instance is a technical contact for the registration." msgstr "" +"La instancia del objeto de entidad es un contacto técnico para el registro." #: assets/utils/functions/rdapTranslation.ts:26 msgid "" "The entity object instance is an administrative contact for the " "registration." msgstr "" +"La instancia del objeto de entidad es un contacto administrativo para el " +"registro." #: assets/utils/functions/rdapTranslation.ts:27 msgid "" "The entity object instance handles network abuse issues on behalf of the " "registrant of the registration." msgstr "" +"La instancia del objeto de entidad gestiona los problemas de abuso de la red " +"en nombre del registrante del registro." #: assets/utils/functions/rdapTranslation.ts:28 msgid "" "The entity object instance handles payment and billing issues on behalf of " "the registrant of the registration." msgstr "" +"La instancia del objeto de entidad gestiona los problemas de pago y " +"facturación en nombre del titular del registro." #: assets/utils/functions/rdapTranslation.ts:29 msgid "" "The entity object instance represents the authority responsible for the " "registration in the registry." msgstr "" +"La instancia del objeto de entidad representa la autoridad responsable del " +"registro en el registro." #: assets/utils/functions/rdapTranslation.ts:30 msgid "" "The entity object instance represents a third party through which the " "registration was conducted (i.e., not the registry or registrar)." msgstr "" +"La instancia del objeto de entidad representa a un tercero a través del cual " +"se realizó el registro (es decir, no el registro ni el registrador)." #: assets/utils/functions/rdapTranslation.ts:31 msgid "" "The entity object instance represents a domain policy sponsor, such as an " "ICANN-approved sponsor." msgstr "" +"La instancia del objeto de entidad representa un patrocinador de políticas " +"de dominio, como un patrocinador aprobado por la ICANN." #: assets/utils/functions/rdapTranslation.ts:32 msgid "" "The entity object instance represents a proxy for another entity object, " "such as a registrant." msgstr "" +"La instancia del objeto de entidad representa un proxy para otro objeto de " +"entidad, como un registrante." #: assets/utils/functions/rdapTranslation.ts:33 msgid "" "An entity object instance designated to receive notifications about " "association object instances." msgstr "" +"Una instancia de objeto de entidad designada para recibir notificaciones " +"sobre instancias de objetos de asociación." #: assets/utils/functions/rdapTranslation.ts:34 msgid "" "The entity object instance handles communications related to a network " "operations center (NOC)." msgstr "" +"La instancia del objeto de entidad gestiona las comunicaciones relacionadas " +"con un centro de operaciones de red (NOC)." #: assets/utils/functions/rdapTranslation.ts:42 msgid "Reregistration" -msgstr "" +msgstr "Reinscripción" #: assets/utils/functions/rdapTranslation.ts:43 msgid "Changed" -msgstr "" +msgstr "Cambió" #: assets/utils/functions/rdapTranslation.ts:44 msgid "Expiration" -msgstr "" +msgstr "Caducidad" #: assets/utils/functions/rdapTranslation.ts:45 msgid "Deletion" -msgstr "" +msgstr "Supresión" #: assets/utils/functions/rdapTranslation.ts:46 msgid "Reinstantiation" -msgstr "" +msgstr "Reinstanciación" #: assets/utils/functions/rdapTranslation.ts:47 msgid "Transfer" -msgstr "" +msgstr "Transferir" #: assets/utils/functions/rdapTranslation.ts:48 msgid "Locked" -msgstr "" +msgstr "Bloqueado" #: assets/utils/functions/rdapTranslation.ts:49 msgid "Unlocked" -msgstr "" +msgstr "Desbloqueado" #: assets/utils/functions/rdapTranslation.ts:50 msgid "Registrar expiration" -msgstr "" +msgstr "Caducidad del registrador" #: assets/utils/functions/rdapTranslation.ts:51 msgid "ENUM validation expiration" -msgstr "" +msgstr "Caducidad de validación ENUM" #: assets/utils/functions/rdapTranslation.ts:58 msgid "The object instance was initially registered." -msgstr "" +msgstr "La instancia del objeto se registró inicialmente." #: assets/utils/functions/rdapTranslation.ts:59 msgid "The object instance was registered subsequently to initial registration." -msgstr "" +msgstr "La instancia del objeto se registró posteriormente al registro inicial." #: assets/utils/functions/rdapTranslation.ts:60 msgid "" "An action noting when the information in the object instance was last " "changed." msgstr "" +"Una acción que registra cuándo se modificó por última vez la información en " +"la instancia del objeto." #: assets/utils/functions/rdapTranslation.ts:61 msgid "" "The object instance has been removed or will be removed at a predetermined " "date and time from the registry." msgstr "" +"La instancia del objeto ha sido eliminada o será eliminada del registro en " +"una fecha y hora predeterminadas." #: assets/utils/functions/rdapTranslation.ts:62 msgid "" "The object instance was removed from the registry at a point in time that " "was not predetermined." msgstr "" +"La instancia del objeto se eliminó del registro en un momento no " +"predeterminado." #: assets/utils/functions/rdapTranslation.ts:63 msgid "" "The object instance was reregistered after having been removed from the " "registry." msgstr "" +"La instancia del objeto se volvió a registrar después de haber sido " +"eliminada del registro." #: assets/utils/functions/rdapTranslation.ts:64 msgid "The object instance was transferred from one registrar to another." -msgstr "" +msgstr "La instancia del objeto se transfirió de un registrador a otro." #: assets/utils/functions/rdapTranslation.ts:65 msgid "The object instance was locked." -msgstr "" +msgstr "La instancia del objeto estaba bloqueada." #: assets/utils/functions/rdapTranslation.ts:66 msgid "The object instance was unlocked." -msgstr "" +msgstr "La instancia del objeto se desbloqueó." #: assets/utils/functions/rdapTranslation.ts:67 msgid "An action noting the expiration date of the object in the registrar system." msgstr "" +"Una acción que registra la fecha de vencimiento del objeto en el sistema de " +"registro." #: assets/utils/functions/rdapTranslation.ts:68 msgid "" "Association of phone number represented by this ENUM domain to registrant " "has expired or will expire at a predetermined date and time." msgstr "" +"La asociación del número de teléfono representado por este dominio ENUM con " +"el registrante ha caducado o caducará en una fecha y hora predeterminadas." #: assets/utils/functions/rdapTranslation.ts:72 #: assets/utils/functions/rdapTranslation.ts:81 @@ -1009,6 +1122,8 @@ msgid "" "This is the standard status for a domain, meaning it has no pending " "operations or prohibitions." msgstr "" +"Este es el estado estándar de un dominio, lo que significa que no tiene " +"operaciones pendientes ni prohibiciones." #: assets/utils/functions/rdapTranslation.ts:73 msgid "" @@ -1016,30 +1131,41 @@ msgid "" "not been associated with your domain. Your domain is not activated in the " "DNS and will not resolve." msgstr "" +"Este código de estado indica que la información de delegación " +"(servidores de nombres) no se ha asociado a su dominio. Su dominio no está " +"activado en el DNS y no se resolverá." #: assets/utils/functions/rdapTranslation.ts:74 msgid "" "This status code indicates that a request to create your domain has been " "received and is being processed." msgstr "" +"Este código de estado indica que se ha recibido una solicitud para crear su " +"dominio y que esta se está procesando." #: assets/utils/functions/rdapTranslation.ts:75 msgid "" "This status code indicates that a request to renew your domain has been " "received and is being processed." msgstr "" +"Este código de estado indica que se ha recibido una solicitud de renovación " +"de su dominio y que esta se está procesando." #: assets/utils/functions/rdapTranslation.ts:76 msgid "" "This status code indicates that a request to transfer your domain to a new " "registrar has been received and is being processed." msgstr "" +"Este código de estado indica que se ha recibido una solicitud para " +"transferir su dominio a un nuevo registrador y que esta se está procesando." #: assets/utils/functions/rdapTranslation.ts:77 msgid "" "This status code indicates that a request to update your domain has been " "received and is being processed." msgstr "" +"Este código de estado indica que se ha recibido una solicitud para " +"actualizar su dominio y que esta se está procesando." #: assets/utils/functions/rdapTranslation.ts:78 msgid "" @@ -1055,6 +1181,17 @@ msgid "" "domain is available for re-registration in accordance with the registry's " "policies." msgstr "" +"Este código de estado puede combinarse con redemptionPeriod o " +"pendingRestore. En tal caso, según el estado " +"(redemptionPeriod o pendingRestore) establecido en el nombre de dominio, se " +"aplicará la descripción correspondiente presentada anteriormente. Si este " +"estado no se combina con redemptionPeriod ni pendingRestore, el código de " +"estado pendingDelete indica que su dominio ha estado en estado " +"redemptionPeriod durante 30 días y no lo ha restaurado dentro de ese " +"período. Su dominio permanecerá en este estado durante varios días, tras los " +"cuales será eliminado de la base de datos del registro. Una vez eliminado, " +"el dominio estará disponible para su reinscripción de acuerdo con las " +"políticas del registro." #: assets/utils/functions/rdapTranslation.ts:79 msgid "" @@ -1063,6 +1200,9 @@ msgid "" "registry may provide credit to the registrar for the cost of the " "registration." msgstr "" +"Este período de gracia se otorga tras el registro inicial de un nombre de " +"dominio. Si el registrador elimina el nombre de dominio durante este " +"período, el registro puede abonar al registrador el coste del registro." #: assets/utils/functions/rdapTranslation.ts:80 msgid "" @@ -1071,12 +1211,18 @@ msgid "" "registrar deletes the domain name during this period, the registry provides " "a credit to the registrar for the cost of the renewal." msgstr "" +"Este período de gracia se otorga tras la expiración del período de registro " +"de un nombre de dominio y se extiende (renueva) automáticamente por el " +"registro. Si el registrador elimina el nombre de dominio durante este " +"período, el registro le abona el costo de la renovación." #: assets/utils/functions/rdapTranslation.ts:82 msgid "" "This status code tells your domain's registry to reject requests to delete " "the domain." msgstr "" +"Este código de estado indica al registro de su dominio que rechace las " +"solicitudes para eliminar el dominio." #: assets/utils/functions/rdapTranslation.ts:83 msgid "" @@ -1085,6 +1231,10 @@ msgid "" "status that is usually enacted during legal disputes, non-payment, or when " "your domain is subject to deletion." msgstr "" +"Este código de estado indica al registro de tu dominio que no lo active en " +"el DNS y, por lo tanto, no se resolverá. Es un estado poco común que suele " +"activarse durante disputas legales, impagos o cuando tu dominio está sujeto " +"a eliminación." #: assets/utils/functions/rdapTranslation.ts:84 msgid "" @@ -1092,18 +1242,25 @@ msgid "" "your domain. It is an uncommon status that is usually enacted during legal " "disputes or when your domain is subject to deletion." msgstr "" +"Este código de estado indica al registro de su dominio que rechace las " +"solicitudes de renovación. Es un estado poco común que suele activarse " +"durante disputas legales o cuando su dominio está sujeto a eliminación." #: assets/utils/functions/rdapTranslation.ts:85 msgid "" "This status code tells your domain's registry to reject requests to " "transfer the domain from your current registrar to another." msgstr "" +"Este código de estado indica al registro de su dominio que rechace las " +"solicitudes de transferencia del dominio desde su registrador actual a otro." #: assets/utils/functions/rdapTranslation.ts:86 msgid "" "This status code tells your domain's registry to reject requests to update " "the domain." msgstr "" +"Este código de estado indica al registro de su dominio que rechace las " +"solicitudes de actualización del dominio." #: assets/utils/functions/rdapTranslation.ts:87 msgid "" @@ -1114,6 +1271,14 @@ msgid "" "documentation to the registry operator within a set time period to confirm " "the restoration request, the domain will revert to redemptionPeriod status." msgstr "" +"Este código de estado indica que su registrador ha solicitado al registro " +"que restaure su dominio, que se encontraba en estado de " +"\"Periodo de redención\". El registro mantendrá el dominio en este estado " +"mientras espera que su registrador proporcione la documentación necesaria " +"para la restauración. Si su registrador no proporciona la documentación al " +"operador del registro dentro del plazo establecido para confirmar la " +"solicitud de restauración, el dominio volverá al estado de " +"\"Periodo de redención\"." #: assets/utils/functions/rdapTranslation.ts:88 msgid "" @@ -1123,6 +1288,11 @@ msgid "" "domain is purged from the registry database and becomes available for " "registration." msgstr "" +"Este código de estado indica que su registrador ha solicitado al registro " +"que elimine su dominio. Su dominio permanecerá en este estado durante 30 " +"días. Transcurridos cinco días naturales desde la finalización del período " +"de redención, su dominio se eliminará de la base de datos del registro y " +"estará disponible para su registro." #: assets/utils/functions/rdapTranslation.ts:89 msgid "" @@ -1131,6 +1301,10 @@ msgid "" "the domain name during this period, the registry provides a credit to the " "registrar for the cost of the renewal." msgstr "" +"Este período de gracia se otorga después de que el registrador extienda " +"(renueve) explícitamente el período de registro de un nombre de dominio. Si " +"el registrador elimina el nombre de dominio durante este período, el " +"registro le otorga un crédito por el costo de la renovación." #: assets/utils/functions/rdapTranslation.ts:90 msgid "" @@ -1138,6 +1312,9 @@ msgid "" "status that is usually enacted during legal disputes, at your request, or " "when a redemptionPeriod status is in place." msgstr "" +"Este código de estado impide que se elimine su dominio. Es un estado poco " +"común que generalmente se activa durante disputas legales, a petición suya o " +"cuando está vigente un período de redención." #: assets/utils/functions/rdapTranslation.ts:91 msgid "" @@ -1146,6 +1323,10 @@ msgid "" "usually enacted during legal disputes or when your domain is subject to " "deletion." msgstr "" +"Este código de estado indica que el operador del registro de su dominio no " +"permitirá que su registrador renueve su dominio. Es un estado poco común que " +"generalmente se activa durante disputas legales o cuando su dominio está " +"sujeto a eliminación." #: assets/utils/functions/rdapTranslation.ts:92 msgid "" @@ -1154,6 +1335,10 @@ msgid "" "enacted during legal or other disputes, at your request, or when a " "redemptionPeriod status is in place." msgstr "" +"Este código de estado impide que su dominio se transfiera de su registrador " +"actual a otro. Es un estado poco común que generalmente se activa durante " +"disputas legales o de otro tipo, a petición suya o cuando está vigente un " +"período de redención." #: assets/utils/functions/rdapTranslation.ts:93 msgid "" @@ -1161,12 +1346,17 @@ msgid "" "an uncommon status that is usually enacted during legal disputes, at your " "request, or when a redemptionPeriod status is in place." msgstr "" +"Este código de estado bloquea su dominio, impidiendo que se actualice. Es un " +"estado poco común que generalmente se activa durante disputas legales, a " +"petición suya o cuando está vigente un período de redención." #: assets/utils/functions/rdapTranslation.ts:94 msgid "" "This status code is set by your domain's Registry Operator. Your domain is " "not activated in the DNS." msgstr "" +"Este código de estado lo establece el operador del registro de su dominio. " +"Su dominio no está activado en el DNS." #: assets/utils/functions/rdapTranslation.ts:95 msgid "" @@ -1175,44 +1365,57 @@ msgid "" "name during this period, the registry provides a credit to the registrar " "for the cost of the transfer." msgstr "" +"Este período de gracia se otorga tras la transferencia exitosa de un nombre " +"de dominio de un registrador a otro. Si el nuevo registrador elimina el " +"nombre de dominio durante este período, el registro le abona el costo de la " +"transferencia." #: assets/utils/functions/rdapTranslation.ts:104 msgid "" "Signifies that the data of the object instance has been found to be " "accurate." msgstr "" +"Significa que se ha comprobado que los datos de la instancia del objeto son " +"correctos." #: assets/utils/functions/rdapTranslation.ts:105 msgid "Renewal or reregistration of the object instance is forbidden." msgstr "" +"Se prohíbe la renovación o el nuevo registro de la instancia del objeto." #: assets/utils/functions/rdapTranslation.ts:106 msgid "Updates to the object instance are forbidden." -msgstr "" +msgstr "Se prohíben las actualizaciones de la instancia del objeto." #: assets/utils/functions/rdapTranslation.ts:107 msgid "Transfers of the registration from one registrar to another are forbidden." msgstr "" +"Quedan prohibidas las transferencias de registro de un registrador a otro." #: assets/utils/functions/rdapTranslation.ts:108 msgid "Deletion of the registration of the object instance is forbidden." -msgstr "" +msgstr "Está prohibida la eliminación del registro de la instancia del objeto." #: assets/utils/functions/rdapTranslation.ts:109 msgid "The registration of the object instance has been performed by a third party." msgstr "" +"El registro de la instancia del objeto ha sido realizado por un tercero." #: assets/utils/functions/rdapTranslation.ts:110 msgid "" "The information of the object instance is not designated for public " "consumption." msgstr "" +"La información de la instancia del objeto no está destinada al consumo " +"público." #: assets/utils/functions/rdapTranslation.ts:111 msgid "" "Some of the information of the object instance has not been made available " "and has been removed." msgstr "" +"Parte de la información de la instancia del objeto no se ha facilitado y se " +"ha eliminado." #: assets/utils/functions/rdapTranslation.ts:112 msgid "" @@ -1220,40 +1423,50 @@ msgid "" "purposes of not readily revealing the actual information of the object " "instance." msgstr "" +"Parte de la información de la instancia del objeto ha sido alterada con el " +"fin de no revelar fácilmente la información real de la instancia del objeto." #: assets/utils/functions/rdapTranslation.ts:113 msgid "" "The object instance is associated with other object instances in the " "registry." msgstr "" +"La instancia del objeto está asociada con otras instancias de objetos en el " +"registro." #: assets/utils/functions/rdapTranslation.ts:114 msgid "" "Changes to the object instance cannot be made, including the association of " "other object instances." msgstr "" +"No se pueden realizar cambios en la instancia del objeto, incluida la " +"asociación con otras instancias de objetos." #: assets/utils/functions/rdapTranslation.ts:118 msgid "" "The object instance has been allocated administratively (i.e., not for use " "by the recipient in their own right in operational networks)." msgstr "" +"La instancia del objeto ha sido asignada administrativamente (es decir, no " +"para uso del destinatario por derecho propio en redes operativas)." #: assets/utils/functions/rdapTranslation.ts:119 msgid "" "The object instance has been allocated to an IANA special-purpose address " "registry." msgstr "" +"La instancia del objeto ha sido asignada a un registro de direcciones de " +"propósito especial de la IANA." #: assets/utils/functions/showErrorAPI.tsx:18 #, javascript-format msgid "Please retry after ${ duration } seconds" -msgstr "" +msgstr "Por favor, inténtelo de nuevo después de ${ duration } segundos" #: assets/utils/functions/showErrorAPI.tsx:22 #: assets/utils/functions/showErrorAPI.tsx:25 msgid "An error occurred" -msgstr "" +msgstr "Se produjo un error" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:10 #: assets/utils/providers/forms/NamecomConnectorForm.tsx:11 @@ -1261,209 +1474,227 @@ msgid "" "This provider does not provide a list of supported TLD. Please double check " "if the domain you want to register is supported." msgstr "" +"Este proveedor no ofrece una lista de los TLD compatibles. Por favor, " +"verifique si el dominio que desea registrar es compatible." #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:16 msgid "AutoDNS Username" -msgstr "" +msgstr "Nombre de usuario AutoDNS" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:19 msgid "" "Because of some limitations in API of AutoDNS, we suggest to create an " "dedicated user for API with limited rights" msgstr "" +"Debido a ciertas limitaciones en la API de AutoDNS, sugerimos crear un " +"usuario dedicado a la API con derechos limitados" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:26 msgid "AutoDNS Password" -msgstr "" +msgstr "Contraseña AutoDNS" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:30 msgid "" "Attention: AutoDNS do not support 2-Factor Authentication on API Users for " "automated systems" msgstr "" +"Atención: AutoDNS no admite la autenticación de dos factores para usuarios " +"de API en sistemas automatizados" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:38 msgid "Owner nic-handle" -msgstr "" +msgstr "Nic-handle del propietario" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:42 msgid "The nic-handle of the domain name owner" -msgstr "" +msgstr "El identificador NIC del propietario del nombre de dominio" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:44 msgid "You can get it from this page" -msgstr "" +msgstr "Puedes obtenerlo en esta página" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:54 msgid "Context Value" -msgstr "" +msgstr "Valor de contexto" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:58 msgid "If you not sure, use the default value 4" -msgstr "" +msgstr "Si no estás seguro, usa el valor predeterminado 4" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:67 msgid "Owner confirmation" -msgstr "" +msgstr "Confirmación del propietario" #: assets/utils/providers/forms/AutoDnsConnectorForm.tsx:74 msgid "Owner confirms his consent of domain order jobs" msgstr "" +"El propietario confirma su consentimiento para los trabajos de orden de " +"dominio" #: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:9 msgid "API Terms of Service" -msgstr "" +msgstr "Condiciones de servicio de la API" #: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:16 msgid "" "I have read and accepted the conditions of use of the Provider API, " "accessible from this hyperlink" msgstr "" +"He leído y acepto las condiciones de uso de la API del proveedor, accesibles " +"desde este enlace" #: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:22 msgid "Legal age" -msgstr "" +msgstr "Edad legal" #: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:27 msgid "I am of the minimum age required to consent to these conditions" -msgstr "" +msgstr "Tengo la edad mínima requerida para aceptar estas condiciones" #: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:32 msgid "Withdrawal period" -msgstr "" +msgstr "Derecho de desistimiento" #: assets/utils/providers/forms/DefaultConnectorFormItems.tsx:37 msgid "" "I waive my right of withdrawal regarding the purchase of domain names via " "the Provider's API" msgstr "" +"Renuncio a mi derecho de desistimiento respecto a la compra de nombres de " +"dominio a través de la API del proveedor" #: assets/utils/providers/forms/EppConnectorForm.tsx:61 msgid "" "This connector is experimental and its implementation has not been fully " "tested. Please submit an issue for any issues related to it." msgstr "" +"Este Conector es experimental y su implementación no ha sido probada " +"completamente. Por favor, reporte cualquier problema relacionado con él." #: assets/utils/providers/forms/EppConnectorForm.tsx:66 msgid "The EPP connector is a special type of connector. Be careful." -msgstr "" +msgstr "El conector EPP es un tipo especial de conector. Tenga cuidado." #: assets/utils/providers/forms/EppConnectorForm.tsx:71 msgid "Server configuration" -msgstr "" +msgstr "Configuración del servidor" #: assets/utils/providers/forms/EppConnectorForm.tsx:72 msgid "Protocol" -msgstr "" +msgstr "Protocolo" #: assets/utils/providers/forms/EppConnectorForm.tsx:76 msgid "Version" -msgstr "" +msgstr "Versión" #: assets/utils/providers/forms/EppConnectorForm.tsx:88 msgid "Language" -msgstr "" +msgstr "Idioma" #: assets/utils/providers/forms/EppConnectorForm.tsx:101 msgid "Server" -msgstr "" +msgstr "Servidor" #: assets/utils/providers/forms/EppConnectorForm.tsx:121 msgid "Credentials" -msgstr "" +msgstr "Cartas credenciales" #: assets/utils/providers/forms/EppConnectorForm.tsx:144 msgid "TLS client certificate" -msgstr "" +msgstr "Certificado de cliente TLS" #: assets/utils/providers/forms/EppConnectorForm.tsx:162 msgid "Private key passphrase (optional)" -msgstr "" +msgstr "Contraseña de clave privada (opcional)" #: assets/utils/providers/forms/EppConnectorForm.tsx:169 msgid "TLS configuration" -msgstr "" +msgstr "Configuración TLS" #: assets/utils/providers/forms/EppConnectorForm.tsx:174 msgid "Verify peer" -msgstr "" +msgstr "Verificar pares" #: assets/utils/providers/forms/EppConnectorForm.tsx:183 msgid "Verify peer name" -msgstr "" +msgstr "Verificar nombre del par" #: assets/utils/providers/forms/EppConnectorForm.tsx:192 msgid "Allow self-signed certificates" -msgstr "" +msgstr "Permitir certificados autofirmados" #: assets/utils/providers/forms/EppConnectorForm.tsx:202 msgid "Domain configuration" -msgstr "" +msgstr "Configuración del dominio" #: assets/utils/providers/forms/EppConnectorForm.tsx:204 msgid "Registration period" -msgstr "" +msgstr "Período de inscripción" #: assets/utils/providers/forms/EppConnectorForm.tsx:217 msgid "Year" -msgstr "" +msgstr "Año" #: assets/utils/providers/forms/EppConnectorForm.tsx:218 msgid "Month" -msgstr "" +msgstr "Mes" #: assets/utils/providers/forms/EppConnectorForm.tsx:225 msgid "Auth-Info Code" -msgstr "" +msgstr "Código de autorización" #: assets/utils/providers/forms/EppConnectorForm.tsx:233 msgid "NIC Handle" -msgstr "" +msgstr "Identificador NIC" #: assets/utils/providers/forms/EppConnectorForm.tsx:261 msgid "Onsite" -msgstr "" +msgstr "In situ" #: assets/utils/providers/forms/EppConnectorForm.tsx:273 msgid "Protocol configuration" -msgstr "" +msgstr "Configuración del protocolo" #: assets/utils/providers/forms/EppConnectorForm.tsx:274 msgid "Services" -msgstr "" +msgstr "Servicios" #: assets/utils/providers/forms/EppConnectorForm.tsx:280 msgid "Extensions" -msgstr "" +msgstr "Extensiones" #: assets/utils/providers/forms/GandiConnectorForm.tsx:10 msgid "Personal Access Token (PAT)" -msgstr "" +msgstr "Token de acceso personal (PAT)" #: assets/utils/providers/forms/GandiConnectorForm.tsx:13 msgid "" "Retrieve a Personal Access Token from your customer account on the " "Provider's website" msgstr "" +"Recupera un token de acceso personal desde tu cuenta de cliente en el sitio " +"web del proveedor" #: assets/utils/providers/forms/GandiConnectorForm.tsx:20 msgid "Organization sharing ID" -msgstr "" +msgstr "ID de la organización" #: assets/utils/providers/forms/GandiConnectorForm.tsx:24 msgid "It indicates the organization that will pay for the ordered product" -msgstr "" +msgstr "Indica la organización que pagará por el producto pedido" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:13 msgid "" "Retrieve an API key and whitelist this instance's IP address on Namecheap's " "website" msgstr "" +"Obtén una clave API y agrega la dirección IP de esta instancia a la lista " +"blanca en el sitio web de Namecheap" #: assets/utils/providers/forms/NamecheapConnectorForm.tsx:19 #: assets/utils/providers/forms/NamecomConnectorForm.tsx:25 msgid "API key" -msgstr "" +msgstr "Clave API" #: assets/utils/providers/forms/NamecomConnectorForm.tsx:19 #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:42 @@ -1471,63 +1702,69 @@ msgid "" "Retrieve a set of tokens from your customer account on the Provider's " "website" msgstr "" +"Recupera un conjunto de tokens de tu cuenta de cliente en el sitio web del " +"proveedor" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:15 msgid "European Region" -msgstr "" +msgstr "Región Europea" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:16 msgid "United States Region" -msgstr "" +msgstr "Región de Estados Unidos" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:17 msgid "Canada Region" -msgstr "" +msgstr "Región de Canadá" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:22 msgid "Europe" -msgstr "" +msgstr "Europa" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:25 msgid "The domain is free and at the standard price" -msgstr "" +msgstr "El nombre de dominio está disponible al precio estándar" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:28 msgid "" "The domain is free but can be premium. Its price varies from one domain to " "another" msgstr "" +"El dominio está disponible, pero puede ser de pago. Su precio varía de un " +"dominio a otro" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:35 msgid "Application key" -msgstr "" +msgstr "Clave de aplicación" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:49 msgid "Application secret" -msgstr "" +msgstr "Secreto de la aplicación" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:57 msgid "Consumer key" -msgstr "" +msgstr "Clave del consumidor" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:65 msgid "OVH Endpoint" -msgstr "" +msgstr "Punto final de OVH" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:72 msgid "OVH subsidiary" -msgstr "" +msgstr "Filial de OVH" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:80 msgid "OVH pricing mode" -msgstr "" +msgstr "Modo de tarificación de OVH" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:85 msgid "Confirm pricing mode" -msgstr "" +msgstr "Confirmar modo de tarificación" #: assets/utils/providers/forms/OvhCloudConnectorForm.tsx:86 msgid "" "Are you sure about this setting? This may result in additional charges from " "the API Provider" msgstr "" +"¿Estás seguro de esta configuración? Esto podría generar cargos adicionales " +"por parte del proveedor de la API" From 7b0b95bdcd87d4ac20099730fc22c6d6f88d8a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 21:33:23 +0100 Subject: [PATCH 127/131] docs: update documentation --- README.md | 2 +- .../{add-provider.mdx => implementing-new-provider.mdx} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/src/content/docs/en/developing/{add-provider.mdx => implementing-new-provider.mdx} (99%) diff --git a/README.md b/README.md index c0c1f2b..3abd205 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ By default, the container listens on http://localhost:8080, but you can configur See [the documentation](https://domainwatchdog.eu) for information on setting up a development environment and making your contributions. -To add a new provider, a [dedicated page](https://domainwatchdog.eu/en/developing/add-provider/) is available. +To add a new provider, a [dedicated page](https://domainwatchdog.eu/en/developing/implementing-new-provider/) is available. ## Security diff --git a/docs/src/content/docs/en/developing/add-provider.mdx b/docs/src/content/docs/en/developing/implementing-new-provider.mdx similarity index 99% rename from docs/src/content/docs/en/developing/add-provider.mdx rename to docs/src/content/docs/en/developing/implementing-new-provider.mdx index 4b3a2ae..2de8051 100644 --- a/docs/src/content/docs/en/developing/add-provider.mdx +++ b/docs/src/content/docs/en/developing/implementing-new-provider.mdx @@ -1,5 +1,5 @@ --- -title: Add a Provider +title: Implementing a new provider description: Step-by-step guide to adding a new Provider, with backend, frontend, and testing instructions to integrate a registrar into the project. --- import {FileTree, Steps, Code, LinkCard} from "@astrojs/starlight/components"; From 63b3d41596725040dd5d502222a19562a3e1e551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 21:33:34 +0100 Subject: [PATCH 128/131] docs: hide credit title Co-authored-by: vinceh121 --- docs/astro.config.mjs | 5 ++++- docs/src/styles/index.css | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/src/styles/index.css diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 5a967d7..d2de2de 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -47,7 +47,7 @@ export default defineConfig({ label: 'Developing', items: [ {slug: 'developing/technical-stack'}, - {slug: 'developing/add-provider'}, + {slug: 'developing/implementing-new-provider'}, {slug: 'developing/translation'}, {label: 'Contributing', autogenerate: {directory: 'developing/contributing'}} ], @@ -125,6 +125,9 @@ _paq.push(['enableHeartBeatTimer']); }, showImage: false }) + ], + customCss: [ + './src/styles/index.css' ] }), mermaid() diff --git a/docs/src/styles/index.css b/docs/src/styles/index.css new file mode 100644 index 0000000..9c32cf9 --- /dev/null +++ b/docs/src/styles/index.css @@ -0,0 +1,3 @@ +.starlight-cooler-credit-aside h2 { + display: none; +} \ No newline at end of file From 11ab26817bfa3ee9592226eb657ab5d43245bc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 20:48:57 +0000 Subject: [PATCH 129/131] Translated using Weblate (Spanish) Currently translated at 100.0% (302 of 302 strings) --- translations/es.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/translations/es.po b/translations/es.po index be80102..240eb4a 100644 --- a/translations/es.po +++ b/translations/es.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2025-11-16 15:14+0000\n" +"PO-Revision-Date: 2025-11-16 20:49+0000\n" "Last-Translator: Maël Gangloff \n" "Language-Team: Spanish \n" @@ -747,12 +747,12 @@ msgid "" msgstr "" "La IANA proporciona la lista de TLD actualmente activos, independientemente " "de su tipo, e ICANN proporciona la lista de gTLD.\n" -" En la mayoría de los casos, el ccTLD de dos letras asignado a un país se " +"En la mayoría de los casos, el ccTLD de dos letras asignado a un país se " "crea de acuerdo con la norma ISO 3166-1.\n" -" Estos datos se actualizan mensualmente. Se necesitan tres solicitudes HTTP " +"Estos datos se actualizan mensualmente. Se necesitan tres solicitudes HTTP " "para la actualización completa de los TLD en Domain Watchdog " "(dos solicitudes a IANA y una a ICANN).\n" -" Al mismo tiempo, se actualiza la lista de servidores RDAP raíz." +"Al mismo tiempo, se actualiza la lista de servidores RDAP raíz." #: assets/pages/infrastructure/TldPage.tsx:169 msgid "Generic Top-Level-Domains" @@ -780,7 +780,7 @@ msgstr "Lo sentimos, la página que intentó visitar no existe." #: assets/pages/search/DomainSearchPage.tsx:36 msgid "Found !" -msgstr "Encontró !" +msgstr "¡Encontrado!" #: assets/pages/search/DomainSearchPage.tsx:53 #, javascript-format From 5fe3f1cbcad1c62d37305e1bb1657a6e393742f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 22:10:00 +0100 Subject: [PATCH 130/131] ci: update publish-docs.yml --- .github/workflows/publish-docs.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 84b9df8..713d342 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -14,7 +14,9 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v4 + uses: actions/checkout@v5 + with: + fetch-depth: 0 - name: Setup Node uses: actions/setup-node@v4 From 34a6db438620165eee0534b80790f55058909dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gangloff?= Date: Sun, 16 Nov 2025 22:13:39 +0100 Subject: [PATCH 131/131] docs: rename to mdx files --- .../contributing/{code-of-conduct.md => code-of-conduct.mdx} | 0 .../contributing/{pull-requests.md => pull-requests.mdx} | 0 .../en/features/search/{domain-search.md => domain-search.mdx} | 0 .../search/{icann-registrar-list.md => icann-registrar-list.mdx} | 0 .../content/docs/en/features/search/{tld-list.md => tld-list.mdx} | 0 .../features/tracking/{tracking-table.md => tracking-table.mdx} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename docs/src/content/docs/en/developing/contributing/{code-of-conduct.md => code-of-conduct.mdx} (100%) rename docs/src/content/docs/en/developing/contributing/{pull-requests.md => pull-requests.mdx} (100%) rename docs/src/content/docs/en/features/search/{domain-search.md => domain-search.mdx} (100%) rename docs/src/content/docs/en/features/search/{icann-registrar-list.md => icann-registrar-list.mdx} (100%) rename docs/src/content/docs/en/features/search/{tld-list.md => tld-list.mdx} (100%) rename docs/src/content/docs/en/features/tracking/{tracking-table.md => tracking-table.mdx} (100%) diff --git a/docs/src/content/docs/en/developing/contributing/code-of-conduct.md b/docs/src/content/docs/en/developing/contributing/code-of-conduct.mdx similarity index 100% rename from docs/src/content/docs/en/developing/contributing/code-of-conduct.md rename to docs/src/content/docs/en/developing/contributing/code-of-conduct.mdx diff --git a/docs/src/content/docs/en/developing/contributing/pull-requests.md b/docs/src/content/docs/en/developing/contributing/pull-requests.mdx similarity index 100% rename from docs/src/content/docs/en/developing/contributing/pull-requests.md rename to docs/src/content/docs/en/developing/contributing/pull-requests.mdx diff --git a/docs/src/content/docs/en/features/search/domain-search.md b/docs/src/content/docs/en/features/search/domain-search.mdx similarity index 100% rename from docs/src/content/docs/en/features/search/domain-search.md rename to docs/src/content/docs/en/features/search/domain-search.mdx diff --git a/docs/src/content/docs/en/features/search/icann-registrar-list.md b/docs/src/content/docs/en/features/search/icann-registrar-list.mdx similarity index 100% rename from docs/src/content/docs/en/features/search/icann-registrar-list.md rename to docs/src/content/docs/en/features/search/icann-registrar-list.mdx diff --git a/docs/src/content/docs/en/features/search/tld-list.md b/docs/src/content/docs/en/features/search/tld-list.mdx similarity index 100% rename from docs/src/content/docs/en/features/search/tld-list.md rename to docs/src/content/docs/en/features/search/tld-list.mdx diff --git a/docs/src/content/docs/en/features/tracking/tracking-table.md b/docs/src/content/docs/en/features/tracking/tracking-table.mdx similarity index 100% rename from docs/src/content/docs/en/features/tracking/tracking-table.md rename to docs/src/content/docs/en/features/tracking/tracking-table.mdx