From f2da39b5941144141556886f2bd1fe14de876b8d Mon Sep 17 00:00:00 2001 From: ilias Date: Thu, 14 Nov 2024 16:02:45 +0100 Subject: [PATCH 1/4] architecture added --- architecture/architecture.md | 66 ++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/architecture/architecture.md b/architecture/architecture.md index 558a6a42a..d059a1a7b 100644 --- a/architecture/architecture.md +++ b/architecture/architecture.md @@ -1,7 +1,67 @@ # Architecture -:heavy_check_mark:_(COMMENT) Add a description of the architecture of your application and create a diagram like the one below. Link to the diagram in this document._ -![eShopOnContainers Architecture](https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/media/eshoponcontainers-development-architecture.png) -[Source](https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/introduce-eshoponcontainers-reference-app) \ No newline at end of file +User (Gebruiker) +Rol: Een gebruiker met specifieke acties zoals het bekijken van gepubliceerde berichten, filteren op basis van specificaties, reageren op berichten, en beheren van eigen reacties. +Relatie: Gebruikt de Single Page Application (SPA) om toegang te krijgen tot deze functies. + +Editor (Redacteur) +Rol: Een redacteur kan nieuwe berichten maken, berichten opslaan als concept, berichten wijzigen, en opmerkingen plaatsen bij afgewezen berichten. +Relatie: Heeft interactie met de SPA om berichten te beheren en krijgt meldingen bij goedkeuring of afwijzing van berichten. + +Chief Editor (Hoofdredacteur) +Rol: Kan berichten goedkeuren of afwijzen en opmerkingen plaatsen bij afgewezen berichten. +Relatie: Gebruikt de SPA voor het uitvoeren van goedkeurings- en afwijzingsacties. + + +Single Page Application (SPA) +Rol: Biedt de functionaliteit van de applicatie in een webbrowser en stelt gebruikers in staat om berichten te bekijken, bewerken, goedkeuren, en op reacties te reageren. +Relatie: Maakt API-aanroepen naar de PostService API, ReviewService API, en CommentService API voor het uitvoeren van verschillende acties. Verzendt en ontvangt berichten van de Open-Feign browser voor communicatie met andere microservices. + +Open-Feign Browser +Rol: Een REST-client die gebruikmaakt van load balancing (via Ribbon) voor communicatie met andere microservices. +Relatie: Publiceert en ontvangt berichten via HTTP om te communiceren met de andere API's in het systeem. +Services en API's +PostService + +PostService API +Rol: Verantwoordelijk voor de functionaliteit van het beheren van berichten. +Relatie: Verbindt met de PostService Database om berichten op te slaan en te lezen via SQL. Maakt gebruik van RabbitMQ Container voor het publiceren en consumeren van berichten met andere services. +PostService Database +Rol: Opslagplaats voor berichten. +Relatie: Wordt aangesproken door de PostService API voor lezen en schrijven van gegevens. +ReviewService + +ReviewService API +Rol: Beheert de functionaliteit rondom beoordelingen van berichten (goedkeuring of afwijzing). +Relatie: Verbindt met de ReviewService Database voor lezen en schrijven van beoordelingen via SQL. Communiceert met andere services via RabbitMQ Container voor berichtenuitwisseling. +ReviewService Database +Rol: Opslagplaats voor beoordelingen. +Relatie: Wordt aangesproken door de ReviewService API voor het lezen en schrijven van beoordelingen. +CommentService + +CommentService API +Rol: Beheert de functionaliteit voor opmerkingen op berichten. +Relatie: Verbindt met de CommentService Database om reacties op te slaan en op te halen via SQL. Communiceert via RabbitMQ Container met andere services voor berichtenuitwisseling. +CommentService Database +Rol: Opslagplaats voor opmerkingen. +Relatie: Wordt aangesproken door de CommentService API voor het lezen en schrijven van reacties. + +RabbitMQ Container +Rol: Biedt berichtgeving en asynchrone communicatie tussen verschillende microservices (AMQP). +Relatie: Wordt gebruikt door de PostService, ReviewService, en CommentService voor het publiceren en consumeren van berichten tussen services. + +Config Service +Rol: Een centrale configuratieservice voor alle application.properties van de microservices. Het zorgt ervoor dat alle microservices toegang hebben tot een gedeelde configuratiebron, wat het beheer van configuraties vereenvoudigt. Dit maakt het gemakkelijker om configuratie-instellingen centraal aan te passen zonder elk component afzonderlijk te hoeven bijwerken. +Relatie: Alle microservices kunnen verbinding maken met de Config Service om hun configuratie-instellingen op te halen. Dit zorgt voor consistentie en centralisatie van de configuraties over het hele systeem. + +Discovery Service +Rol: Verantwoordelijk voor service-registratie en -ontdekking, wat essentieel is voor dynamische microservices-architecturen. Alle microservices registreren zichzelf bij de Discovery Service. Hierdoor kan elke service andere services in het systeem ontdekken en op basis daarvan communiceren, zonder afhankelijk te zijn van harde URL’s of IP-adressen. +Relatie: Alle microservices melden zich aan bij de Discovery Service, die dient als een directory of registry. Wanneer een service communicatie met een andere service wil opzetten, kan het via de Discovery Service de locatie en status van die service vinden. + +Relaties en Interactie +API-aanroepen: De SPA maakt HTTP-aanroepen naar de verschillende service API’s (PostService API, ReviewService API, en CommentService API) voor toegang tot respectievelijke functionaliteiten. +Messaging/Communicatie: De RabbitMQ Container fungeert als een tussenlaag voor berichtenuitwisseling tussen de microservices, waardoor asynchrone communicatie mogelijk is. Dit stelt de services in staat om berichten te publiceren en te consumeren zonder directe afhankelijkheden. +Data Opslag: Elke service heeft een eigen SQL-database voor het opslaan van zijn specifieke gegevens (berichten, beoordelingen, reacties). De API’s van elke service beheren de toegang tot hun respectievelijke databases. + From c5636584bc96963c6c95037838286d62c10cc143 Mon Sep 17 00:00:00 2001 From: ilias Date: Thu, 14 Nov 2024 16:27:41 +0100 Subject: [PATCH 2/4] update architecture na feedback --- architecture/architecture.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/architecture/architecture.md b/architecture/architecture.md index d059a1a7b..5d303458d 100644 --- a/architecture/architecture.md +++ b/architecture/architecture.md @@ -7,14 +7,9 @@ Rol: Een gebruiker met specifieke acties zoals het bekijken van gepubliceerde be Relatie: Gebruikt de Single Page Application (SPA) om toegang te krijgen tot deze functies. Editor (Redacteur) -Rol: Een redacteur kan nieuwe berichten maken, berichten opslaan als concept, berichten wijzigen, en opmerkingen plaatsen bij afgewezen berichten. +Rol: Een redacteur kan nieuwe berichten maken, berichten opslaan als concept, berichten wijzigen, en opmerkingen plaatsen bij afgewezen berichten, kan berichten goedkeuren of afwijzen en opmerkingen plaatsen bij afgewezen berichten.. Relatie: Heeft interactie met de SPA om berichten te beheren en krijgt meldingen bij goedkeuring of afwijzing van berichten. -Chief Editor (Hoofdredacteur) -Rol: Kan berichten goedkeuren of afwijzen en opmerkingen plaatsen bij afgewezen berichten. -Relatie: Gebruikt de SPA voor het uitvoeren van goedkeurings- en afwijzingsacties. - - Single Page Application (SPA) Rol: Biedt de functionaliteit van de applicatie in een webbrowser en stelt gebruikers in staat om berichten te bekijken, bewerken, goedkeuren, en op reacties te reageren. Relatie: Maakt API-aanroepen naar de PostService API, ReviewService API, en CommentService API voor het uitvoeren van verschillende acties. Verzendt en ontvangt berichten van de Open-Feign browser voor communicatie met andere microservices. From badf627ad37b6e5307730701d00511be139bf241 Mon Sep 17 00:00:00 2001 From: ilias Date: Fri, 22 Nov 2024 17:12:38 +0100 Subject: [PATCH 3/4] Startup project en postservice backend start --- architecture/.$C4-.net.drawio.bkp | 366 ++++++++++++++++++ architecture/.$C4-java.drawio.bkp | 296 ++++++++++++++ architecture/C4-java.drawio | 321 +++++++++++++++ architecture/C4-java.drawio.png | Bin 0 -> 337647 bytes backend-java/Microservices/.gitattributes | 2 + backend-java/Microservices/.gitignore | 33 ++ .../.mvn/wrapper/maven-wrapper.properties | 19 + .../Microservices/CommentService/pom.xml | 46 +++ .../services/CommentServiceApplication.java | 19 + .../src/main/resources/application.properties | 5 + .../CommentServiceApplicationTest.java | 38 ++ .../Microservices/ConfigService/pom.xml | 34 ++ .../services/ConfigServiceApplication.java | 21 + .../src/main/resources/application.properties | 4 + .../config/comment-service.properties | 11 + .../config/discovery-service.properties | 9 + .../resources/config/post-service.properties | 11 + .../config/review-service.properties | 11 + .../ConfigServiceApplicationTest.java | 38 ++ .../Microservices/DiscoveryService/pom.xml | 36 ++ .../services/DiscoveryServiceApplication.java | 19 + .../src/main/resources/application.properties | 5 + .../test/java/be/pxl/services/AppTest.java | 38 ++ .../Microservices/PostService/pom.xml | 46 +++ .../pxl/services/PostServiceApplication.java | 19 + .../services/controller/PostController.java | 55 +++ .../controller/request/PostRequest.java | 6 + .../java/be/pxl/services/domain/Post.java | 26 ++ .../services/repository/PostRepository.java | 17 + .../be/pxl/services/service/IPostService.java | 19 + .../be/pxl/services/service/PostService.java | 77 ++++ .../src/main/resources/application.properties | 5 + .../services/PostServiceApplicationTest.java | 38 ++ .../Microservices/ReviewService/pom.xml | 46 +++ .../services/ReviewServiceApplication.java | 19 + .../src/main/resources/application.properties | 5 + .../ReviewServiceApplicationTest.java | 38 ++ backend-java/Microservices/docker-compose.yml | 56 +++ backend-java/Microservices/mvnw | 259 +++++++++++++ backend-java/Microservices/mvnw.cmd | 149 +++++++ backend-java/Microservices/pom.xml | 104 +++++ .../services/MicroservicesApplication.java | 13 + .../src/main/resources/application.properties | 1 + .../MicroservicesApplicationTests.java | 13 + 44 files changed, 2393 insertions(+) create mode 100644 architecture/.$C4-.net.drawio.bkp create mode 100644 architecture/.$C4-java.drawio.bkp create mode 100644 architecture/C4-java.drawio create mode 100644 architecture/C4-java.drawio.png create mode 100644 backend-java/Microservices/.gitattributes create mode 100644 backend-java/Microservices/.gitignore create mode 100644 backend-java/Microservices/.mvn/wrapper/maven-wrapper.properties create mode 100644 backend-java/Microservices/CommentService/pom.xml create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java create mode 100644 backend-java/Microservices/CommentService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java create mode 100644 backend-java/Microservices/ConfigService/pom.xml create mode 100644 backend-java/Microservices/ConfigService/src/main/java/be/pxl/services/ConfigServiceApplication.java create mode 100644 backend-java/Microservices/ConfigService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties create mode 100644 backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties create mode 100644 backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties create mode 100644 backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties create mode 100644 backend-java/Microservices/ConfigService/src/test/java/be/pxl/services/ConfigServiceApplicationTest.java create mode 100644 backend-java/Microservices/DiscoveryService/pom.xml create mode 100644 backend-java/Microservices/DiscoveryService/src/main/java/be/pxl/services/DiscoveryServiceApplication.java create mode 100644 backend-java/Microservices/DiscoveryService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/DiscoveryService/src/test/java/be/pxl/services/AppTest.java create mode 100644 backend-java/Microservices/PostService/pom.xml create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/repository/PostRepository.java create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java create mode 100644 backend-java/Microservices/PostService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java create mode 100644 backend-java/Microservices/ReviewService/pom.xml create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java create mode 100644 backend-java/Microservices/ReviewService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java create mode 100644 backend-java/Microservices/docker-compose.yml create mode 100644 backend-java/Microservices/mvnw create mode 100644 backend-java/Microservices/mvnw.cmd create mode 100644 backend-java/Microservices/pom.xml create mode 100644 backend-java/Microservices/src/main/java/be/pxl/services/MicroservicesApplication.java create mode 100644 backend-java/Microservices/src/main/resources/application.properties create mode 100644 backend-java/Microservices/src/test/java/be/pxl/services/MicroservicesApplicationTests.java diff --git a/architecture/.$C4-.net.drawio.bkp b/architecture/.$C4-.net.drawio.bkp new file mode 100644 index 000000000..7d672a309 --- /dev/null +++ b/architecture/.$C4-.net.drawio.bkp @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/.$C4-java.drawio.bkp b/architecture/.$C4-java.drawio.bkp new file mode 100644 index 000000000..9291df603 --- /dev/null +++ b/architecture/.$C4-java.drawio.bkp @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/C4-java.drawio b/architecture/C4-java.drawio new file mode 100644 index 000000000..0b9cda297 --- /dev/null +++ b/architecture/C4-java.drawio @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/architecture/C4-java.drawio.png b/architecture/C4-java.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..ebdfdc16fcef56856c9f210a08a1c80a5fb6ed51 GIT binary patch literal 337647 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%0A^`Yv74 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

LG7Nt`T0!uYpQe#;~V-&{T;f+SuqGXB=Zo{(4 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 + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + CommentService + jar + + CommentService + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-config + + + + diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java new file mode 100644 index 000000000..20c5156ee --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java @@ -0,0 +1,19 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * Hello world! + * + */ +@SpringBootApplication +@EnableDiscoveryClient +public class CommentServiceApplication +{ + public static void main( String[] args ) + { + SpringApplication.run(CommentServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/CommentService/src/main/resources/application.properties b/backend-java/Microservices/CommentService/src/main/resources/application.properties new file mode 100644 index 000000000..2cb18d70a --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/resources/application.properties @@ -0,0 +1,5 @@ + + +spring.application.name=comment-service +spring.config.import=optional:configserver:${CONFIG_SERVER_URL:http://localhost:8088/} + diff --git a/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java new file mode 100644 index 000000000..cfd331ca4 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java @@ -0,0 +1,38 @@ +package be.pxl.services; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class CommentServiceApplicationTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public CommentServiceApplicationTest(String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( CommentServiceApplicationTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/backend-java/Microservices/ConfigService/pom.xml b/backend-java/Microservices/ConfigService/pom.xml new file mode 100644 index 000000000..165e3fecb --- /dev/null +++ b/backend-java/Microservices/ConfigService/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + ConfigService + jar + + ConfigService + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + org.springframework.cloud + spring-cloud-config-server + + + + diff --git a/backend-java/Microservices/ConfigService/src/main/java/be/pxl/services/ConfigServiceApplication.java b/backend-java/Microservices/ConfigService/src/main/java/be/pxl/services/ConfigServiceApplication.java new file mode 100644 index 000000000..48328f1c6 --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/main/java/be/pxl/services/ConfigServiceApplication.java @@ -0,0 +1,21 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +import javax.swing.*; + +/** + * Hello world! + * + */ +@SpringBootApplication +@EnableConfigServer +public class ConfigServiceApplication +{ + public static void main( String[] args ) + { + SpringApplication.run(ConfigServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/ConfigService/src/main/resources/application.properties b/backend-java/Microservices/ConfigService/src/main/resources/application.properties new file mode 100644 index 000000000..5886557de --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port=8088 +spring.application.name=config-service +spring.profiles.active=native +spring.cloud.config.server.native.search-locations=classpath:/config, classpath:/common \ No newline at end of file diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties new file mode 100644 index 000000000..c6f3dc2d7 --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties @@ -0,0 +1,11 @@ +server.port=8082 +spring.datasource.url=jdbc:mysql://localhost:3308/commentservice_db +spring.datasource.username=root +spring.datasource.password=password +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.hibernate.ddl-auto=update + +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect +spring.cloud.compatibility-verifier.enabled=false +eureka.client.service-url.defaultZone=http://localhost:8061/eureka/ +spring.config.import-check.enabled=false \ No newline at end of file diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties new file mode 100644 index 000000000..3af71a1a2 --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties @@ -0,0 +1,9 @@ +server.port=8061 +spring.cloud.compatibility-verifier.enabled=false +eureka.instance.hostname=localhost +eureka.client.register-with-eureka=false +eureka.client.fetch-registry=false +#eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/ + +# application.properties +eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ \ No newline at end of file diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties new file mode 100644 index 000000000..c202e618c --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties @@ -0,0 +1,11 @@ +server.port=8080 +spring.datasource.url=jdbc:mysql://localhost:3306/postservice_db +spring.datasource.username=root +spring.datasource.password=password +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.hibernate.ddl-auto=update + +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect +spring.cloud.compatibility-verifier.enabled=false +eureka.client.service-url.defaultZone=http://localhost:8061/eureka/ +spring.config.import-check.enabled=false \ No newline at end of file diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties new file mode 100644 index 000000000..8b66293e1 --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties @@ -0,0 +1,11 @@ +server.port=8081 +spring.datasource.url=jdbc:mysql://localhost:3307/reviewservice_db +spring.datasource.username=root +spring.datasource.password=password +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.hibernate.ddl-auto=update + +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect +spring.cloud.compatibility-verifier.enabled=false +eureka.client.service-url.defaultZone=http://localhost:8061/eureka/ +spring.config.import-check.enabled=false \ No newline at end of file diff --git a/backend-java/Microservices/ConfigService/src/test/java/be/pxl/services/ConfigServiceApplicationTest.java b/backend-java/Microservices/ConfigService/src/test/java/be/pxl/services/ConfigServiceApplicationTest.java new file mode 100644 index 000000000..cc55a48ba --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/test/java/be/pxl/services/ConfigServiceApplicationTest.java @@ -0,0 +1,38 @@ +package be.pxl.services; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class ConfigServiceApplicationTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public ConfigServiceApplicationTest(String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( ConfigServiceApplicationTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/backend-java/Microservices/DiscoveryService/pom.xml b/backend-java/Microservices/DiscoveryService/pom.xml new file mode 100644 index 000000000..d9ff7f202 --- /dev/null +++ b/backend-java/Microservices/DiscoveryService/pom.xml @@ -0,0 +1,36 @@ + + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + DiscoveryService + jar + + DiscoveryService + http://maven.apache.org + + + UTF-8 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-server + + + org.springframework.cloud + spring-cloud-starter-config + + + + diff --git a/backend-java/Microservices/DiscoveryService/src/main/java/be/pxl/services/DiscoveryServiceApplication.java b/backend-java/Microservices/DiscoveryService/src/main/java/be/pxl/services/DiscoveryServiceApplication.java new file mode 100644 index 000000000..2b35de5dc --- /dev/null +++ b/backend-java/Microservices/DiscoveryService/src/main/java/be/pxl/services/DiscoveryServiceApplication.java @@ -0,0 +1,19 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; + +/** + * Hello world! + * + */ +@SpringBootApplication +@EnableEurekaServer +public class DiscoveryServiceApplication +{ + public static void main( String[] args ) + { + SpringApplication.run(DiscoveryServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/DiscoveryService/src/main/resources/application.properties b/backend-java/Microservices/DiscoveryService/src/main/resources/application.properties new file mode 100644 index 000000000..dc28f7cfd --- /dev/null +++ b/backend-java/Microservices/DiscoveryService/src/main/resources/application.properties @@ -0,0 +1,5 @@ + + +spring.application.name=discovery-service +spring.config.import=optional:configserver:${CONFIG_SERVER_URL:http://localhost:8088} + diff --git a/backend-java/Microservices/DiscoveryService/src/test/java/be/pxl/services/AppTest.java b/backend-java/Microservices/DiscoveryService/src/test/java/be/pxl/services/AppTest.java new file mode 100644 index 000000000..e87772ee6 --- /dev/null +++ b/backend-java/Microservices/DiscoveryService/src/test/java/be/pxl/services/AppTest.java @@ -0,0 +1,38 @@ +package be.pxl.services; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/backend-java/Microservices/PostService/pom.xml b/backend-java/Microservices/PostService/pom.xml new file mode 100644 index 000000000..db658e4ff --- /dev/null +++ b/backend-java/Microservices/PostService/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + PostService + jar + + PostService + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-config + + + + diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java new file mode 100644 index 000000000..02fc1b39a --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java @@ -0,0 +1,19 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * Hello world! + * + */ +@SpringBootApplication +@EnableDiscoveryClient +public class PostServiceApplication +{ + public static void main( String[] args ) + { + SpringApplication.run(PostServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java new file mode 100644 index 000000000..14e562110 --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java @@ -0,0 +1,55 @@ +package be.pxl.services.controller; + +import be.pxl.services.controller.request.PostRequest; +import be.pxl.services.domain.Post; +import be.pxl.services.service.PostService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/posts") +@CrossOrigin(origins = "http://localhost:4200") +@RequiredArgsConstructor +public class PostController { + private final PostService postService; + + @GetMapping + public ResponseEntity> getAllPosts() { + List posts = postService.getAllPosts(); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @GetMapping("/concept") + public ResponseEntity> getConceptPosts() { + List posts = postService.getConceptPosts(); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @GetMapping("/published") + public ResponseEntity> getPublishedPosts() { + List posts = postService.getPublishedPosts(); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @PostMapping + public ResponseEntity addPost(@RequestBody PostRequest postRequest) { + Post newPost = postService.addPost(postRequest); + return new ResponseEntity<>(newPost, HttpStatus.CREATED); + } + + @GetMapping("/findByTitle") + public ResponseEntity getPostByTitle(@RequestParam String title) { + Post post = postService.findPostByTitle(title); + return new ResponseEntity<>(post, HttpStatus.OK); + } + + @PostMapping("/update/{id}") + public ResponseEntity updatePost(@PathVariable Long id, @RequestBody PostRequest postRequest) { + postService.updatePost(id, postRequest); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java new file mode 100644 index 000000000..95aaba5bd --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java @@ -0,0 +1,6 @@ +package be.pxl.services.controller.request; + +import java.util.Date; + +public record PostRequest (String author, Date date, String title, String content) { +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java new file mode 100644 index 000000000..e538a4493 --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java @@ -0,0 +1,26 @@ +package be.pxl.services.domain; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Entity +@Table(name = "posts") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Post { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String author; + private Date date; + private String title; + private String content; + private boolean concept; +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/repository/PostRepository.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/repository/PostRepository.java new file mode 100644 index 000000000..c1dffa2f0 --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/repository/PostRepository.java @@ -0,0 +1,17 @@ +package be.pxl.services.repository; + +import be.pxl.services.domain.Post; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +@Repository +public interface PostRepository extends JpaRepository { + Optional findByTitle(String title); + Optional findByContent(String content); + Optional findByAuthor(String author); + Optional findByDate(Date date); +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java new file mode 100644 index 000000000..90aa47b94 --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java @@ -0,0 +1,19 @@ +package be.pxl.services.service; + +import be.pxl.services.controller.request.PostRequest; +import be.pxl.services.domain.Post; + +import java.util.Date; +import java.util.List; + +public interface IPostService { + List getAllPosts(); + List getConceptPosts(); + List getPublishedPosts(); + Post findPostByTitle(String title); + Post findPostByContent(String content); + Post findPostByAuthor(String author); + Post findPostByDate(Date date); + Post addPost(PostRequest postRequest); + void updatePost(Long id, PostRequest postRequest); +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java new file mode 100644 index 000000000..79364f0de --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java @@ -0,0 +1,77 @@ +package be.pxl.services.service; + +import be.pxl.services.controller.request.PostRequest; +import be.pxl.services.domain.Post; +import be.pxl.services.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class PostService implements IPostService{ + private final PostRepository postRepository; + + @Override + public List getAllPosts() { + return postRepository.findAll(); + } + + @Override + public List getConceptPosts() { + return postRepository.findAll().stream().filter(Post::isConcept).toList(); + } + + @Override + public List getPublishedPosts() { + return postRepository.findAll().stream().filter(post -> !post.isConcept()).toList(); + } + + @Override + public Post findPostByTitle(String title) { + return postRepository.findByTitle(title).orElse(null); + } + + @Override + public Post findPostByContent(String content) { + return postRepository.findByContent(content).orElse(null); + } + + @Override + public Post findPostByAuthor(String author) { + return postRepository.findByAuthor(author).orElse(null); + } + + @Override + public Post findPostByDate(Date date) { + return postRepository.findByDate(date).orElse(null); + } + + @Override + public Post addPost(PostRequest postRequest){ + Post post = new Post(); + BeanUtils.copyProperties(postRequest, post); + post.setConcept(true); + postRepository.save(post); + return post; + } + + @Override + public void updatePost(Long id, PostRequest postRequest) { + Optional post = postRepository.findById(id); + if(post.isPresent()){ + if(postRequest.title() != null){ + post.get().setTitle(postRequest.title()); + } + if (postRequest.content() != null){ + post.get().setContent(postRequest.content()); + } + Post updatedPost = post.get(); + postRepository.save(updatedPost); + } + } +} diff --git a/backend-java/Microservices/PostService/src/main/resources/application.properties b/backend-java/Microservices/PostService/src/main/resources/application.properties new file mode 100644 index 000000000..6fabba59b --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/resources/application.properties @@ -0,0 +1,5 @@ + + +spring.application.name=post-service +spring.config.import=optional:configserver:${CONFIG_SERVER_URL:http://localhost:8088} + diff --git a/backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java new file mode 100644 index 000000000..eee970f52 --- /dev/null +++ b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java @@ -0,0 +1,38 @@ +package be.pxl.services; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class PostServiceApplicationTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public PostServiceApplicationTest(String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( PostServiceApplicationTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/backend-java/Microservices/ReviewService/pom.xml b/backend-java/Microservices/ReviewService/pom.xml new file mode 100644 index 000000000..280b711ed --- /dev/null +++ b/backend-java/Microservices/ReviewService/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + ReviewService + jar + + ReviewService + http://maven.apache.org + + + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-config + + + + junit + junit + 3.8.1 + test + + + org.springframework.cloud + spring-cloud-commons + + + diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java new file mode 100644 index 000000000..38bc838ad --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java @@ -0,0 +1,19 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * Hello world! + * + */ +@SpringBootApplication +@EnableDiscoveryClient +public class ReviewServiceApplication +{ + public static void main( String[] args ) + { + SpringApplication.run(ReviewServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/ReviewService/src/main/resources/application.properties b/backend-java/Microservices/ReviewService/src/main/resources/application.properties new file mode 100644 index 000000000..03f2bda9d --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/resources/application.properties @@ -0,0 +1,5 @@ + + +spring.application.name=review-service +spring.config.import=optional:configserver:${CONFIG_SERVER_URL:http://localhost:8088/} + diff --git a/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java new file mode 100644 index 000000000..086f1e2ee --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java @@ -0,0 +1,38 @@ +package be.pxl.services; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class ReviewServiceApplicationTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public ReviewServiceApplicationTest(String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( ReviewServiceApplicationTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/backend-java/Microservices/docker-compose.yml b/backend-java/Microservices/docker-compose.yml new file mode 100644 index 000000000..a620d8d63 --- /dev/null +++ b/backend-java/Microservices/docker-compose.yml @@ -0,0 +1,56 @@ +version: '3.7' + +services: + mysql-post: + image: mysql:latest + ports: + - '3306:3306' + restart: always + environment: + MYSQL_DATABASE: postservice_db + # MYSQL_USER: root + # MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: password + volumes: + - mysql-post-data:/var/lib/mysql + - ./mysql-post/init.sql:/docker-entrypoint-initdb.d/init.sql + + mysql-review: + image: mysql:latest + ports: + - '3307:3306' + restart: always + environment: + MYSQL_DATABASE: reviewservice_db + # MYSQL_USER: root + # MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: password + volumes: + - mysql-review-data:/var/lib/mysql + + mysql-comment: + image: mysql:latest + ports: + - '3308:3306' + restart: always + environment: + MYSQL_DATABASE: commentservice_db + # MYSQL_USER: root + # MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: password + volumes: + - mysql-comment-data:/var/lib/mysql + + + rabbitmq: + image: "rabbitmq:3-management-alpine" + ports: + - "5672:5672" # RabbitMQ default port + - "15672:15672" # RabbitMQ Management Console + restart: always + + +volumes: + mysql-post-data: + mysql-review-data: + mysql-comment-data: \ No newline at end of file diff --git a/backend-java/Microservices/mvnw b/backend-java/Microservices/mvnw new file mode 100644 index 000000000..19529ddf8 --- /dev/null +++ b/backend-java/Microservices/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/backend-java/Microservices/mvnw.cmd b/backend-java/Microservices/mvnw.cmd new file mode 100644 index 000000000..249bdf382 --- /dev/null +++ b/backend-java/Microservices/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/backend-java/Microservices/pom.xml b/backend-java/Microservices/pom.xml new file mode 100644 index 000000000..32da8239b --- /dev/null +++ b/backend-java/Microservices/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.6 + + + be.pxl + Microservices + 0.0.1-SNAPSHOT + pom + Microservices + Microservices + + + + + + + + + PostService + ReviewService + CommentService + DiscoveryService + ConfigService + + + + + + + + + 17 + 2023.0.3 + + + + + org.springframework.boot + spring-boot-starter-web + + + + com.mysql + mysql-connector-j + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud-version} + pom + import + + + + org.testcontainers + testcontainers-bom + 1.17.3 + pom + import + + + + + diff --git a/backend-java/Microservices/src/main/java/be/pxl/services/MicroservicesApplication.java b/backend-java/Microservices/src/main/java/be/pxl/services/MicroservicesApplication.java new file mode 100644 index 000000000..5d65768de --- /dev/null +++ b/backend-java/Microservices/src/main/java/be/pxl/services/MicroservicesApplication.java @@ -0,0 +1,13 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MicroservicesApplication { + + public static void main(String[] args) { + SpringApplication.run(MicroservicesApplication.class, args); + } + +} diff --git a/backend-java/Microservices/src/main/resources/application.properties b/backend-java/Microservices/src/main/resources/application.properties new file mode 100644 index 000000000..66b4c04b1 --- /dev/null +++ b/backend-java/Microservices/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.application.name=Microservices diff --git a/backend-java/Microservices/src/test/java/be/pxl/services/MicroservicesApplicationTests.java b/backend-java/Microservices/src/test/java/be/pxl/services/MicroservicesApplicationTests.java new file mode 100644 index 000000000..5da6fcfc1 --- /dev/null +++ b/backend-java/Microservices/src/test/java/be/pxl/services/MicroservicesApplicationTests.java @@ -0,0 +1,13 @@ +package be.pxl.services; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class MicroservicesApplicationTests { + + @Test + void contextLoads() { + } + +} From 741f35a22563a197694b74c2c584f16d0431b656 Mon Sep 17 00:00:00 2001 From: ilias Date: Sat, 11 Jan 2025 16:29:23 +0100 Subject: [PATCH 4/4] testen geschreven backend af frotnend subscribe error --- .idea/.gitignore | 8 + .idea/compiler.xml | 33 + .idea/dataSources.xml | 41 + .idea/encodings.xml | 15 + .idea/jarRepositories.xml | 20 + .idea/misc.xml | 14 + .idea/modules.xml | 9 + .idea/project-IliasAzrhari.iml | 9 + .idea/uiDesigner.xml | 124 + .idea/vcs.xml | 6 + backend-java/.idea/.gitignore | 8 + backend-java/.idea/backend-java.iml | 9 + backend-java/.idea/compiler.xml | 26 + backend-java/.idea/encodings.xml | 12 + backend-java/.idea/jarRepositories.xml | 20 + backend-java/.idea/misc.xml | 14 + backend-java/.idea/modules.xml | 8 + backend-java/.idea/vcs.xml | 6 + .../CommentService/logs/comments.log | 0 .../Microservices/CommentService/pom.xml | 22 +- .../services/CommentServiceApplication.java | 2 + .../services/client/NotificationClient.java | 13 + .../controller/CommentController.java | 54 + .../controller/request/CommentRequest.java | 4 + .../request/NotificationRequest.java | 17 + .../java/be/pxl/services/domain/Comment.java | 24 + .../repository/CommentRepository.java | 9 + .../pxl/services/services/CommentService.java | 68 + .../services/services/ICommentService.java | 15 + .../src/main/resources/logback.xml | 13 + .../CommentServiceApplicationTest.java | 34 +- .../controller/CommentControllerTest.java | 137 + .../be/pxl/services/domain/CommentTest.java | 38 + .../services/services/CommentServiceTest.java | 162 + .../src/main/resources/application.properties | 2 +- .../config/comment-service.properties | 3 +- .../config/discovery-service.properties | 3 +- .../main/resources/config/gateway-service.yml | 51 + .../resources/config/post-service.properties | 3 +- .../config/review-service.properties | 3 +- .../Microservices/GatewayService/pom.xml | 47 + .../services/GatewayServiceApplication.java | 19 + .../src/main/resources/application.properties | 3 + .../Microservices/MessagingService/pom.xml | 34 + .../services/MessagingServiceApplication.java | 17 + .../configuration/QueueConfiguration.java | 35 + .../be/pxl/services/service/QueueService.java | 23 + .../src/main/resources/application.properties | 2 + .../Microservices/NotificationService/pom.xml | 41 + .../NotificationServiceApplication.java | 20 + .../controller/NotificationController.java | 31 + .../be/pxl/services/domain/Notification.java | 15 + .../service/INotificationService.java | 8 + .../services/service/NotificationService.java | 40 + .../src/main/resources/application.properties | 12 + .../test/java/be/pxl/services/AppTest.java | 38 + .../Microservices/PostService/logs/posts.log | 0 .../Microservices/PostService/pom.xml | 25 +- .../pxl/services/PostServiceApplication.java | 2 + .../services/client/NotificationClient.java | 17 + .../services/controller/PostController.java | 57 +- .../request/NotificationRequest.java | 17 + .../controller/request/PostRequest.java | 5 +- .../java/be/pxl/services/domain/Post.java | 4 +- .../be/pxl/services/service/IPostService.java | 12 +- .../be/pxl/services/service/PostService.java | 100 +- .../src/main/resources/logback.xml | 13 + .../services/PostServiceApplicationTest.java | 35 +- .../controller/PostControllerTest.java | 252 + .../java/be/pxl/services/domain/PostTest.java | 96 + .../services/services/PostServicesTest.java | 283 + .../ReviewService/logs/reviews.log | 0 .../Microservices/ReviewService/pom.xml | 20 +- .../services/ReviewServiceApplication.java | 2 + .../services/client/NotificationClient.java | 13 + .../services/controller/ReviewController.java | 53 + .../request/NotificationRequest.java | 17 + .../controller/request/ReviewRequest.java | 4 + .../java/be/pxl/services/domain/Review.java | 22 + .../services/repository/ReviewRepository.java | 13 + .../pxl/services/service/IReviewService.java | 15 + .../pxl/services/service/ReviewService.java | 90 + .../src/main/resources/logback.xml | 13 + .../ReviewServiceApplicationTest.java | 34 +- .../controller/ReviewControllerTest.java | 120 + .../be/pxl/services/domain/ReviewTest.java | 39 + .../services/services/ReviewServiceTest.java | 132 + backend-java/Microservices/pom.xml | 6 +- .../src/main/resources/application.properties | 1 + frontend-web/.idea/.gitignore | 8 + frontend-web/.idea/frontend-web.iml | 9 + frontend-web/.idea/misc.xml | 6 + frontend-web/.idea/modules.xml | 8 + frontend-web/.idea/vcs.xml | 6 + frontend-web/Frontend/.editorconfig | 17 + frontend-web/Frontend/.gitignore | 42 + frontend-web/Frontend/.vscode/extensions.json | 4 + frontend-web/Frontend/.vscode/launch.json | 20 + frontend-web/Frontend/.vscode/tasks.json | 42 + frontend-web/Frontend/README.md | 59 + frontend-web/Frontend/angular.json | 96 + frontend-web/Frontend/package-lock.json | 15575 ++++++++++++++++ frontend-web/Frontend/package.json | 39 + frontend-web/Frontend/public/favicon.ico | Bin 0 -> 15086 bytes .../Frontend/src/app/app.component.css | 0 .../Frontend/src/app/app.component.html | 1 + .../Frontend/src/app/app.component.spec.ts | 23 + .../Frontend/src/app/app.component.ts | 13 + frontend-web/Frontend/src/app/app.config.ts | 14 + frontend-web/Frontend/src/app/app.routes.ts | 25 + .../add-comment/add-comment.component.css | 0 .../add-comment/add-comment.component.html | 23 + .../add-comment/add-comment.component.spec.ts | 73 + .../add-comment/add-comment.component.ts | 53 + .../component/add-post/add-post.component.css | 0 .../add-post/add-post.component.html | 43 + .../add-post/add-post.component.spec.ts | 78 + .../component/add-post/add-post.component.ts | 59 + .../component/comments/comments.component.css | 0 .../comments/comments.component.html | 27 + .../comments/comments.component.spec.ts | 82 + .../component/comments/comments.component.ts | 49 + .../concept-posts/concept-posts.component.css | 0 .../concept-posts.component.html | 22 + .../concept-posts.component.spec.ts | 58 + .../concept-posts/concept-posts.component.ts | 37 + .../datepicker/datepicker.component.css | 0 .../datepicker/datepicker.component.html | 142 + .../datepicker/datepicker.component.spec.ts | 55 + .../datepicker/datepicker.component.ts | 56 + .../edit-comment/edit-comment.component.css | 0 .../edit-comment/edit-comment.component.html | 23 + .../edit-comment.component.spec.ts | 103 + .../edit-comment/edit-comment.component.ts | 58 + .../edit-post/edit-post.component.css | 0 .../edit-post/edit-post.component.html | 31 + .../edit-post/edit-post.component.spec.ts | 107 + .../edit-post/edit-post.component.ts | 82 + .../app/component/login/login.component.css | 0 .../app/component/login/login.component.html | 33 + .../component/login/login.component.spec.ts | 49 + .../app/component/login/login.component.ts | 27 + .../app/component/navbar/navbar.component.css | 0 .../component/navbar/navbar.component.html | 59 + .../component/navbar/navbar.component.spec.ts | 62 + .../app/component/navbar/navbar.component.ts | 38 + .../app/component/posts/posts.component.css | 0 .../app/component/posts/posts.component.html | 34 + .../component/posts/posts.component.spec.ts | 68 + .../app/component/posts/posts.component.ts | 39 + .../review-details.component.css | 0 .../review-details.component.html | 41 + .../review-details.component.spec.ts | 92 + .../review-details.component.ts | 45 + .../review-post/review-post.component.css | 0 .../review-post/review-post.component.html | 39 + .../review-post/review-post.component.spec.ts | 103 + .../review-post/review-post.component.ts | 94 + .../searchbar/searchbar.component.css | 0 .../searchbar/searchbar.component.html | 35 + .../searchbar/searchbar.component.spec.ts | 114 + .../searchbar/searchbar.component.ts | 106 + .../src/app/services/auth.service.spec.ts | 39 + .../Frontend/src/app/services/auth.service.ts | 19 + .../src/app/services/comment.service.spec.ts | 102 + .../src/app/services/comment.service.ts | 38 + .../app/services/notification.service.spec.ts | 16 + .../src/app/services/notification.service.ts | 18 + .../src/app/services/posts.service.spec.ts | 213 + .../src/app/services/posts.service.ts | 56 + .../src/app/services/review.service.spec.ts | 67 + .../src/app/services/review.service.ts | 27 + .../app/shared/models/post/comment.model.ts | 6 + .../src/app/shared/models/post/post.model.ts | 9 + .../app/shared/models/post/review.model.ts | 4 + frontend-web/Frontend/src/assets/asta.png | Bin 0 -> 30540 bytes frontend-web/Frontend/src/index.html | 13 + frontend-web/Frontend/src/main.ts | 6 + frontend-web/Frontend/src/styles.css | 8 + frontend-web/Frontend/tailwind.config.js | 12 + frontend-web/Frontend/tsconfig.app.json | 15 + frontend-web/Frontend/tsconfig.json | 27 + frontend-web/Frontend/tsconfig.spec.json | 15 + logs/comments.log | 0 logs/posts.log | 0 logs/reviews.log | 0 186 files changed, 21891 insertions(+), 121 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/dataSources.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/project-IliasAzrhari.iml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 backend-java/.idea/.gitignore create mode 100644 backend-java/.idea/backend-java.iml create mode 100644 backend-java/.idea/compiler.xml create mode 100644 backend-java/.idea/encodings.xml create mode 100644 backend-java/.idea/jarRepositories.xml create mode 100644 backend-java/.idea/misc.xml create mode 100644 backend-java/.idea/modules.xml create mode 100644 backend-java/.idea/vcs.xml create mode 100644 backend-java/Microservices/CommentService/logs/comments.log create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/client/NotificationClient.java create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/CommentController.java create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/CommentRequest.java create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/domain/Comment.java create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/repository/CommentRepository.java create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/CommentService.java create mode 100644 backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/ICommentService.java create mode 100644 backend-java/Microservices/CommentService/src/main/resources/logback.xml create mode 100644 backend-java/Microservices/CommentService/src/test/java/be/pxl/services/controller/CommentControllerTest.java create mode 100644 backend-java/Microservices/CommentService/src/test/java/be/pxl/services/domain/CommentTest.java create mode 100644 backend-java/Microservices/CommentService/src/test/java/be/pxl/services/services/CommentServiceTest.java create mode 100644 backend-java/Microservices/ConfigService/src/main/resources/config/gateway-service.yml create mode 100644 backend-java/Microservices/GatewayService/pom.xml create mode 100644 backend-java/Microservices/GatewayService/src/main/java/be/pxl/services/GatewayServiceApplication.java create mode 100644 backend-java/Microservices/GatewayService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/MessagingService/pom.xml create mode 100644 backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/MessagingServiceApplication.java create mode 100644 backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/configuration/QueueConfiguration.java create mode 100644 backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/service/QueueService.java create mode 100644 backend-java/Microservices/MessagingService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/NotificationService/pom.xml create mode 100644 backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/NotificationServiceApplication.java create mode 100644 backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/controller/NotificationController.java create mode 100644 backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/domain/Notification.java create mode 100644 backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/INotificationService.java create mode 100644 backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/NotificationService.java create mode 100644 backend-java/Microservices/NotificationService/src/main/resources/application.properties create mode 100644 backend-java/Microservices/NotificationService/src/test/java/be/pxl/services/AppTest.java create mode 100644 backend-java/Microservices/PostService/logs/posts.log create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/client/NotificationClient.java create mode 100644 backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java create mode 100644 backend-java/Microservices/PostService/src/main/resources/logback.xml create mode 100644 backend-java/Microservices/PostService/src/test/java/be/pxl/services/controller/PostControllerTest.java create mode 100644 backend-java/Microservices/PostService/src/test/java/be/pxl/services/domain/PostTest.java create mode 100644 backend-java/Microservices/PostService/src/test/java/be/pxl/services/services/PostServicesTest.java create mode 100644 backend-java/Microservices/ReviewService/logs/reviews.log create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/client/NotificationClient.java create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/ReviewController.java create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/ReviewRequest.java create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/domain/Review.java create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/repository/ReviewRepository.java create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/IReviewService.java create mode 100644 backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/ReviewService.java create mode 100644 backend-java/Microservices/ReviewService/src/main/resources/logback.xml create mode 100644 backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/controller/ReviewControllerTest.java create mode 100644 backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/domain/ReviewTest.java create mode 100644 backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/services/ReviewServiceTest.java create mode 100644 frontend-web/.idea/.gitignore create mode 100644 frontend-web/.idea/frontend-web.iml create mode 100644 frontend-web/.idea/misc.xml create mode 100644 frontend-web/.idea/modules.xml create mode 100644 frontend-web/.idea/vcs.xml create mode 100644 frontend-web/Frontend/.editorconfig create mode 100644 frontend-web/Frontend/.gitignore create mode 100644 frontend-web/Frontend/.vscode/extensions.json create mode 100644 frontend-web/Frontend/.vscode/launch.json create mode 100644 frontend-web/Frontend/.vscode/tasks.json create mode 100644 frontend-web/Frontend/README.md create mode 100644 frontend-web/Frontend/angular.json create mode 100644 frontend-web/Frontend/package-lock.json create mode 100644 frontend-web/Frontend/package.json create mode 100644 frontend-web/Frontend/public/favicon.ico create mode 100644 frontend-web/Frontend/src/app/app.component.css create mode 100644 frontend-web/Frontend/src/app/app.component.html create mode 100644 frontend-web/Frontend/src/app/app.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/app.component.ts create mode 100644 frontend-web/Frontend/src/app/app.config.ts create mode 100644 frontend-web/Frontend/src/app/app.routes.ts create mode 100644 frontend-web/Frontend/src/app/component/add-comment/add-comment.component.css create mode 100644 frontend-web/Frontend/src/app/component/add-comment/add-comment.component.html create mode 100644 frontend-web/Frontend/src/app/component/add-comment/add-comment.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/add-comment/add-comment.component.ts create mode 100644 frontend-web/Frontend/src/app/component/add-post/add-post.component.css create mode 100644 frontend-web/Frontend/src/app/component/add-post/add-post.component.html create mode 100644 frontend-web/Frontend/src/app/component/add-post/add-post.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/add-post/add-post.component.ts create mode 100644 frontend-web/Frontend/src/app/component/comments/comments.component.css create mode 100644 frontend-web/Frontend/src/app/component/comments/comments.component.html create mode 100644 frontend-web/Frontend/src/app/component/comments/comments.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/comments/comments.component.ts create mode 100644 frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.css create mode 100644 frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.html create mode 100644 frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.ts create mode 100644 frontend-web/Frontend/src/app/component/datepicker/datepicker.component.css create mode 100644 frontend-web/Frontend/src/app/component/datepicker/datepicker.component.html create mode 100644 frontend-web/Frontend/src/app/component/datepicker/datepicker.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/datepicker/datepicker.component.ts create mode 100644 frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.css create mode 100644 frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.html create mode 100644 frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.ts create mode 100644 frontend-web/Frontend/src/app/component/edit-post/edit-post.component.css create mode 100644 frontend-web/Frontend/src/app/component/edit-post/edit-post.component.html create mode 100644 frontend-web/Frontend/src/app/component/edit-post/edit-post.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/edit-post/edit-post.component.ts create mode 100644 frontend-web/Frontend/src/app/component/login/login.component.css create mode 100644 frontend-web/Frontend/src/app/component/login/login.component.html create mode 100644 frontend-web/Frontend/src/app/component/login/login.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/login/login.component.ts create mode 100644 frontend-web/Frontend/src/app/component/navbar/navbar.component.css create mode 100644 frontend-web/Frontend/src/app/component/navbar/navbar.component.html create mode 100644 frontend-web/Frontend/src/app/component/navbar/navbar.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/navbar/navbar.component.ts create mode 100644 frontend-web/Frontend/src/app/component/posts/posts.component.css create mode 100644 frontend-web/Frontend/src/app/component/posts/posts.component.html create mode 100644 frontend-web/Frontend/src/app/component/posts/posts.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/posts/posts.component.ts create mode 100644 frontend-web/Frontend/src/app/component/review-details/review-details.component.css create mode 100644 frontend-web/Frontend/src/app/component/review-details/review-details.component.html create mode 100644 frontend-web/Frontend/src/app/component/review-details/review-details.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/review-details/review-details.component.ts create mode 100644 frontend-web/Frontend/src/app/component/review-post/review-post.component.css create mode 100644 frontend-web/Frontend/src/app/component/review-post/review-post.component.html create mode 100644 frontend-web/Frontend/src/app/component/review-post/review-post.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/review-post/review-post.component.ts create mode 100644 frontend-web/Frontend/src/app/component/searchbar/searchbar.component.css create mode 100644 frontend-web/Frontend/src/app/component/searchbar/searchbar.component.html create mode 100644 frontend-web/Frontend/src/app/component/searchbar/searchbar.component.spec.ts create mode 100644 frontend-web/Frontend/src/app/component/searchbar/searchbar.component.ts create mode 100644 frontend-web/Frontend/src/app/services/auth.service.spec.ts create mode 100644 frontend-web/Frontend/src/app/services/auth.service.ts create mode 100644 frontend-web/Frontend/src/app/services/comment.service.spec.ts create mode 100644 frontend-web/Frontend/src/app/services/comment.service.ts create mode 100644 frontend-web/Frontend/src/app/services/notification.service.spec.ts create mode 100644 frontend-web/Frontend/src/app/services/notification.service.ts create mode 100644 frontend-web/Frontend/src/app/services/posts.service.spec.ts create mode 100644 frontend-web/Frontend/src/app/services/posts.service.ts create mode 100644 frontend-web/Frontend/src/app/services/review.service.spec.ts create mode 100644 frontend-web/Frontend/src/app/services/review.service.ts create mode 100644 frontend-web/Frontend/src/app/shared/models/post/comment.model.ts create mode 100644 frontend-web/Frontend/src/app/shared/models/post/post.model.ts create mode 100644 frontend-web/Frontend/src/app/shared/models/post/review.model.ts create mode 100644 frontend-web/Frontend/src/assets/asta.png create mode 100644 frontend-web/Frontend/src/index.html create mode 100644 frontend-web/Frontend/src/main.ts create mode 100644 frontend-web/Frontend/src/styles.css create mode 100644 frontend-web/Frontend/tailwind.config.js create mode 100644 frontend-web/Frontend/tsconfig.app.json create mode 100644 frontend-web/Frontend/tsconfig.json create mode 100644 frontend-web/Frontend/tsconfig.spec.json create mode 100644 logs/comments.log create mode 100644 logs/posts.log create mode 100644 logs/reviews.log diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 000000000..dead6c382 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 000000000..fbc318451 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,41 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3306 + + + + + + $ProjectFileDir$ + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3307 + + + + + + $ProjectFileDir$ + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3308 + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 000000000..0d939e62f --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 000000000..712ab9d98 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..887ee8c6e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..f6d43bee6 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/project-IliasAzrhari.iml b/.idea/project-IliasAzrhari.iml new file mode 100644 index 000000000..d6ebd4805 --- /dev/null +++ b/.idea/project-IliasAzrhari.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 000000000..2b63946d5 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..35eb1ddfb --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/backend-java/.idea/.gitignore b/backend-java/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/backend-java/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/backend-java/.idea/backend-java.iml b/backend-java/.idea/backend-java.iml new file mode 100644 index 000000000..d6ebd4805 --- /dev/null +++ b/backend-java/.idea/backend-java.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/backend-java/.idea/compiler.xml b/backend-java/.idea/compiler.xml new file mode 100644 index 000000000..0ba114e25 --- /dev/null +++ b/backend-java/.idea/compiler.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend-java/.idea/encodings.xml b/backend-java/.idea/encodings.xml new file mode 100644 index 000000000..2d9a7e9ba --- /dev/null +++ b/backend-java/.idea/encodings.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/backend-java/.idea/jarRepositories.xml b/backend-java/.idea/jarRepositories.xml new file mode 100644 index 000000000..712ab9d98 --- /dev/null +++ b/backend-java/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/backend-java/.idea/misc.xml b/backend-java/.idea/misc.xml new file mode 100644 index 000000000..1d44d03cd --- /dev/null +++ b/backend-java/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/backend-java/.idea/modules.xml b/backend-java/.idea/modules.xml new file mode 100644 index 000000000..508d7535b --- /dev/null +++ b/backend-java/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/backend-java/.idea/vcs.xml b/backend-java/.idea/vcs.xml new file mode 100644 index 000000000..6c0b86358 --- /dev/null +++ b/backend-java/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/backend-java/Microservices/CommentService/logs/comments.log b/backend-java/Microservices/CommentService/logs/comments.log new file mode 100644 index 000000000..e69de29bb diff --git a/backend-java/Microservices/CommentService/pom.xml b/backend-java/Microservices/CommentService/pom.xml index 8247d69c7..71eb42c1d 100644 --- a/backend-java/Microservices/CommentService/pom.xml +++ b/backend-java/Microservices/CommentService/pom.xml @@ -22,7 +22,7 @@ junit junit - 3.8.1 + 4.13.2 test @@ -42,5 +42,25 @@ spring-cloud-starter-config + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.amqp + spring-rabbit + + + + org.testcontainers + mysql + test + + + org.testcontainers + junit-jupiter + test + diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java index 20c5156ee..84087822d 100644 --- a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/CommentServiceApplication.java @@ -3,6 +3,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; /** * Hello world! @@ -10,6 +11,7 @@ */ @SpringBootApplication @EnableDiscoveryClient +@EnableFeignClients public class CommentServiceApplication { public static void main( String[] args ) diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/client/NotificationClient.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/client/NotificationClient.java new file mode 100644 index 000000000..c721b5103 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/client/NotificationClient.java @@ -0,0 +1,13 @@ +package be.pxl.services.client; + +import be.pxl.services.controller.request.NotificationRequest; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = "notification-service") +public interface NotificationClient { + + @PostMapping("/notification") + void sendNotification(@RequestBody NotificationRequest notificationRequest); +} diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/CommentController.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/CommentController.java new file mode 100644 index 000000000..f89318285 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/CommentController.java @@ -0,0 +1,54 @@ +package be.pxl.services.controller; + +import be.pxl.services.controller.request.CommentRequest; +import be.pxl.services.domain.Comment; +import be.pxl.services.services.CommentService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/comments") +@RequiredArgsConstructor +public class CommentController { + private final CommentService commentService; + + @GetMapping + public ResponseEntity> getComments() { + List comments = commentService.getComments(); + return new ResponseEntity<>(comments, HttpStatus.OK); + } + + @GetMapping("/{id}") + public ResponseEntity getCommentById(@PathVariable Long id) { + Comment comment = commentService.getCommentById(id); + return new ResponseEntity<>(comment, HttpStatus.OK); + } + + @GetMapping("/findByAuthor") + public ResponseEntity> getCommentsByAuthor(@RequestParam String author) { + List comments = commentService.getCommentsByAuthor(author); + return new ResponseEntity<>(comments, HttpStatus.OK); + } + + @PostMapping("/{postId}") + public ResponseEntity createComment(@PathVariable Long postId, @RequestBody CommentRequest comment) { + Comment newComment = commentService.createComment(postId, comment); + return new ResponseEntity<>(newComment, HttpStatus.CREATED); + } + + @PutMapping("/{id}") + public ResponseEntity updateComment(@PathVariable Long id, @RequestBody CommentRequest comment) { + Comment updatedComment = commentService.updateComment(id, comment); + return new ResponseEntity<>(updatedComment, HttpStatus.OK); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteComment(@PathVariable Long id) { + commentService.deleteComment(id); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } +} diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/CommentRequest.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/CommentRequest.java new file mode 100644 index 000000000..a142512c6 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/CommentRequest.java @@ -0,0 +1,4 @@ +package be.pxl.services.controller.request; + +public record CommentRequest (String author, String content) { +} diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java new file mode 100644 index 000000000..e5e90d5e0 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java @@ -0,0 +1,17 @@ +package be.pxl.services.controller.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class NotificationRequest { + + private String message; + private String sender; + +} diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/domain/Comment.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/domain/Comment.java new file mode 100644 index 000000000..d867f1fb9 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/domain/Comment.java @@ -0,0 +1,24 @@ +package be.pxl.services.domain; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Table(name = "comments") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Comment { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String author; + private Long postId; + private String content; +} diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/repository/CommentRepository.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/repository/CommentRepository.java new file mode 100644 index 000000000..570eeea9c --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/repository/CommentRepository.java @@ -0,0 +1,9 @@ +package be.pxl.services.repository; + +import be.pxl.services.domain.Comment; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CommentRepository extends JpaRepository { +} diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/CommentService.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/CommentService.java new file mode 100644 index 000000000..7f35b4491 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/CommentService.java @@ -0,0 +1,68 @@ +package be.pxl.services.services; + +import be.pxl.services.controller.request.CommentRequest; +import be.pxl.services.domain.Comment; +import be.pxl.services.repository.CommentRepository; +import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class CommentService implements ICommentService { + private final CommentRepository commentRepository; + private static Logger logger = LoggerFactory.getLogger(CommentService.class.getName()); + + @Override + public Comment createComment(Long postId, CommentRequest commentRequest) { + Comment comment = Comment.builder() + .author(commentRequest.author()) + .content(commentRequest.content()) + .postId(postId) + .build(); + commentRepository.save(comment); + logger.info("Comment created: {}", comment); + return comment; + } + + @Override + public Comment getCommentById(Long id) { + logger.info("Fetching comment by id: {}", id); + return commentRepository.findById(id).orElse(null); + } + + @Override + public Comment updateComment(Long id, CommentRequest commentRequest) { + Comment comment = commentRepository.findById(id).orElse(null); + if(commentRequest.author() != null){ + comment.setAuthor(commentRequest.author()); + } + if (commentRequest.content() != null){ + comment.setContent(commentRequest.content()); + } + commentRepository.save(comment); + logger.info("Comment updated: {}", comment); + return comment; + } + + @Override + public void deleteComment(Long id) { + commentRepository.deleteById(id); + logger.info("Comment deleted with id: {}", id); + } + + @Override + public List getComments() { + logger.info("Fetching all comments"); + return commentRepository.findAll(); + } + + @Override + public List getCommentsByAuthor(String author) { + logger.info("Fetching comments by author: {}", author); + return commentRepository.findAll().stream().filter(comment -> comment.getAuthor().equals(author)).toList(); + } +} diff --git a/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/ICommentService.java b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/ICommentService.java new file mode 100644 index 000000000..37d20f7b5 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/java/be/pxl/services/services/ICommentService.java @@ -0,0 +1,15 @@ +package be.pxl.services.services; + +import be.pxl.services.controller.request.CommentRequest; +import be.pxl.services.domain.Comment; + +import java.util.List; + +public interface ICommentService { + Comment createComment(Long postId, CommentRequest commentRequest); + Comment getCommentById(Long id); + Comment updateComment(Long id, CommentRequest commentRequest); + void deleteComment(Long id); + List getComments(); + List getCommentsByAuthor(String author); +} diff --git a/backend-java/Microservices/CommentService/src/main/resources/logback.xml b/backend-java/Microservices/CommentService/src/main/resources/logback.xml new file mode 100644 index 000000000..ec3118e0a --- /dev/null +++ b/backend-java/Microservices/CommentService/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + logs/comments.log + true + + %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java index cfd331ca4..6d496663b 100644 --- a/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java +++ b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/CommentServiceApplicationTest.java @@ -4,35 +4,17 @@ import junit.framework.TestCase; import junit.framework.TestSuite; -/** - * Unit test for simple App. - */ -public class CommentServiceApplicationTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public CommentServiceApplicationTest(String testName ) - { - super( testName ); +public class CommentServiceApplicationTest extends TestCase { + + public CommentServiceApplicationTest(String testName) { + super(testName); } - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( CommentServiceApplicationTest.class ); + public static Test suite() { + return new TestSuite(CommentServiceApplicationTest.class); } - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); + public void testApp() { + assertTrue(true); } } diff --git a/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/controller/CommentControllerTest.java b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/controller/CommentControllerTest.java new file mode 100644 index 000000000..400d6cf84 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/controller/CommentControllerTest.java @@ -0,0 +1,137 @@ +package be.pxl.services.controller; + +import be.pxl.services.controller.CommentController; +import be.pxl.services.controller.request.CommentRequest; +import be.pxl.services.domain.Comment; +import be.pxl.services.repository.CommentRepository; +import be.pxl.services.services.CommentService; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@SpringBootTest +@Testcontainers +@AutoConfigureMockMvc +public class CommentControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private CommentService commentService; + + @Autowired + private CommentRepository commentRepository; + + @Autowired + private ObjectMapper objectMapper; + + @Container + private static final MySQLContainer sqlContainer = new MySQLContainer("mysql:5.7.37"); + + @DynamicPropertySource + static void registerMySQLProperties(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", sqlContainer::getJdbcUrl); + registry.add("spring.datasource.username", sqlContainer::getUsername); + registry.add("spring.datasource.password", sqlContainer::getPassword); + } + + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + commentRepository.deleteAll(); + Comment comment1 = new Comment(1L, "Author1", 2L,"Content1"); + Comment comment2 = new Comment(2L, "Author2", 2L, "Content2"); + commentRepository.saveAll(Arrays.asList(comment1, comment2)); + } + + @Test + void testGetComments() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/api/comments")) + .andExpect(status().isOk()); + assertEquals(2, commentRepository.findAll().size()); + } + + @Test + void testGetCommentById() throws Exception { + Comment comment = Comment.builder() + .id(1L) + .author("Author1") + .postId(2L) + .content("Content1") + .build(); + mockMvc.perform(MockMvcRequestBuilders.get("/api/comments/{id}", 1L)) + .andExpect(status().isOk()); + } + + @Test + void testGetCommentsByAuthor() throws Exception { + + mockMvc.perform(get("/api/comments/findByAuthor").param("author", "Author1")) + .andExpect(status().isOk()); + + assertEquals(1, commentRepository.findAll().stream().filter(comment -> comment.getAuthor().equals("Author1")).count()); + } + + @Test + void testCreateComment() throws Exception { + Comment comment = Comment.builder() + .id(1L) + .author("Author1") + .postId(2L) + .content("Content1") + .build(); + + String commentString = objectMapper.writeValueAsString(comment); + + mockMvc.perform(MockMvcRequestBuilders.post("/api/comments/{postId}", 1L) + .contentType(MediaType.APPLICATION_JSON) + .content(commentString)) + .andExpect(status().isCreated()); + } + + @Test + void testUpdateComment() throws Exception { + CommentRequest commentRequest = new CommentRequest("Author1", "UpdatedContent"); + String commentString = objectMapper.writeValueAsString(commentRequest); + + mockMvc.perform(MockMvcRequestBuilders.put("/api/comments/{id}", 1L) + .contentType(MediaType.APPLICATION_JSON) + .content(commentString)) + .andExpect(status().isOk()); + } + + @Test + void testDeleteComment() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.delete("/api/comments/{id}", 1L)) + .andExpect(status().isNoContent()); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/domain/CommentTest.java b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/domain/CommentTest.java new file mode 100644 index 000000000..ec469f412 --- /dev/null +++ b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/domain/CommentTest.java @@ -0,0 +1,38 @@ +package be.pxl.services.domain; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +public class CommentTest { + @Test void testCommentCreation() { + // Arrange + Comment comment = Comment.builder() + .id(2L) + .author("John Doe") + .postId(1L) + .content("This is a comment") + .build(); + // Assert + assertThat(comment).isNotNull(); + assertThat(comment.getId()).isEqualTo(2L); + assertThat(comment.getPostId()).isEqualTo(1L); + assertThat(comment.getAuthor()).isEqualTo("John Doe"); + assertThat(comment.getContent()).isEqualTo("This is a comment"); + } + + @Test + void testCommentSettersAndGetters() { + // Arrange + Comment comment = new Comment(); + + // Act + comment.setId(2L); + comment.setAuthor("Jane"); + comment.setContent("This is a comment"); + comment.setPostId(1L); + + // Assert + assertThat(comment.getId()).isEqualTo(2L); + assertThat(comment.getPostId()).isEqualTo(1L); + assertThat(comment.getAuthor()).isEqualTo("Jane"); + assertThat(comment.getContent()).isEqualTo("This is a comment"); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/services/CommentServiceTest.java b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/services/CommentServiceTest.java new file mode 100644 index 000000000..6b1630f0d --- /dev/null +++ b/backend-java/Microservices/CommentService/src/test/java/be/pxl/services/services/CommentServiceTest.java @@ -0,0 +1,162 @@ +package be.pxl.services.services; + +import be.pxl.services.controller.request.CommentRequest; +import be.pxl.services.domain.Comment; +import be.pxl.services.repository.CommentRepository; +import be.pxl.services.services.CommentService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class CommentServiceTest { + @Mock + private CommentRepository commentRepository; + + @InjectMocks + private CommentService commentService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testCreateComment() { + CommentRequest commentRequest = new CommentRequest("author", "content"); + Comment comment = Comment.builder() + .author("author") + .content("content") + .postId(1L) + .build(); + + when(commentRepository.save(any(Comment.class))).thenReturn(comment); + + Comment createdComment = commentService.createComment(1L, commentRequest); + + assertNotNull(createdComment); + assertEquals("author", createdComment.getAuthor()); + assertEquals("content", createdComment.getContent()); + assertEquals(1L, createdComment.getPostId()); + verify(commentRepository, times(1)).save(any(Comment.class)); + } + + @Test + void testGetCommentById() { + Comment comment = new Comment(); + comment.setId(1L); + when(commentRepository.findById(1L)).thenReturn(Optional.of(comment)); + + Comment foundComment = commentService.getCommentById(1L); + + assertNotNull(foundComment); + assertEquals(1L, foundComment.getId()); + verify(commentRepository, times(1)).findById(1L); + } + + @Test + void testUpdateComment() { + CommentRequest commentRequest = new CommentRequest("newAuthor", "newContent"); + Comment comment = new Comment(); + comment.setId(1L); + comment.setAuthor("author"); + comment.setContent("content"); + + when(commentRepository.findById(1L)).thenReturn(Optional.of(comment)); + when(commentRepository.save(any(Comment.class))).thenReturn(comment); + + Comment updatedComment = commentService.updateComment(1L, commentRequest); + + assertNotNull(updatedComment); + assertEquals("newAuthor", updatedComment.getAuthor()); + assertEquals("newContent", updatedComment.getContent()); + verify(commentRepository, times(1)).findById(1L); + verify(commentRepository, times(1)).save(any(Comment.class)); + } + + @Test + void testUpdateCommentWithNullAuthor() { + CommentRequest commentRequest = new CommentRequest(null, "newContent"); + Comment comment = new Comment(); + comment.setId(1L); + comment.setAuthor("author"); + comment.setContent("content"); + + when(commentRepository.findById(1L)).thenReturn(Optional.of(comment)); + when(commentRepository.save(any(Comment.class))).thenReturn(comment); + + Comment updatedComment = commentService.updateComment(1L, commentRequest); + + assertNotNull(updatedComment); + assertEquals("author", updatedComment.getAuthor()); + assertEquals("newContent", updatedComment.getContent()); + verify(commentRepository, times(1)).findById(1L); + verify(commentRepository, times(1)).save(any(Comment.class)); + } + + @Test + void testUpdateCommentWithNullContent() { + CommentRequest commentRequest = new CommentRequest("newAuthor", null); + Comment comment = new Comment(); + comment.setId(1L); + comment.setAuthor("author"); + comment.setContent("content"); + + when(commentRepository.findById(1L)).thenReturn(Optional.of(comment)); + when(commentRepository.save(any(Comment.class))).thenReturn(comment); + + Comment updatedComment = commentService.updateComment(1L, commentRequest); + + assertNotNull(updatedComment); + assertEquals("newAuthor", updatedComment.getAuthor()); + assertEquals("content", updatedComment.getContent()); + verify(commentRepository, times(1)).findById(1L); + verify(commentRepository, times(1)).save(any(Comment.class)); + } + + @Test + void testDeleteComment() { + doNothing().when(commentRepository).deleteById(1L); + + commentService.deleteComment(1L); + + verify(commentRepository, times(1)).deleteById(1L); + } + + @Test + void testGetComments() { + List comments = List.of(new Comment(), new Comment()); + when(commentRepository.findAll()).thenReturn(comments); + + List foundComments = commentService.getComments(); + + assertNotNull(foundComments); + assertEquals(2, foundComments.size()); + verify(commentRepository, times(1)).findAll(); + } + + @Test + void testGetCommentsByAuthor() { + Comment comment1 = new Comment(); + comment1.setAuthor("author"); + Comment comment2 = new Comment(); + comment2.setAuthor("author"); + List comments = List.of(comment1, comment2); + + when(commentRepository.findAll()).thenReturn(comments); + + List foundComments = commentService.getCommentsByAuthor("author"); + + assertNotNull(foundComments); + assertEquals(2, foundComments.size()); + verify(commentRepository, times(1)).findAll(); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/ConfigService/src/main/resources/application.properties b/backend-java/Microservices/ConfigService/src/main/resources/application.properties index 5886557de..dafb5b293 100644 --- a/backend-java/Microservices/ConfigService/src/main/resources/application.properties +++ b/backend-java/Microservices/ConfigService/src/main/resources/application.properties @@ -1,4 +1,4 @@ server.port=8088 spring.application.name=config-service spring.profiles.active=native -spring.cloud.config.server.native.search-locations=classpath:/config, classpath:/common \ No newline at end of file +spring.cloud.config.server.native.search-locations=classpath:/config, classpath:/common diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties index c6f3dc2d7..71dd00e80 100644 --- a/backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/comment-service.properties @@ -8,4 +8,5 @@ spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect spring.cloud.compatibility-verifier.enabled=false eureka.client.service-url.defaultZone=http://localhost:8061/eureka/ -spring.config.import-check.enabled=false \ No newline at end of file +spring.config.import-check.enabled=false +eureka.instance.prefer-ip-address=true diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties index 3af71a1a2..c09741a31 100644 --- a/backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/discovery-service.properties @@ -1,9 +1,10 @@ server.port=8061 spring.cloud.compatibility-verifier.enabled=false eureka.instance.hostname=localhost +#eureka.instance.prefer-ip-address=true eureka.client.register-with-eureka=false eureka.client.fetch-registry=false +eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ #eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/ # application.properties -eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ \ No newline at end of file diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/gateway-service.yml b/backend-java/Microservices/ConfigService/src/main/resources/config/gateway-service.yml new file mode 100644 index 000000000..e961331b6 --- /dev/null +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/gateway-service.yml @@ -0,0 +1,51 @@ +server: + port: 8095 + +#logging: +# pattern: +# console: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" + +spring: + cloud: + gateway: + discovery: + locator: + enabled: true + globalcors: + corsConfigurations: + '[/**]': + allowedOrigins: + - "http://localhost:4200" + allowedMethods: + - GET + - POST + - PUT + - DELETE + allowedHeaders: + - "*" + routes: + - id: post-service + uri: lb://post-service + predicates: + - Path=/post/** + filters: + - RewritePath=/post/(?.*), /$\{path} + - id: review-service + uri: lb://review-service + predicates: + - Path=/review/** + filters: + - RewritePath=/review/(?.*), /$\{path} + - id: comment-service + uri: lb://comment-service + predicates: + - Path=/comment/** + filters: + - RewritePath=/comment/(?.*), /$\{path} + +eureka: + client: + serviceUrl: + defaultZone: http://localhost:8061/eureka/ + instance: + preferIpAddress: true diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties index c202e618c..8e6b5b0c9 100644 --- a/backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/post-service.properties @@ -8,4 +8,5 @@ spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect spring.cloud.compatibility-verifier.enabled=false eureka.client.service-url.defaultZone=http://localhost:8061/eureka/ -spring.config.import-check.enabled=false \ No newline at end of file +spring.config.import-check.enabled=false +eureka.instance.prefer-ip-address=true diff --git a/backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties b/backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties index 8b66293e1..e6ffba7ca 100644 --- a/backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties +++ b/backend-java/Microservices/ConfigService/src/main/resources/config/review-service.properties @@ -8,4 +8,5 @@ spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect spring.cloud.compatibility-verifier.enabled=false eureka.client.service-url.defaultZone=http://localhost:8061/eureka/ -spring.config.import-check.enabled=false \ No newline at end of file +spring.config.import-check.enabled=false +eureka.instance.prefer-ip-address=true diff --git a/backend-java/Microservices/GatewayService/pom.xml b/backend-java/Microservices/GatewayService/pom.xml new file mode 100644 index 000000000..e04501303 --- /dev/null +++ b/backend-java/Microservices/GatewayService/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + GatewayService + jar + + GatewayService + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.cloud + spring-cloud-starter-gateway + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + + + + + + diff --git a/backend-java/Microservices/GatewayService/src/main/java/be/pxl/services/GatewayServiceApplication.java b/backend-java/Microservices/GatewayService/src/main/java/be/pxl/services/GatewayServiceApplication.java new file mode 100644 index 000000000..e8a073f32 --- /dev/null +++ b/backend-java/Microservices/GatewayService/src/main/java/be/pxl/services/GatewayServiceApplication.java @@ -0,0 +1,19 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * Hello world! + * + */ +@SpringBootApplication +@EnableDiscoveryClient +public class GatewayServiceApplication +{ + public static void main( String[] args ) + { + SpringApplication.run(GatewayServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/GatewayService/src/main/resources/application.properties b/backend-java/Microservices/GatewayService/src/main/resources/application.properties new file mode 100644 index 000000000..c22bfc69d --- /dev/null +++ b/backend-java/Microservices/GatewayService/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.application.name=gateway-service +spring.config.import=optional:configserver:${CONFIG_SERVER_URL:http://localhost:8088} +spring.main.web-application-type=reactive \ No newline at end of file diff --git a/backend-java/Microservices/MessagingService/pom.xml b/backend-java/Microservices/MessagingService/pom.xml new file mode 100644 index 000000000..0992ff697 --- /dev/null +++ b/backend-java/Microservices/MessagingService/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + MessagingService + jar + + MessagingService + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + + org.springframework.boot + spring-boot-starter-amqp + + + diff --git a/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/MessagingServiceApplication.java b/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/MessagingServiceApplication.java new file mode 100644 index 000000000..fd0b371e3 --- /dev/null +++ b/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/MessagingServiceApplication.java @@ -0,0 +1,17 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Hello world! + * + */ +@SpringBootApplication +public class MessagingServiceApplication +{ + public static void main( String[] args ) + { + SpringApplication.run(MessagingServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/configuration/QueueConfiguration.java b/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/configuration/QueueConfiguration.java new file mode 100644 index 000000000..700532679 --- /dev/null +++ b/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/configuration/QueueConfiguration.java @@ -0,0 +1,35 @@ +package be.pxl.services.configuration; + +import org.springframework.amqp.core.Queue; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +@Configuration +public class QueueConfiguration { + + @Bean + public Queue postCreatedQueue() { + return new Queue("postCreatedQueue", false); + } + + @Bean + public Queue postReviewQueue() { + return new Queue("postReviewQueue", false); + } + + @Bean + public Queue postApproved(){ + return new Queue("postApprovedQueue", false); + } + + @Bean + public Queue postRejected(){ + return new Queue("postRejectedQueue", false); + } + + @Bean + public Queue postCommentQueue() { + return new Queue("postCommentQueue", false); + } +} diff --git a/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/service/QueueService.java b/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/service/QueueService.java new file mode 100644 index 000000000..f9558eee5 --- /dev/null +++ b/backend-java/Microservices/MessagingService/src/main/java/be/pxl/services/service/QueueService.java @@ -0,0 +1,23 @@ +package be.pxl.services.service; + +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Service; + +@Service +public class QueueService { + +// @RabbitListener(queues = "postCreatedQueue") +// public void listenPostCreated(Long id) { +// //System.out.println("Post created for post with id: " + id); +// } +// +// @RabbitListener(queues = "postReviewQueue") +// public void listenPostReview(Long id) { +// //System.out.println("Message read from postReviewQueue: " + id); +// } +// +// @RabbitListener(queues = "postCommentQueue") +// public void listenPostComment(String in) { +// //System.out.println("Message read from postCommentQueue: " + in); +// } +} diff --git a/backend-java/Microservices/MessagingService/src/main/resources/application.properties b/backend-java/Microservices/MessagingService/src/main/resources/application.properties new file mode 100644 index 000000000..2555a4971 --- /dev/null +++ b/backend-java/Microservices/MessagingService/src/main/resources/application.properties @@ -0,0 +1,2 @@ +server.port=8091 +#spring.rabbitmq.host=localhost \ No newline at end of file diff --git a/backend-java/Microservices/NotificationService/pom.xml b/backend-java/Microservices/NotificationService/pom.xml new file mode 100644 index 000000000..78c9f9bcf --- /dev/null +++ b/backend-java/Microservices/NotificationService/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + + be.pxl + Microservices + 0.0.1-SNAPSHOT + + + be.pxl.services + NotificationService + jar + + NotificationService + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.boot + spring-boot-starter-mail + + + diff --git a/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/NotificationServiceApplication.java b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/NotificationServiceApplication.java new file mode 100644 index 000000000..3b205d656 --- /dev/null +++ b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/NotificationServiceApplication.java @@ -0,0 +1,20 @@ +package be.pxl.services; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * Hello world! + * + */ +@SpringBootApplication +@EnableDiscoveryClient +public class NotificationServiceApplication +{ + public static void main( String[] args ) + { + + SpringApplication.run(NotificationServiceApplication.class, args); + } +} diff --git a/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/controller/NotificationController.java b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/controller/NotificationController.java new file mode 100644 index 000000000..834fa2390 --- /dev/null +++ b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/controller/NotificationController.java @@ -0,0 +1,31 @@ +package be.pxl.services.controller; + +import be.pxl.services.domain.Notification; +import be.pxl.services.service.NotificationService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@Slf4j +@RequestMapping("/notification") +public class NotificationController { + + private final NotificationService notificationService; + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public void sendMessage(@RequestBody Notification notification){ + notificationService.sendMessage(notification); + } + + @PostMapping("/sendEmail") + @ResponseStatus(HttpStatus.CREATED) + public void sendEmail(@RequestParam String to, @RequestParam String subject ,@RequestBody Notification notification){ + notificationService.sendEmail(to, subject, notification); + } + + +} diff --git a/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/domain/Notification.java b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/domain/Notification.java new file mode 100644 index 000000000..e3625d5fc --- /dev/null +++ b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/domain/Notification.java @@ -0,0 +1,15 @@ +package be.pxl.services.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Notification { + private String message; + private String sender; +} diff --git a/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/INotificationService.java b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/INotificationService.java new file mode 100644 index 000000000..73e23d54e --- /dev/null +++ b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/INotificationService.java @@ -0,0 +1,8 @@ +package be.pxl.services.service; + +import be.pxl.services.domain.Notification; + +public interface INotificationService { + void sendMessage(Notification notification); + void sendEmail(String to, String subject, Notification notification); +} diff --git a/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/NotificationService.java b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/NotificationService.java new file mode 100644 index 000000000..c86d6abf6 --- /dev/null +++ b/backend-java/Microservices/NotificationService/src/main/java/be/pxl/services/service/NotificationService.java @@ -0,0 +1,40 @@ +package be.pxl.services.service; + +import be.pxl.services.domain.Notification; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class NotificationService implements INotificationService { + @Value("${spring.mail.username}") + private String fromEmail; + + private final JavaMailSender mailSender; + + public NotificationService(JavaMailSender mailSender) { + this.mailSender = mailSender; + } + + @Override + public void sendMessage(Notification notification){ + log.info("Receiving notification..."); + log.info("Sending... {} ", notification.getMessage()); + log.info("TO {}", notification.getSender()); + } + + @Override + public void sendEmail(String to, String subject, Notification notification) { + SimpleMailMessage message = new SimpleMailMessage(); + message.setFrom(fromEmail); + message.setTo(to); + message.setSubject(subject); + message.setText(notification.getMessage()); + mailSender.send(message); + } + + +} diff --git a/backend-java/Microservices/NotificationService/src/main/resources/application.properties b/backend-java/Microservices/NotificationService/src/main/resources/application.properties new file mode 100644 index 000000000..7033b5c08 --- /dev/null +++ b/backend-java/Microservices/NotificationService/src/main/resources/application.properties @@ -0,0 +1,12 @@ +server.port=8089 +spring.application.name=notification-service + +eureka.client.service-url.defaultZone=http://localhost:8061/eureka/ + +#Email Configuration +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.username=noreplycollide2425@gmail.com +spring.mail.password=bimz oifp qssb rttj +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true \ No newline at end of file diff --git a/backend-java/Microservices/NotificationService/src/test/java/be/pxl/services/AppTest.java b/backend-java/Microservices/NotificationService/src/test/java/be/pxl/services/AppTest.java new file mode 100644 index 000000000..e87772ee6 --- /dev/null +++ b/backend-java/Microservices/NotificationService/src/test/java/be/pxl/services/AppTest.java @@ -0,0 +1,38 @@ +package be.pxl.services; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/backend-java/Microservices/PostService/logs/posts.log b/backend-java/Microservices/PostService/logs/posts.log new file mode 100644 index 000000000..e69de29bb diff --git a/backend-java/Microservices/PostService/pom.xml b/backend-java/Microservices/PostService/pom.xml index db658e4ff..97fe0a69c 100644 --- a/backend-java/Microservices/PostService/pom.xml +++ b/backend-java/Microservices/PostService/pom.xml @@ -22,7 +22,7 @@ junit junit - 3.8.1 + 4.13.2 test @@ -41,6 +41,27 @@ org.springframework.cloud spring-cloud-starter-config - + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.springframework.amqp + spring-rabbit + + + ch.qos.logback + logback-classic + + + org.testcontainers + mysql + test + + + org.testcontainers + junit-jupiter + test + diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java index 02fc1b39a..de34dcae8 100644 --- a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/PostServiceApplication.java @@ -3,6 +3,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; /** * Hello world! @@ -10,6 +11,7 @@ */ @SpringBootApplication @EnableDiscoveryClient +@EnableFeignClients public class PostServiceApplication { public static void main( String[] args ) diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/client/NotificationClient.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/client/NotificationClient.java new file mode 100644 index 000000000..f2de57430 --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/client/NotificationClient.java @@ -0,0 +1,17 @@ +package be.pxl.services.client; + +import be.pxl.services.controller.request.NotificationRequest; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "notification-service") +public interface NotificationClient { + + @PostMapping("/notification") + void sendNotification(@RequestBody NotificationRequest notificationRequest); + + @PostMapping("/notification/sendEmail") + void sendEmail(@RequestParam String to, @RequestParam String subject, @RequestBody NotificationRequest notificationRequest); +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java index 14e562110..3650077c3 100644 --- a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/PostController.java @@ -1,9 +1,12 @@ package be.pxl.services.controller; +import be.pxl.services.client.NotificationClient; +import be.pxl.services.controller.request.NotificationRequest; import be.pxl.services.controller.request.PostRequest; import be.pxl.services.domain.Post; import be.pxl.services.service.PostService; import lombok.RequiredArgsConstructor; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -12,11 +15,12 @@ @RestController @RequestMapping("/api/posts") -@CrossOrigin(origins = "http://localhost:4200") @RequiredArgsConstructor public class PostController { private final PostService postService; + + @GetMapping public ResponseEntity> getAllPosts() { List posts = postService.getAllPosts(); @@ -35,10 +39,20 @@ public ResponseEntity> getPublishedPosts() { return new ResponseEntity<>(posts, HttpStatus.OK); } + @GetMapping("/findById/{id}") + public ResponseEntity getById(@PathVariable Long id) { + Post post = postService.getById(id); + return new ResponseEntity<>(post, HttpStatus.OK); + } + @PostMapping - public ResponseEntity addPost(@RequestBody PostRequest postRequest) { - Post newPost = postService.addPost(postRequest); - return new ResponseEntity<>(newPost, HttpStatus.CREATED); + public ResponseEntity addPost(@RequestHeader("User-Role") String userRole, @RequestBody PostRequest postRequest) { + if(userRole.equals("editor")) { + Post newPost = postService.addPost(postRequest); + return new ResponseEntity<>(newPost, HttpStatus.CREATED); + }else { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } } @GetMapping("/findByTitle") @@ -47,9 +61,38 @@ public ResponseEntity getPostByTitle(@RequestParam String title) { return new ResponseEntity<>(post, HttpStatus.OK); } + @GetMapping("/findAllPostWithTitle") + public ResponseEntity> getAllPostsWithTitle(@RequestParam String title) { + List posts = postService.findAllPostWithTitle(title); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @GetMapping("/findByContent") + public ResponseEntity> getPostByContent(@RequestParam String content) { + List posts = postService.findPostByContent(content); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @GetMapping("/findByAuthor") + public ResponseEntity> getPostByAuthor(@RequestParam String author) { + List posts = postService.findPostByAuthor(author); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + + @GetMapping("/findByDate") + public ResponseEntity> getPostByDate(@RequestParam String date) { + List posts = postService.findPostByDate(date); + return new ResponseEntity<>(posts, HttpStatus.OK); + } + @PostMapping("/update/{id}") - public ResponseEntity updatePost(@PathVariable Long id, @RequestBody PostRequest postRequest) { - postService.updatePost(id, postRequest); - return new ResponseEntity<>(HttpStatus.OK); + public ResponseEntity updatePost(@RequestHeader("User-Role") String userRole, @PathVariable Long id, @RequestBody PostRequest postRequest) { + if(userRole.equals("editor")) { + postService.updatePost(id, postRequest); + return new ResponseEntity<>(HttpStatus.OK); + }else { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } } + } diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java new file mode 100644 index 000000000..e5e90d5e0 --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java @@ -0,0 +1,17 @@ +package be.pxl.services.controller.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class NotificationRequest { + + private String message; + private String sender; + +} diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java index 95aaba5bd..85c86936e 100644 --- a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/controller/request/PostRequest.java @@ -1,6 +1,5 @@ package be.pxl.services.controller.request; +import java.time.LocalDate; -import java.util.Date; - -public record PostRequest (String author, Date date, String title, String content) { +public record PostRequest (String author, LocalDate date, String title, String content) { } diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java index e538a4493..55b6ce316 100644 --- a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/domain/Post.java @@ -6,7 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; -import java.util.Date; +import java.time.LocalDate; @Entity @Table(name = "posts") @@ -19,7 +19,7 @@ public class Post { @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String author; - private Date date; + private LocalDate date; private String title; private String content; private boolean concept; diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java index 90aa47b94..ce9c0e987 100644 --- a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/IPostService.java @@ -3,7 +3,6 @@ import be.pxl.services.controller.request.PostRequest; import be.pxl.services.domain.Post; -import java.util.Date; import java.util.List; public interface IPostService { @@ -11,9 +10,14 @@ public interface IPostService { List getConceptPosts(); List getPublishedPosts(); Post findPostByTitle(String title); - Post findPostByContent(String content); - Post findPostByAuthor(String author); - Post findPostByDate(Date date); + List findPostByContent(String content); + List findAllPostWithTitle(String title); + List findPostByAuthor(String author); + List findPostByDate(String date); Post addPost(PostRequest postRequest); + void deletePost( ); void updatePost(Long id, PostRequest postRequest); + Post getById(Long id); + void approvePost(Long id); + void rejectPost(Long id); } diff --git a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java index 79364f0de..5ee82105b 100644 --- a/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java +++ b/backend-java/Microservices/PostService/src/main/java/be/pxl/services/service/PostService.java @@ -1,67 +1,95 @@ package be.pxl.services.service; +import be.pxl.services.client.NotificationClient; +import be.pxl.services.controller.request.NotificationRequest; import be.pxl.services.controller.request.PostRequest; import be.pxl.services.domain.Post; import be.pxl.services.repository.PostRepository; import lombok.RequiredArgsConstructor; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; - -import java.util.Date; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Optional; +import org.slf4j.Logger; + @Service @RequiredArgsConstructor public class PostService implements IPostService{ private final PostRepository postRepository; + private final NotificationClient notificationClient; + private final RabbitTemplate rabbitTemplate; + private static Logger logger = LoggerFactory.getLogger(PostService.class.getName()); @Override public List getAllPosts() { + logger.info("Fetching all posts"); return postRepository.findAll(); } - @Override public List getConceptPosts() { + logger.debug("Fetching concept posts"); return postRepository.findAll().stream().filter(Post::isConcept).toList(); } - @Override public List getPublishedPosts() { + logger.debug("Fetching published posts"); return postRepository.findAll().stream().filter(post -> !post.isConcept()).toList(); } - @Override public Post findPostByTitle(String title) { - return postRepository.findByTitle(title).orElse(null); + logger.debug("Finding post by title: {}", title); + return postRepository.findByTitle(title.toLowerCase().trim()).orElse(null); } - @Override - public Post findPostByContent(String content) { - return postRepository.findByContent(content).orElse(null); + public List findAllPostWithTitle(String title) { + logger.debug("Finding all posts with title: {}", title); + return postRepository.findAll().stream().filter(post -> post.getTitle().contains(title) && !post.isConcept()).toList(); } - @Override - public Post findPostByAuthor(String author) { - return postRepository.findByAuthor(author).orElse(null); + public List findPostByContent(String content) { + logger.debug("Finding posts by content: {}", content); + return postRepository.findAll().stream().filter(post -> post.getContent().contains(content) && !post.isConcept()).toList(); } - @Override - public Post findPostByDate(Date date) { - return postRepository.findByDate(date).orElse(null); + public List findPostByAuthor(String author) { + logger.debug("Finding posts by author: {}", author); + return postRepository.findAll().stream().filter(post -> post.getAuthor().equals(author) && !post.isConcept()).toList(); + } + @Override + public List findPostByDate(String date) { + logger.debug("Finding posts by date: {}", date); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate localDate = LocalDate.parse(date, formatter); + return postRepository.findAll().stream().filter(post -> post.getDate().equals(localDate) && !post.isConcept()).toList(); } - @Override public Post addPost(PostRequest postRequest){ + logger.debug("Adding new post: {}", postRequest); Post post = new Post(); BeanUtils.copyProperties(postRequest, post); post.setConcept(true); + post.setDate(postRequest.date()); postRepository.save(post); + NotificationRequest notificationRequest = NotificationRequest.builder().message("New post added").sender("PostService").build(); + notificationClient.sendNotification(notificationRequest); + notificationClient.sendEmail("iliasazrhari112@gmail.com", "New post added", notificationRequest); + rabbitTemplate.convertAndSend("postCreatedQueue", post.getId()); return post; } - + @Override + public void deletePost() { + logger.debug("Deleting all posts"); + postRepository.deleteAll(); + } @Override public void updatePost(Long id, PostRequest postRequest) { + logger.debug("Updating post with id: {}", id); Optional post = postRepository.findById(id); if(post.isPresent()){ if(postRequest.title() != null){ @@ -70,8 +98,46 @@ public void updatePost(Long id, PostRequest postRequest) { if (postRequest.content() != null){ post.get().setContent(postRequest.content()); } + if (postRequest.author() != null){ + post.get().setAuthor(postRequest.author()); + } + if (postRequest.date() != null){ + post.get().setDate(postRequest.date()); + } + post.get().setConcept(true); Post updatedPost = post.get(); postRepository.save(updatedPost); } } + @Override + public Post getById(Long id) { + logger.debug("Getting post by id: {}", id); + return postRepository.findById(id).orElse(null); + } + + @RabbitListener(queues = "postApprovedQueue") + @Override + public void approvePost(Long id) { + logger.debug("Approving post with id: {}", id); + Optional post = postRepository.findById(id); + if(post.isPresent()){ + post.get().setConcept(false); + postRepository.save(post.get()); + NotificationRequest notificationRequest = NotificationRequest.builder().message("Post approved").sender("PostService").build(); + notificationClient.sendEmail("iliasazrhari112@gmail.com", "Post approved", notificationRequest); + notificationClient.sendNotification(notificationRequest); + } + } + @RabbitListener(queues = "postRejectedQueue") + @Override + public void rejectPost(Long id) { + logger.debug("Rejecting post with id: {}", id); + Optional post = postRepository.findById(id); + if(post.isPresent()){ + //postRepository.delete(post.get()); + NotificationRequest notificationRequest = NotificationRequest.builder().message("Post rejected").sender("PostService").build(); + notificationClient.sendNotification(notificationRequest); + notificationClient.sendEmail("iliasazrhari112@gmail.com", "Post rejected", notificationRequest); + } + } } diff --git a/backend-java/Microservices/PostService/src/main/resources/logback.xml b/backend-java/Microservices/PostService/src/main/resources/logback.xml new file mode 100644 index 000000000..82955bff5 --- /dev/null +++ b/backend-java/Microservices/PostService/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + logs/posts.log + true + + %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java index eee970f52..518126eaf 100644 --- a/backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java +++ b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/PostServiceApplicationTest.java @@ -4,35 +4,18 @@ import junit.framework.TestCase; import junit.framework.TestSuite; -/** - * Unit test for simple App. - */ -public class PostServiceApplicationTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public PostServiceApplicationTest(String testName ) - { - super( testName ); +public class PostServiceApplicationTest extends TestCase { + + public PostServiceApplicationTest(String testName) { + super(testName); } - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( PostServiceApplicationTest.class ); + public static Test suite() { + return new TestSuite(PostServiceApplicationTest.class); } - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); + public void testApp() { + assertTrue(true); } + } diff --git a/backend-java/Microservices/PostService/src/test/java/be/pxl/services/controller/PostControllerTest.java b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/controller/PostControllerTest.java new file mode 100644 index 000000000..e570d94d0 --- /dev/null +++ b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/controller/PostControllerTest.java @@ -0,0 +1,252 @@ +package be.pxl.services.controller; +import be.pxl.services.controller.request.PostRequest; +import be.pxl.services.domain.Post; +import be.pxl.services.repository.PostRepository; +import be.pxl.services.service.PostService; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import java.time.LocalDate; +import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; + +@Testcontainers +@SpringBootTest +@AutoConfigureMockMvc +public class PostControllerTest { + + @Mock + private PostService postService; + + @InjectMocks + private PostController postController; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private PostRepository postRepository; + + @Container + private static final MySQLContainer sqlContainer = new MySQLContainer("mysql:5.7.37"); + + @DynamicPropertySource + static void registerMySQLProperties(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", sqlContainer::getJdbcUrl); + registry.add("spring.datasource.username", sqlContainer::getUsername); + registry.add("spring.datasource.password", sqlContainer::getPassword); + } + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + postRepository.deleteAll(); + + Post post1 = new Post(1L, "Author1", LocalDate.now(), "Title1", "Content1", false); + Post post2 = new Post(2L, "Author2", LocalDate.now(), "Title2", "Content2", true); + postRepository.saveAll(Arrays.asList(post1, post2)); + } + + @Test + void testGetById() throws Exception { + Post post = Post.builder() + .id(3L) + .title("Title1") + .author("Author1") + .content("Content1") + .date(LocalDate.now()) + .concept(false) + .build(); + postRepository.save(post); + + mockMvc.perform(MockMvcRequestBuilders.get("/api/posts/findById/{id}", 3L)) + .andExpect(status().isOk()); + } + + @Test + void testGetAllPosts() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/api/posts/concept")) + .andExpect(status().isOk()); + assertEquals(2, postRepository.findAll().size()); + } + + @Test + void testGetConceptPosts() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/api/posts/concept")) + .andExpect(status().isOk()); + assertEquals(1, postRepository.findAll().stream().filter(Post::isConcept).count()); + } + + @Test + void testGetPublishedPosts() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/api/posts/published")) + .andExpect(status().isOk()); + assertEquals(1, postRepository.findAll().stream().filter(post -> !post.isConcept()).count()); + } + + + @Test + void testAddPostWithEditorRole() throws Exception { + Post post = Post.builder() + .id(1L) + .title("Title1") + .author("Jane") + .content("Content") + .date(LocalDate.now()) + .concept(true) + .build(); + String postString = objectMapper.writeValueAsString(post); + + mockMvc.perform(MockMvcRequestBuilders.post("/api/posts") + .contentType(MediaType.APPLICATION_JSON) + .header("User-Role", "editor") + .content(postString)) + .andExpect(status().isCreated()); + } + + @Test + void testAddPostWithNonEditorRole() throws Exception { + PostRequest postRequest = new PostRequest("Jane", LocalDate.now(), "Title", "Content"); + String postRequestString = objectMapper.writeValueAsString(postRequest); + + mockMvc.perform(post("/api/posts") + .contentType("application/json") + .header("User-Role", "user") + .content(postRequestString)) + .andExpect(status().isUnauthorized()); + } + + @Test + void testGetPostByTitle() throws Exception { + Post post = Post.builder() + .id(1L) + .title("Title1") + .author("Author1") + .content("Content1") + .date(LocalDate.now()) + .concept(true) + .build(); + + mockMvc.perform(get("/api/posts/findByTitle") + .param("title", "Title1")) + .andExpect(status().isOk()); + + assertEquals(post.getTitle(), postRepository.findByTitle("Title1").get().getTitle()); + } + +// @Test +// void testGetAllPostsWithTitle() throws Exception { +// List posts = Arrays.asList(new Post(), new Post()); +// when(postService.findAllPostWithTitle("title")).thenReturn(posts); +// +// mockMvc.perform(get("/api/posts/findAllPostWithTitle") +// .param("title", "title")) +// .andExpect(status().isOk()) +// .andExpect(jsonPath("$[0]").exists()) +// .andExpect(jsonPath("$[1]").exists()); +// } + + @Test + void testGetPostByContent() throws Exception { + Post post = Post.builder() + .id(1L) + .title("Title1") + .author("Author1") + .content("Content1") + .date(LocalDate.now()) + .concept(true) + .build(); + + mockMvc.perform(get("/api/posts/findByContent") + .param("content", "Content1")) + .andExpect(status().isOk()); + assertEquals(post.getContent(), postRepository.findByContent("Content1").get().getContent()); + } + + @Test + void testGetPostByAuthor() throws Exception { + Post post = Post.builder() + .id(1L) + .title("Title1") + .author("Author1") + .content("Content1") + .date(LocalDate.now()) + .concept(false) + .build(); + + mockMvc.perform(get("/api/posts/findByAuthor") + .param("author", "Jane")) + .andExpect(status().isOk()); + assertEquals(post.getAuthor(), postRepository.findByAuthor("Author1").get().getAuthor()); + } + + @Test + void testGetPostByDate() throws Exception { + Post post = Post.builder() + .id(1L) + .title("Title1") + .author("Author1") + .content("Content1") + .date(LocalDate.now()) + .concept(true) + .build(); + + mockMvc.perform(get("/api/posts/findByDate") + .param("date", LocalDate.now().toString())) + .andExpect(status().isOk()); + } + + @Test + void testUpdatePostWithEditorRole() throws Exception { + PostRequest postRequest = new PostRequest("Jane", LocalDate.now(), "Title", "Content"); + String postRequestString = objectMapper.writeValueAsString(postRequest); + + Post post = Post.builder() + .id(1L) + .title("Title") + .author("Jane") + .content("Content") + .date(LocalDate.now()) + .concept(false) + .build(); + + mockMvc.perform(post("/api/posts/update/{id}", 1L) + .contentType("application/json") + .header("User-Role", "editor") + .content(postRequestString)) + .andExpect(status().isOk()); + } + + @Test + void testUpdatePostWithNonEditorRole() throws Exception { + PostRequest postRequest = new PostRequest("Jane", LocalDate.now(), "Title", "Content"); + String postRequestString = objectMapper.writeValueAsString(postRequest); + + mockMvc.perform(post("/api/posts/update/1") + .contentType("application/json") + .header("User-Role", "user") + .content(postRequestString)) + .andExpect(status().isUnauthorized()); + } + +} \ No newline at end of file diff --git a/backend-java/Microservices/PostService/src/test/java/be/pxl/services/domain/PostTest.java b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/domain/PostTest.java new file mode 100644 index 000000000..5e89bdc8b --- /dev/null +++ b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/domain/PostTest.java @@ -0,0 +1,96 @@ +package be.pxl.services.domain; import org.junit.jupiter.api.Test; +import java.time.LocalDate; +import static org.assertj.core.api.Assertions.assertThat; +public class PostTest { @Test void testPostCreation() { + // Arrange + Post post = Post.builder() + .id(2L) + .author("John Doe") + .title("Title") + .content("This is a post") + .date(LocalDate.parse("2021-10-10")) + .concept(false) + .build(); + // Assert + assertThat(post).isNotNull(); + assertThat(post.getId()).isEqualTo(2L); + assertThat(post.getTitle()).isEqualTo("Title"); + assertThat(post.getAuthor()).isEqualTo("John Doe"); + assertThat(post.getContent()).isEqualTo("This is a post"); + assertThat(post.getDate().isEqual(LocalDate.parse("2021-10-10"))); + assertThat(post.isConcept()).isFalse(); +} + + @Test + void testPostSettersAndGetters() { + // Arrange + Post post = new Post(); + + // Act + post.setId(2L); + post.setAuthor("Jane"); + post.setContent("This is a post"); + post.setTitle("Title"); + post.setDate(LocalDate.parse("2021-10-10")); + post.setConcept(false); + + // Assert + assertThat(post.getId()).isEqualTo(2L); + assertThat(post.getTitle()).isEqualTo("Title"); + assertThat(post.getAuthor()).isEqualTo("Jane"); + assertThat(post.getContent()).isEqualTo("This is a post"); + assertThat(post.getDate().isEqual(LocalDate.parse("2021-10-10"))); + assertThat(post.isConcept()).isFalse(); + } + + @Test + void testPostToString() { + // Arrange + Post post = Post.builder() + .id(2L) + .author("John Doe") + .title("Title") + .content("This is a post") + .date(LocalDate.parse("2021-10-10")) + .concept(false) + .build(); + + // Act + String postString = post.toString(); + + // Assert + assertThat(postString).contains("Post"); + assertThat(postString).contains("id=2"); + assertThat(postString).contains("author=John Doe"); + assertThat(postString).contains("title=Title"); + assertThat(postString).contains("content=This is a post"); + assertThat(postString).contains("date=2021-10-10"); + assertThat(postString).contains("concept=false"); + } + + @Test + void testPostEqualsAndHashCode() { + // Arrange + Post post1 = Post.builder() + .id(2L) + .author("John Doe") + .title("Title") + .content("This is a post") + .date(LocalDate.parse("2021-10-10")) + .concept(false) + .build(); + + Post post2 = Post.builder() + .id(2L) + .author("John Doe") + .title("Title") + .content("This is a post") + .date(LocalDate.parse("2021-10-10")) + .concept(false) + .build(); + + // Assert + assertThat(post1).isEqualTo(post2); + assertThat(post1.hashCode()).isEqualTo(post2.hashCode()); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/PostService/src/test/java/be/pxl/services/services/PostServicesTest.java b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/services/PostServicesTest.java new file mode 100644 index 000000000..e31419b15 --- /dev/null +++ b/backend-java/Microservices/PostService/src/test/java/be/pxl/services/services/PostServicesTest.java @@ -0,0 +1,283 @@ +package be.pxl.services.services; + +import be.pxl.services.client.NotificationClient; +import be.pxl.services.controller.request.NotificationRequest; +import be.pxl.services.controller.request.PostRequest; +import be.pxl.services.domain.Post; +import be.pxl.services.repository.PostRepository; +import be.pxl.services.service.PostService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class PostServicesTest { + + @Mock + private PostRepository postRepository; + + @Mock + private NotificationClient notificationClient; + + @Mock + private RabbitTemplate rabbitTemplate; + + @InjectMocks + private PostService postService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testGetAllPosts() { + Post post = new Post(); + when(postRepository.findAll()).thenReturn(Collections.singletonList(post)); + + List posts = postService.getAllPosts(); + + assertNotNull(posts); + assertEquals(1, posts.size()); + verify(postRepository, times(1)).findAll(); + } + + @Test + void testGetConceptPosts() { + Post conceptPost = new Post(); + conceptPost.setConcept(true); + when(postRepository.findAll()).thenReturn(Collections.singletonList(conceptPost)); + + List result = postService.getConceptPosts(); + + assertNotNull(result); + assertEquals(1, result.size()); + assertTrue(result.get(0).isConcept()); + verify(postRepository, times(1)).findAll(); + } + + @Test + void testGetPublishedPosts() { + Post publishedPost = new Post(); + publishedPost.setConcept(false); + when(postRepository.findAll()).thenReturn(Collections.singletonList(publishedPost)); + + List result = postService.getPublishedPosts(); + + assertNotNull(result); + assertEquals(1, result.size()); + assertFalse(result.get(0).isConcept()); + verify(postRepository, times(1)).findAll(); + } + + @Test + void testAddPost() { + PostRequest postRequest = new PostRequest("Title", LocalDate.now(),"Content", "Author"); + Post post = new Post(); + when(postRepository.save(any(Post.class))).thenReturn(post); + + Post result = postService.addPost(postRequest); + + assertNotNull(result); + verify(postRepository, times(1)).save(any(Post.class)); + verify(notificationClient, times(1)).sendNotification(any(NotificationRequest.class)); + verify(notificationClient, times(1)).sendEmail(anyString(), anyString(), any(NotificationRequest.class)); + } + + @Test + void testFindPostByTitle() { + Post post = new Post(); + when(postRepository.findByTitle(anyString())).thenReturn(Optional.of(post)); + + Post result = postService.findPostByTitle("Title"); + + assertNotNull(result); + verify(postRepository, times(1)).findByTitle(anyString()); + } + + @Test + void testFindAllPostWithTitle() { + Post post = new Post(); + post.setTitle("Test Title"); + post.setConcept(false); + when(postRepository.findAll()).thenReturn(Collections.singletonList(post)); + + List result = postService.findAllPostWithTitle("Test"); + + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals("Test Title", result.get(0).getTitle()); + verify(postRepository, times(1)).findAll(); + } + + @Test + void testFindPostByContent() { + Post post = new Post(); + post.setContent("Test Content"); + post.setConcept(false); + when(postRepository.findAll()).thenReturn(Collections.singletonList(post)); + + List result = postService.findPostByContent("Test"); + + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals("Test Content", result.get(0).getContent()); + verify(postRepository, times(1)).findAll(); + } + + @Test + void testFindPostByAuthor() { + Post post = new Post(); + post.setAuthor("Test Author"); + post.setConcept(false); + when(postRepository.findAll()).thenReturn(Collections.singletonList(post)); + + List result = postService.findPostByAuthor("Test Author"); + + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals("Test Author", result.get(0).getAuthor()); + verify(postRepository, times(1)).findAll(); + } + + @Test + void testFindPostByDate() { + Post post = new Post(); + post.setDate(LocalDate.of(2023, 10, 10)); + post.setConcept(false); + when(postRepository.findAll()).thenReturn(Collections.singletonList(post)); + + List result = postService.findPostByDate("2023-10-10"); + + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals(LocalDate.of(2023, 10, 10), result.get(0).getDate()); + verify(postRepository, times(1)).findAll(); + } + + @Test + void testGetById() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + + Post result = postService.getById(1L); + + assertNotNull(result); + verify(postRepository, times(1)).findById(anyLong()); + } + + @Test + void testDeletePost() { + doNothing().when(postRepository).deleteAll(); + + postService.deletePost(); + + verify(postRepository, times(1)).deleteAll(); + } + + @Test + void testUpdatePost() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + when(postRepository.save(any(Post.class))).thenReturn(post); + + PostRequest postRequest = new PostRequest("Updated Title", LocalDate.now(),"Updated Content", "Updated Author"); + postService.updatePost(1L, postRequest); + + verify(postRepository, times(1)).findById(anyLong()); + verify(postRepository, times(1)).save(any(Post.class)); + } + + @Test + void testUpdatePostWithTitle() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + when(postRepository.save(any(Post.class))).thenReturn(post); + + PostRequest postRequest = new PostRequest(null, null, "Updated Title", null); + postService.updatePost(1L, postRequest); + + verify(postRepository, times(1)).findById(anyLong()); + verify(postRepository, times(1)).save(any(Post.class)); + assertEquals("Updated Title", post.getTitle()); + } + + @Test + void testUpdatePostWithContent() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + when(postRepository.save(any(Post.class))).thenReturn(post); + + PostRequest postRequest = new PostRequest(null, null, null, "Updated Content"); + postService.updatePost(1L, postRequest); + + verify(postRepository, times(1)).findById(anyLong()); + verify(postRepository, times(1)).save(any(Post.class)); + assertEquals("Updated Content", post.getContent()); + } + + @Test + void testUpdatePostWithAuthor() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + when(postRepository.save(any(Post.class))).thenReturn(post); + + PostRequest postRequest = new PostRequest("Updated Author", null, null, null); + postService.updatePost(1L, postRequest); + + verify(postRepository, times(1)).findById(anyLong()); + verify(postRepository, times(1)).save(any(Post.class)); + assertEquals("Updated Author", post.getAuthor()); + } + + @Test + void testApprovePost() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + + postService.approvePost(1L); + + verify(postRepository, times(1)).findById(anyLong()); + verify(postRepository, times(1)).save(any(Post.class)); + verify(notificationClient, times(1)).sendNotification(any(NotificationRequest.class)); + verify(notificationClient, times(1)).sendEmail(anyString(), anyString(), any(NotificationRequest.class)); + } + + @Test + void testRejectPost() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + + postService.rejectPost(1L); + + verify(postRepository, times(1)).findById(anyLong()); + verify(notificationClient, times(1)).sendNotification(any(NotificationRequest.class)); + verify(notificationClient, times(1)).sendEmail(anyString(), anyString(), any(NotificationRequest.class)); + } + + @Test + void testUpdatePostWithDate() { + Post post = new Post(); + when(postRepository.findById(anyLong())).thenReturn(Optional.of(post)); + when(postRepository.save(any(Post.class))).thenReturn(post); + + LocalDate updatedDate = LocalDate.now(); + PostRequest postRequest = new PostRequest(null, updatedDate, null, null); + postService.updatePost(1L, postRequest); + + verify(postRepository, times(1)).findById(anyLong()); + verify(postRepository, times(1)).save(any(Post.class)); + assertEquals(updatedDate, post.getDate()); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/ReviewService/logs/reviews.log b/backend-java/Microservices/ReviewService/logs/reviews.log new file mode 100644 index 000000000..e69de29bb diff --git a/backend-java/Microservices/ReviewService/pom.xml b/backend-java/Microservices/ReviewService/pom.xml index 280b711ed..ac222531a 100644 --- a/backend-java/Microservices/ReviewService/pom.xml +++ b/backend-java/Microservices/ReviewService/pom.xml @@ -31,16 +31,34 @@ org.springframework.cloud spring-cloud-starter-config + + org.springframework.cloud + spring-cloud-starter-openfeign + junit junit - 3.8.1 + 4.13.2 test org.springframework.cloud spring-cloud-commons + + org.springframework.amqp + spring-rabbit + + + org.testcontainers + mysql + test + + + org.testcontainers + junit-jupiter + test + diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java index 38bc838ad..0bf5c4a12 100644 --- a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/ReviewServiceApplication.java @@ -3,6 +3,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; /** * Hello world! @@ -10,6 +11,7 @@ */ @SpringBootApplication @EnableDiscoveryClient +@EnableFeignClients public class ReviewServiceApplication { public static void main( String[] args ) diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/client/NotificationClient.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/client/NotificationClient.java new file mode 100644 index 000000000..c721b5103 --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/client/NotificationClient.java @@ -0,0 +1,13 @@ +package be.pxl.services.client; + +import be.pxl.services.controller.request.NotificationRequest; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = "notification-service") +public interface NotificationClient { + + @PostMapping("/notification") + void sendNotification(@RequestBody NotificationRequest notificationRequest); +} diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/ReviewController.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/ReviewController.java new file mode 100644 index 000000000..69e20ca59 --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/ReviewController.java @@ -0,0 +1,53 @@ +package be.pxl.services.controller; + +import be.pxl.services.controller.request.ReviewRequest; +import be.pxl.services.domain.Review; +import be.pxl.services.service.ReviewService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("api/reviews") +@RequiredArgsConstructor +public class ReviewController { + private final ReviewService reviewService; + + + @GetMapping + public ResponseEntity> getAllReviews() { + List reviews = reviewService.getAllReviews(); + return new ResponseEntity<>(reviews, HttpStatus.OK); + } + + @GetMapping("/{postId}") + public ResponseEntity> getReviewsByPostId(@PathVariable Long postId) { + List reviews = reviewService.getAllReviewsByPostId(postId); + return new ResponseEntity<>(reviews, HttpStatus.OK); + } + + @PostMapping + public ResponseEntity createReview(@RequestParam Long postId) { + reviewService.createReview(postId); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping("/review/{postId}") + public ResponseEntity completeReview(@RequestHeader("User-Role") String userRole, @PathVariable Long postId, @RequestBody ReviewRequest review) { + if(userRole.equals("editor")) { + Review updatedReview = reviewService.completeReview(postId, review); + return new ResponseEntity<>(updatedReview, HttpStatus.OK); + }else { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } + } + +// @DeleteMapping("/{postId}") +// public ResponseEntity deleteReview(@PathVariable Long postId) { +// reviewService.deleteReview(postId); +// return new ResponseEntity<>(HttpStatus.NO_CONTENT); +// } +} diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java new file mode 100644 index 000000000..e5e90d5e0 --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/NotificationRequest.java @@ -0,0 +1,17 @@ +package be.pxl.services.controller.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class NotificationRequest { + + private String message; + private String sender; + +} diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/ReviewRequest.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/ReviewRequest.java new file mode 100644 index 000000000..12672f793 --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/controller/request/ReviewRequest.java @@ -0,0 +1,4 @@ +package be.pxl.services.controller.request; + +public record ReviewRequest (String description, boolean approved) { +} diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/domain/Review.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/domain/Review.java new file mode 100644 index 000000000..c164cdb21 --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/domain/Review.java @@ -0,0 +1,22 @@ +package be.pxl.services.domain; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Table(name = "reviews") +@Entity +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Review { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private Long postId; + private String description; + private boolean approved; +} diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/repository/ReviewRepository.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/repository/ReviewRepository.java new file mode 100644 index 000000000..4c54e3181 --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/repository/ReviewRepository.java @@ -0,0 +1,13 @@ +package be.pxl.services.repository; + +import be.pxl.services.domain.Review; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ReviewRepository extends JpaRepository { + Review findFirstByPostId(Long postId); + List findAllByPostId(Long postId); +} diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/IReviewService.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/IReviewService.java new file mode 100644 index 000000000..5888a28ac --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/IReviewService.java @@ -0,0 +1,15 @@ +package be.pxl.services.service; + +import be.pxl.services.controller.request.ReviewRequest; +import be.pxl.services.domain.Review; + +import java.util.List; + +public interface IReviewService { + List getAllReviews(); + List getAllReviewsByPostId(Long postId); + void createReview(Long postId); + Review completeReview(Long postId, ReviewRequest reviewRequest); +// void deleteReview(Long postId); + +} diff --git a/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/ReviewService.java b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/ReviewService.java new file mode 100644 index 000000000..a0129472f --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/java/be/pxl/services/service/ReviewService.java @@ -0,0 +1,90 @@ +package be.pxl.services.service; + +import be.pxl.services.client.NotificationClient; +import be.pxl.services.controller.request.NotificationRequest; +import be.pxl.services.controller.request.ReviewRequest; +import be.pxl.services.domain.Review; +import be.pxl.services.repository.ReviewRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ReviewService implements IReviewService { + private final ReviewRepository reviewRepository; + private final NotificationClient notificationClient; + private final RabbitTemplate rabbitTemplate; + private static Logger logger = LoggerFactory.getLogger(ReviewService.class.getName()); + + + @Override + public List getAllReviews() { + logger.info("Fetching all reviews"); + return reviewRepository.findAll(); + } + + @Override + public List getAllReviewsByPostId(Long postId) { + logger.info("Fetching all reviews by post id: {}", postId); + return reviewRepository.findAllByPostId(postId); + } + + @RabbitListener(queues = "postCreatedQueue") + @Override + public void createReview(Long postId) { + Review review = new Review(); + review.setPostId(postId); + reviewRepository.save(review); + sendNotification("New review intitialized for post " + postId, "ReviewService"); + rabbitTemplate.convertAndSend("postReviewQueue", postId); + log.info("Review created for post with id: " + postId); + logger.info("Review created for post with id: {}", postId); + } + + + @Override + public Review completeReview(Long postId, ReviewRequest reviewRequest) { + Review review = reviewRepository.findFirstByPostId(postId); + if(review.isApproved() || review.getDescription() != null){ + Review newReview = new Review(); + newReview.setPostId(postId); + newReview.setDescription(reviewRequest.description()); + newReview.setApproved(reviewRequest.approved()); + reviewRepository.save(newReview); + sendNotification("New review added for post " + postId, "ReviewService"); + sendMassTransitNotification(postId, reviewRequest); + logger.info("Review completed for post with id: {}", postId); + return newReview; + } + + review.setDescription(reviewRequest.description()); + review.setApproved(reviewRequest.approved()); + reviewRepository.save(review); + sendNotification("Review updated for post " + postId, "ReviewService"); + sendMassTransitNotification(postId, reviewRequest); + logger.info("Review completed for post with id: {}", postId); + return review; + } + + public void sendNotification(String message, String sender){ + NotificationRequest notificationRequest = NotificationRequest.builder().message(message).sender(sender).build(); + notificationClient.sendNotification(notificationRequest); + } + + public void sendMassTransitNotification(Long postId, ReviewRequest reviewRequest){ + if(reviewRequest.approved()){ + rabbitTemplate.convertAndSend("postApprovedQueue", postId); + }else{ + rabbitTemplate.convertAndSend("postRejectedQueue", postId); + } + rabbitTemplate.convertAndSend("postReviewQueue", postId); + } +} diff --git a/backend-java/Microservices/ReviewService/src/main/resources/logback.xml b/backend-java/Microservices/ReviewService/src/main/resources/logback.xml new file mode 100644 index 000000000..7903e09d2 --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + logs/reviews.log + true + + %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java index 086f1e2ee..b78e1f600 100644 --- a/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java +++ b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/ReviewServiceApplicationTest.java @@ -4,35 +4,17 @@ import junit.framework.TestCase; import junit.framework.TestSuite; -/** - * Unit test for simple App. - */ -public class ReviewServiceApplicationTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public ReviewServiceApplicationTest(String testName ) - { - super( testName ); +public class ReviewServiceApplicationTest extends TestCase { + + public ReviewServiceApplicationTest(String testName) { + super(testName); } - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( ReviewServiceApplicationTest.class ); + public static Test suite() { + return new TestSuite(ReviewServiceApplicationTest.class); } - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); + public void testApp() { + assertTrue(true); } } diff --git a/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/controller/ReviewControllerTest.java b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/controller/ReviewControllerTest.java new file mode 100644 index 000000000..eb84e803d --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/controller/ReviewControllerTest.java @@ -0,0 +1,120 @@ +package be.pxl.services.controller; + +import be.pxl.services.controller.request.ReviewRequest; +import be.pxl.services.domain.Review; +import be.pxl.services.repository.ReviewRepository; +import be.pxl.services.service.ReviewService; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import java.util.Arrays; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc +@Testcontainers +public class ReviewControllerTest { + + @Mock + private ReviewService reviewService; + + @InjectMocks + private ReviewController reviewController; + + @Autowired + private ReviewRepository reviewRepository; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Container + private static final MySQLContainer sqlContainer = new MySQLContainer("mysql:5.7.37"); + + @DynamicPropertySource + static void registerMySQLProperties(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", sqlContainer::getJdbcUrl); + registry.add("spring.datasource.username", sqlContainer::getUsername); + registry.add("spring.datasource.password", sqlContainer::getPassword); + } + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + reviewRepository.deleteAll(); + Review review1 = new Review(1L, 3L, "description", true); + Review review2 = new Review(2L, 8L, "description", false); + reviewRepository.saveAll(Arrays.asList(review1, review2)); + } + + @Test + void testGetAllReviews() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/api/reviews")) + .andExpect(status().isOk()); + } + + @Test + void testGetReviewsByPostId() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/api/reviews/{id}", 1L)) + .andExpect(status().isOk()); + } + + @Test + void testCreateReview() throws Exception { + Review review = Review.builder() + .id(4L) + .postId(3L) + .description("description") + .approved(false) + .build(); + String reviewString = objectMapper.writeValueAsString(review); + mockMvc.perform(MockMvcRequestBuilders.post("/api/reviews") + .contentType("application/json") + .param("postId", "3") + .content(reviewString)) + .andExpect(status().isCreated()); + } + + @Test + void testCompleteReviewWithEditorRole() throws Exception { + ReviewRequest reviewRequest = new ReviewRequest("description", true); + String reviewString = objectMapper.writeValueAsString(reviewRequest); + + mockMvc.perform(MockMvcRequestBuilders.put("/api/reviews/review/{id}", 3L) + .contentType(MediaType.APPLICATION_JSON) + .header("User-Role", "editor") + .content(reviewString)) + .andExpect(status().isOk()); + } + + @Test + void testCompleteReviewWithUnauthorizedRole() throws Exception { + ReviewRequest reviewRequest = new ReviewRequest("description", true); + String reviewString = objectMapper.writeValueAsString(reviewRequest); + + mockMvc.perform(MockMvcRequestBuilders.put("/api/reviews/review/{id}", 8L) + .contentType("application/json") + .header("User-Role", "user") + .content(reviewString)) + .andExpect(status().isUnauthorized()); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/domain/ReviewTest.java b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/domain/ReviewTest.java new file mode 100644 index 000000000..69e1217dd --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/domain/ReviewTest.java @@ -0,0 +1,39 @@ +package be.pxl.services.domain; import org.junit.jupiter.api.Test; +import java.time.LocalDate; +import static org.assertj.core.api.Assertions.assertThat; + +public class ReviewTest { @Test void testReviewCreation() { + // Arrange + Review review = Review.builder() + .id(2L) + .postId(1L) + .description("This is a review") + .approved(false) + .build(); + + // Assert + assertThat(review).isNotNull(); + assertThat(review.getId()).isEqualTo(2L); + assertThat(review.getPostId()).isEqualTo(1L); + assertThat(review.getDescription()).isEqualTo("This is a review"); + assertThat(review.isApproved()).isFalse(); +} + + @Test + void testReviewSettersAndGetters() { + // Arrange + Review review = new Review(); + + // Act + review.setId(2L); + review.setPostId(1L); + review.setDescription("This is a review"); + review.setApproved(false); + + // Assert + assertThat(review.getId()).isEqualTo(2L); + assertThat(review.getPostId()).isEqualTo(1L); + assertThat(review.getDescription()).isEqualTo("This is a review"); + assertThat(review.isApproved()).isEqualTo(false); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/services/ReviewServiceTest.java b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/services/ReviewServiceTest.java new file mode 100644 index 000000000..9a9f696dd --- /dev/null +++ b/backend-java/Microservices/ReviewService/src/test/java/be/pxl/services/services/ReviewServiceTest.java @@ -0,0 +1,132 @@ +package be.pxl.services.services; + +import be.pxl.services.client.NotificationClient; +import be.pxl.services.controller.request.ReviewRequest; +import be.pxl.services.domain.Review; +import be.pxl.services.repository.ReviewRepository; +import be.pxl.services.service.ReviewService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.amqp.rabbit.core.RabbitTemplate; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class ReviewServiceTest { + + @Mock + private ReviewRepository reviewRepository; + + @Mock + private NotificationClient notificationClient; + + @Mock + private RabbitTemplate rabbitTemplate; + + @InjectMocks + private ReviewService reviewService; + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void testGetAllReviews() { + Review review1 = new Review(); + Review review2 = new Review(); + when(reviewRepository.findAll()).thenReturn(Arrays.asList(review1, review2)); + + List reviews = reviewService.getAllReviews(); + + assertEquals(2, reviews.size()); + verify(reviewRepository, times(1)).findAll(); + } + + @Test + public void testGetAllReviewsByPostId() { + Long postId = 1L; + Review review1 = new Review(); + Review review2 = new Review(); + when(reviewRepository.findAllByPostId(postId)).thenReturn(Arrays.asList(review1, review2)); + + List reviews = reviewService.getAllReviewsByPostId(postId); + + assertEquals(2, reviews.size()); + verify(reviewRepository, times(1)).findAllByPostId(postId); + } + + @Test + public void testCreateReview() { + Long postId = 1L; + doNothing().when(rabbitTemplate).convertAndSend(anyString(), anyLong()); + doNothing().when(notificationClient).sendNotification(any()); + + reviewService.createReview(postId); + + verify(reviewRepository, times(1)).save(any(Review.class)); + verify(rabbitTemplate, times(1)).convertAndSend("postReviewQueue", postId); + } + + @Test + public void testCompleteReview() { + Long postId = 1L; + ReviewRequest reviewRequest = new ReviewRequest("description", true); + Review review = new Review(); + review.setPostId(postId); + when(reviewRepository.findFirstByPostId(postId)).thenReturn(review); + + Review completedReview = reviewService.completeReview(postId, reviewRequest); + + assertEquals("description", completedReview.getDescription()); + assertEquals(true, completedReview.isApproved()); + verify(reviewRepository, times(1)).save(review); + verify(notificationClient, times(1)).sendNotification(any()); + verify(rabbitTemplate, times(1)).convertAndSend("postApprovedQueue", postId); + } + + @Test + public void testCompleteReviewWithNewReview() { + Long postId = 1L; + ReviewRequest reviewRequest = new ReviewRequest("description", true); + Review existingReview = new Review(); + existingReview.setPostId(postId); + existingReview.setApproved(true); // This will trigger the if condition + + when(reviewRepository.findFirstByPostId(postId)).thenReturn(existingReview); + + Review completedReview = reviewService.completeReview(postId, reviewRequest); + + assertEquals("description", completedReview.getDescription()); + assertEquals(true, completedReview.isApproved()); + verify(reviewRepository, times(1)).save(any(Review.class)); + verify(notificationClient, times(1)).sendNotification(any()); + verify(rabbitTemplate, times(1)).convertAndSend("postApprovedQueue", postId); + } + + @Test + public void testCompleteReviewWithDescription() { + Long postId = 1L; + ReviewRequest reviewRequest = new ReviewRequest("description", true); + Review existingReview = new Review(); + existingReview.setPostId(postId); + existingReview.setDescription("existing description"); // This will trigger the if condition + + when(reviewRepository.findFirstByPostId(postId)).thenReturn(existingReview); + + Review completedReview = reviewService.completeReview(postId, reviewRequest); + + assertEquals("description", completedReview.getDescription()); + assertEquals(true, completedReview.isApproved()); + verify(reviewRepository, times(1)).save(any(Review.class)); + verify(notificationClient, times(1)).sendNotification(any()); + verify(rabbitTemplate, times(1)).convertAndSend("postApprovedQueue", postId); + } +} \ No newline at end of file diff --git a/backend-java/Microservices/pom.xml b/backend-java/Microservices/pom.xml index 32da8239b..decf1b1db 100644 --- a/backend-java/Microservices/pom.xml +++ b/backend-java/Microservices/pom.xml @@ -27,7 +27,11 @@ CommentService DiscoveryService ConfigService - + NotificationService + NotificationService + GatewayService + MessagingService + diff --git a/backend-java/Microservices/src/main/resources/application.properties b/backend-java/Microservices/src/main/resources/application.properties index 66b4c04b1..ce3c963e8 100644 --- a/backend-java/Microservices/src/main/resources/application.properties +++ b/backend-java/Microservices/src/main/resources/application.properties @@ -1 +1,2 @@ spring.application.name=Microservices + diff --git a/frontend-web/.idea/.gitignore b/frontend-web/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/frontend-web/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/frontend-web/.idea/frontend-web.iml b/frontend-web/.idea/frontend-web.iml new file mode 100644 index 000000000..d6ebd4805 --- /dev/null +++ b/frontend-web/.idea/frontend-web.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/frontend-web/.idea/misc.xml b/frontend-web/.idea/misc.xml new file mode 100644 index 000000000..45091de93 --- /dev/null +++ b/frontend-web/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/frontend-web/.idea/modules.xml b/frontend-web/.idea/modules.xml new file mode 100644 index 000000000..e0d27b4d3 --- /dev/null +++ b/frontend-web/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/frontend-web/.idea/vcs.xml b/frontend-web/.idea/vcs.xml new file mode 100644 index 000000000..6c0b86358 --- /dev/null +++ b/frontend-web/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/frontend-web/Frontend/.editorconfig b/frontend-web/Frontend/.editorconfig new file mode 100644 index 000000000..f166060da --- /dev/null +++ b/frontend-web/Frontend/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/frontend-web/Frontend/.gitignore b/frontend-web/Frontend/.gitignore new file mode 100644 index 000000000..cc7b14135 --- /dev/null +++ b/frontend-web/Frontend/.gitignore @@ -0,0 +1,42 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/frontend-web/Frontend/.vscode/extensions.json b/frontend-web/Frontend/.vscode/extensions.json new file mode 100644 index 000000000..77b374577 --- /dev/null +++ b/frontend-web/Frontend/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/frontend-web/Frontend/.vscode/launch.json b/frontend-web/Frontend/.vscode/launch.json new file mode 100644 index 000000000..925af8370 --- /dev/null +++ b/frontend-web/Frontend/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/frontend-web/Frontend/.vscode/tasks.json b/frontend-web/Frontend/.vscode/tasks.json new file mode 100644 index 000000000..a298b5bd8 --- /dev/null +++ b/frontend-web/Frontend/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/frontend-web/Frontend/README.md b/frontend-web/Frontend/README.md new file mode 100644 index 000000000..d5242f769 --- /dev/null +++ b/frontend-web/Frontend/README.md @@ -0,0 +1,59 @@ +# Frontend + +This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.0.1. + +## Development server + +To start a local development server, run: + +```bash +ng serve +``` + +Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. + +## Code scaffolding + +Angular CLI includes powerful code scaffolding tools. To generate a new component, run: + +```bash +ng generate component component-name +``` + +For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: + +```bash +ng generate --help +``` + +## Building + +To build the project run: + +```bash +ng build +``` + +This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. + +## Running unit tests + +To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command: + +```bash +ng test +``` + +## Running end-to-end tests + +For end-to-end (e2e) testing, run: + +```bash +ng e2e +``` + +Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. + +## Additional Resources + +For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/frontend-web/Frontend/angular.json b/frontend-web/Frontend/angular.json new file mode 100644 index 000000000..ed6e1e288 --- /dev/null +++ b/frontend-web/Frontend/angular.json @@ -0,0 +1,96 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "Frontend": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/frontend", + "index": "src/index.html", + "browser": "src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "Frontend:build:production" + }, + "development": { + "buildTarget": "Frontend:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ], + "scripts": [] + } + } + } + } + } +} diff --git a/frontend-web/Frontend/package-lock.json b/frontend-web/Frontend/package-lock.json new file mode 100644 index 000000000..523146754 --- /dev/null +++ b/frontend-web/Frontend/package-lock.json @@ -0,0 +1,15575 @@ +{ + "name": "frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.1", + "@angular/cli": "^19.0.1", + "@angular/compiler-cli": "^19.0.0", + "@types/jasmine": "~5.1.0", + "jasmine-core": "~5.4.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "tailwindcss": "^3.4.15", + "typescript": "~5.6.2" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1900.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1900.1.tgz", + "integrity": "sha512-4SONLz5lzuNINz5DAaZlQLhBasLqEiDKMH+YHYgYE2N3ImfuYj9urgfdRnfarPInQslCE9OzahOQslVzoQxJhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.0.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.0.1.tgz", + "integrity": "sha512-XF/jkBFchpwQzSS0efVk1MNvcTYI4FCBsRmneLkprfftoi9e9A2IqUk8GJncNj3MIa/wZ1bNnzp+Z0uGGqrb6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.1", + "@angular-devkit/build-webpack": "0.1900.1", + "@angular-devkit/core": "19.0.1", + "@angular/build": "19.0.1", + "@babel/core": "7.26.0", + "@babel/generator": "7.26.2", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.25.9", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.25.9", + "@babel/preset-env": "7.26.0", + "@babel/runtime": "7.26.0", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "19.0.1", + "@vitejs/plugin-basic-ssl": "1.1.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.2.1", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", + "esbuild-wasm": "0.24.0", + "fast-glob": "3.3.2", + "http-proxy-middleware": "3.0.3", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.0", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.0", + "ora": "5.4.1", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "postcss": "8.4.49", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.80.7", + "sass-loader": "16.0.3", + "semver": "7.6.3", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.36.0", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.96.1", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.1.0", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.24.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.1", + "@web/test-runner": "^0.19.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^19.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1900.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1900.1.tgz", + "integrity": "sha512-WTlSE5tWJCTD22GQO8LFPYFL4eEFStHubo7zJpjFnf5gJPwcKMcV323LeEviHyudQz5eQ2SiVpDOqsC13IP6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.1900.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/core": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.0.1.tgz", + "integrity": "sha512-oXIAV3hXqUW3Pmm95pvEmb+24n1cKQG62FzhQSjOIrMeHiCbGLNuc8zHosIi2oMrcCJJxR6KzWjThvbuzDwWlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.0.1.tgz", + "integrity": "sha512-N9dV8WpNRULykNj8fSxQrta85gPKxb315J3xugLS2uwiFWhz7wo5EY1YeYhoVKoVcNB2ng9imJgC5aO52AHZwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.0.1", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.12", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/animations": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.0.0.tgz", + "integrity": "sha512-+uZTvEXjYh8PZKB4ijk8uuH1K+Tz/A67mUlltFv9pYKtnmbZAeS/PI66g/7pigRYDvEgid1fvlAANeBShAiPZQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.0" + } + }, + "node_modules/@angular/build": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.0.1.tgz", + "integrity": "sha512-Aodt+EsGQyM8LVG/GjeMAC7BQ4z14SmtUbu6S54mAjGn9uiiYixszAi3fM4SsaQZRK9m0Lwv3a151rw2yZUJow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1900.1", + "@babel/core": "7.26.0", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.26.0", + "@inquirer/confirm": "5.0.2", + "@vitejs/plugin-basic-ssl": "1.1.0", + "beasties": "0.1.0", + "browserslist": "^4.23.0", + "esbuild": "0.24.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.3", + "listr2": "8.2.5", + "magic-string": "0.30.12", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.7.0", + "rollup": "4.26.0", + "sass": "1.80.7", + "semver": "7.6.3", + "vite": "5.4.11", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.1.5" + }, + "peerDependencies": { + "@angular/compiler": "^19.0.0", + "@angular/compiler-cli": "^19.0.0", + "@angular/localize": "^19.0.0", + "@angular/platform-server": "^19.0.0", + "@angular/service-worker": "^19.0.0", + "@angular/ssr": "^19.0.1", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.5 <5.7" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/cli": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.0.1.tgz", + "integrity": "sha512-vn+assDJoTQyHKSiWorduJ4JDlPyLSJ8M4EHod9Kdn8XT26dEwubTh6o70GkFNEiZ7TSSqQbrAEYuGVJwMRQjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.1900.1", + "@angular-devkit/core": "19.0.1", + "@angular-devkit/schematics": "19.0.1", + "@inquirer/prompts": "7.1.0", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.0.1", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.0", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.8", + "semver": "7.6.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.0.0.tgz", + "integrity": "sha512-kb2iS26GZS0vyR3emAQbIiQifnK5M5vnbclEHni+pApDEU5V9FufbdRP3vCxs28UHZvAZKB0LrxkTrnT6T+z5g==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.0.0.tgz", + "integrity": "sha512-Uw2Yy25pdqfzKsS9WofnIq1zvknlVYyy03LYO7NMKHlFWiy8q8SIXN7WKPFhiHlOfyACXipp4eZb9m3+IbOfSA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.0.0" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.0.0.tgz", + "integrity": "sha512-2PxpsIeppoDLAx7A6i0GE10WjC+Fkz8tTQioa7r4y/+eYnniEjJFIQM/8lbkOnRVcuYoeXoNyYWr3fEQAyO4LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.26.0", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "19.0.0", + "typescript": ">=5.5 <5.7" + } + }, + "node_modules/@angular/core": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.0.0.tgz", + "integrity": "sha512-aNG2kd30BOM/zf0jC+aEVG8OA27IwqCki9EkmyRNYnaP2O5Mj1n7JpCyZGI+0LrWTJ2UUCfRNZiZdZwmNThr1Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + } + }, + "node_modules/@angular/forms": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.0.0.tgz", + "integrity": "sha512-gM4bUdlIJ0uRYNwoVMbXiZt4+bZzPXzyQ7ByNIOVKEAI0PN9Jz1dR1pSeQgIoUvKQbhwsVKVUoa7Tn1hoqwvTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.0", + "@angular/core": "19.0.0", + "@angular/platform-browser": "19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.0.0.tgz", + "integrity": "sha512-g9Qkv+KgEmXLVeg+dw1edmWsRBspUGeJMOBf2UX1kUCw6txeco+pzCMimouB5LQYHfs6cD6oC+FwINm0HNwrhg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.0.0", + "@angular/common": "19.0.0", + "@angular/core": "19.0.0" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.0.0.tgz", + "integrity": "sha512-ljvycDe0etmTBDzbCFakpsItywddpKEyCZGMKRvz5TdND1N1qqXydxAF1kLzP5H7F/QOMdP4/T/T1HS+6AUpkw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.0", + "@angular/compiler": "19.0.0", + "@angular/core": "19.0.0", + "@angular/platform-browser": "19.0.0" + } + }, + "node_modules/@angular/router": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.0.0.tgz", + "integrity": "sha512-uFyT8DWVLGY8k0AZjpK7iyMO/WwT4/+b09Ax0uUEbdcRxTXSOg8/U/AVzQWtxzxI80/vJE2WZMmhIJFUTYwhKA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.0.0", + "@angular/core": "19.0.0", + "@angular/platform-browser": "19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", + "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", + "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", + "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.2.tgz", + "integrity": "sha512-+gznPl8ip8P8HYHYecDtUtdsh1t2jvb+sWCD72GAiZ9m45RqwrLmReDaqdC0umQfamtFXVRoMVJ2/qINKGm9Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.0.2.tgz", + "integrity": "sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.0.tgz", + "integrity": "sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/editor": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.1.0.tgz", + "integrity": "sha512-K1gGWsxEqO23tVdp5MT3H799OZ4ER1za7Dlc8F4um0W7lwSv0KGR/YyrUEyimj0g7dXZd8XknM/5QA2/Uy+TbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.2.tgz", + "integrity": "sha512-WdgCX1cUtinz+syKyZdJomovULYlKUWZbVYZzhf+ZeeYf4htAQ3jLymoNs3koIAKfZZl3HUBb819ClCBfyznaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.0.2.tgz", + "integrity": "sha512-yCLCraigU085EcdpIVEDgyfGv4vBiE4I+k1qRkc9C5dMjWF42ADMGy1RFU94+eZlz4YlkmFsiyHZy0W1wdhaNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.2.tgz", + "integrity": "sha512-MKQhYofdUNk7eqJtz52KvM1dH6R93OMrqHduXCvuefKrsiMjHiMwjc3NZw5Imm2nqY7gWd9xdhYrtcHMJQZUxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.2.tgz", + "integrity": "sha512-tQXGSu7IO07gsYlGy3VgXRVsbOWqFBMbqAUrJSc1PDTQQ5Qdm+QVwkP0OC0jnUZ62D19iPgXOMO+tnWG+HhjNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.1.0.tgz", + "integrity": "sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.0.2", + "@inquirer/confirm": "^5.0.2", + "@inquirer/editor": "^4.1.0", + "@inquirer/expand": "^4.0.2", + "@inquirer/input": "^4.0.2", + "@inquirer/number": "^3.0.2", + "@inquirer/password": "^4.0.2", + "@inquirer/rawlist": "^4.0.2", + "@inquirer/search": "^3.0.2", + "@inquirer/select": "^4.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.2.tgz", + "integrity": "sha512-3XGcskMoVF8H0Dl1S5TSZ3rMPPBWXRcM0VeNVsS4ByWeWjSeb0lPqfnBg6N7T0608I1B2bSVnbi2cwCrmOD1Yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.2.tgz", + "integrity": "sha512-Zv4FC7w4dJ13BOJfKRQCICQfShinGjb1bCEIHxTSnjj2telu3+3RHwHubPG9HyD4aix5s+lyAMEK/wSFD75HLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.2.tgz", + "integrity": "sha512-uSWUzaSYAEj0hlzxa1mUB6VqrKaYx0QxGBLZzU4xWFxaSyGaXxsSE4OSOwdU24j0xl8OajgayqFXW0l2bkl2kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", + "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", + "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", + "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.1.5.tgz", + "integrity": "sha512-ue5PSOzHMCIYrfvPP/MRS6hsKKLzqqhcdAvJCO8uFlDdj598EhgnacuOTuqA6uBK5rgiZXfDWyb7DVZSiBKxBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.1.5.tgz", + "integrity": "sha512-CGhsb0R5vE6mMNCoSfxHFD8QTvBHM51gs4DBeigTYHWnYv2V5YpJkC4rMo5qAAFifuUcc0+a8a3SIU0c9NrfNw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.1.5.tgz", + "integrity": "sha512-3WeW328DN+xB5PZdhSWmqE+t3+44xWXEbqQ+caWJEZfOFdLp9yklBZEbVqVdqzznkoaXJYxTCp996KD6HmANeg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.1.5.tgz", + "integrity": "sha512-LAjaoOcBHGj6fiYB8ureiqPoph4eygbXu4vcOF+hsxiY74n8ilA7rJMmGUT0K0JOB5lmRQHSmor3mytRjS4qeQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.1.5.tgz", + "integrity": "sha512-k/IklElP70qdCXOQixclSl2GPLFiopynGoKX1FqDd1/H0E3Fo1oPwjY2rEVu+0nS3AOw1sryStdXk8CW3cVIsw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.1.5.tgz", + "integrity": "sha512-KYar6W8nraZfSJspcK7Kp7hdj238X/FNauYbZyrqPBrtsXI1hvI4/KcRcRGP50aQoV7fkKDyJERlrQGMGTZUsA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", + "integrity": "sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.1", + "@napi-rs/nice-android-arm64": "1.0.1", + "@napi-rs/nice-darwin-arm64": "1.0.1", + "@napi-rs/nice-darwin-x64": "1.0.1", + "@napi-rs/nice-freebsd-x64": "1.0.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.1", + "@napi-rs/nice-linux-arm64-gnu": "1.0.1", + "@napi-rs/nice-linux-arm64-musl": "1.0.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.1", + "@napi-rs/nice-linux-s390x-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-gnu": "1.0.1", + "@napi-rs/nice-linux-x64-musl": "1.0.1", + "@napi-rs/nice-win32-arm64-msvc": "1.0.1", + "@napi-rs/nice-win32-ia32-msvc": "1.0.1", + "@napi-rs/nice-win32-x64-msvc": "1.0.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.0.1.tgz", + "integrity": "sha512-qi274Ge8TS//IUyhaUiqcu/GCIL4uybFgm+uCCzu0Bvmww1X+vFZvd6bPaMNNMY1wf0IWbG6aZyt04noYH8Xzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0", + "typescript": ">=5.5 <5.7", + "webpack": "^5.54.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.1.tgz", + "integrity": "sha512-BBWMMxeQzalmKadyimwb2/VVQyJB01PH0HhVSNLHNBDZN/M/h/02P6f8fxedIiFhpMj11SO9Ep5tKTBE7zL2nw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.0.1.tgz", + "integrity": "sha512-YW6PZ99sc1Q4DINEY2td5z9Z3rwbbsx7CyCnOc7UXUUdePXh5gPi1UeaoQVmKQMVbIU7aOwX2l1OG5ZfjgGi5g==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "normalize-package-data": "^7.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.0.0.tgz", + "integrity": "sha512-/1uFzjVcfzqrgCeGW7+SZ4hv0qLWmKXVzFahZGJ6QuJBj6Myt9s17+JL86i76NV9YSnJRcGXJYQbAU0rn1YTCQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.0.1.tgz", + "integrity": "sha512-q9C0uHrb6B6cm3qXVM32UmpqTKuFGbtP23O2K5sLvPMz2hilKd0ptqGXSpuunOuOmPQb/aT5F/kCXFc1P2gO/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz", + "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz", + "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz", + "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz", + "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz", + "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz", + "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz", + "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz", + "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz", + "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz", + "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz", + "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz", + "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz", + "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz", + "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz", + "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz", + "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz", + "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz", + "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.0.1.tgz", + "integrity": "sha512-zjUv+D8j21dmWgJrNCgav3njb06509Mwy7/ZIC5TMyzWfRsrNlrHLEam/tasi4dt171d5mj9A+IlXeEPnWoNCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.0.1", + "@angular-devkit/schematics": "19.0.1", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.0.0.tgz", + "integrity": "sha512-XDUYX56iMPAn/cdgh/DTJxz5RWmqKV4pwvUAEKEWJl+HzKdCd/24wUa9JYNMlDSCb7SUHAdtksxYX779Nne/Zg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.0.0.tgz", + "integrity": "sha512-UjhDMQOkyDoktpXoc5YPJpJK6IooF2gayAr5LvXI4EL7O0vd58okgfRcxuaH+YTdhvb5aa1Q9f+WJ0c2sVuYIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^14.0.1", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign/node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sigstore/sign/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sigstore/sign/node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/@sigstore/sign/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@sigstore/sign/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@sigstore/sign/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.0.0.tgz", + "integrity": "sha512-9Xxy/8U5OFJu7s+OsHzI96IX/OzjF/zj0BSSaWhgJgTqtlBhQIV2xdrQI5qxLD7+CWWDepadnXAxzaZ3u9cvRw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.0.0.tgz", + "integrity": "sha512-Ggtq2GsJuxFNUvQzLoXqRwS4ceRfLAJnrIHUDrzAD0GgnOhwujJkKkxM/s5Bako07c3WtAs/sZo5PJq7VHjeDg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz", + "integrity": "sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", + "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz", + "integrity": "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.6.0" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/beasties": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.1.0.tgz", + "integrity": "sha512-+Ssscd2gVG24qRNC+E2g88D+xsQW4xwakWtKAiGEQ3Pw54/FGdyo9RrfxhGhEv6ilFVbB7r3Lgx+QnAxnSpECw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^9.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-media-query-parser": "^0.2.3" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001683", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001683.tgz", + "integrity": "sha512-iqmNnThZ0n70mNwvxpEC2nBJ037ZHZUoBI5Gorh1Mw6IlEAZujEoU1tXA628iZfzm7R9FvFzxbfdgml82a3k8Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true, + "license": "ISC" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.64", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.64.tgz", + "integrity": "sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", + "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.0.tgz", + "integrity": "sha512-xhNn5tL1AhkPg4ft59yXT6FkwKXiPSYyz1IeinJHUJpjvOHOIPvdmFQc0pGdjxlKSbzZc2mNmtVOWAR1EF/JAg==", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.2.tgz", + "integrity": "sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz", + "integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", + "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", + "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", + "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.1.5.tgz", + "integrity": "sha512-46Mch5Drq+A93Ss3gtbg+Xuvf5BOgIuvhKDWoGa3HcPHI6BL2NCOkRdSx1D4VfzwrxhnsjbyIVsLRlQHu6URvw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.1.5", + "@lmdb/lmdb-darwin-x64": "3.1.5", + "@lmdb/lmdb-linux-arm": "3.1.5", + "@lmdb/lmdb-linux-arm64": "3.1.5", + "@lmdb/lmdb-linux-x64": "3.1.5", + "@lmdb/lmdb-win32-x64": "3.1.5" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/make-fetch-happen/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/make-fetch-happen/node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen/node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.14.0.tgz", + "integrity": "sha512-JUeY0F/fQZgIod31Ja1eJgiSxLn7BfQlCnqhwXFBzFHEw63OdLK7VJUJ7bnzNsWgCyoUP5tEp1VRY8rDaYzqOA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "license": "MIT", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", + "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-7.0.0.tgz", + "integrity": "sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.0.tgz", + "integrity": "sha512-ZTE0hbwSdTNL+Stx2zxSqdu2KZfNDcrtrLdIk7XGnQFYBWYDho/ORvXtn5XEePcL3tFpGjHCV3X3xrtDh7eZ+A==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", + "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm-registry-fetch/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm-registry-fetch/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm-registry-fetch/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", + "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", + "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/piscina": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.7.0.tgz", + "integrity": "sha512-b8hvkpp9zS0zsfa939b/jXbe64Z2gZv0Ha7FYPNUiDIB1y2AtxcOZdfP8xN8HFjUaqQiT9gRlfjAsoL8vdJ1Iw==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz", + "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz", + "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.26.0", + "@rollup/rollup-android-arm64": "4.26.0", + "@rollup/rollup-darwin-arm64": "4.26.0", + "@rollup/rollup-darwin-x64": "4.26.0", + "@rollup/rollup-freebsd-arm64": "4.26.0", + "@rollup/rollup-freebsd-x64": "4.26.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", + "@rollup/rollup-linux-arm-musleabihf": "4.26.0", + "@rollup/rollup-linux-arm64-gnu": "4.26.0", + "@rollup/rollup-linux-arm64-musl": "4.26.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", + "@rollup/rollup-linux-riscv64-gnu": "4.26.0", + "@rollup/rollup-linux-s390x-gnu": "4.26.0", + "@rollup/rollup-linux-x64-gnu": "4.26.0", + "@rollup/rollup-linux-x64-musl": "4.26.0", + "@rollup/rollup-win32-arm64-msvc": "4.26.0", + "@rollup/rollup-win32-ia32-msvc": "4.26.0", + "@rollup/rollup-win32-x64-msvc": "4.26.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.80.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.7.tgz", + "integrity": "sha512-MVWvN0u5meytrSjsU7AWsbhoXi1sc58zADXFllfZzbsBT1GHjjar6JwBINYPRrkx/zqnQ6uqbQuHgE95O+C+eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.3.tgz", + "integrity": "sha512-gosNorT1RCkuCMyihv6FBRR7BMV06oKRAs+l4UMp1mlcVg9rWN6KMmUj3igjQwmYys4mDP3etEYJgiHRbgHCHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.0.0.tgz", + "integrity": "sha512-PHMifhh3EN4loMcHCz6l3v/luzgT3za+9f8subGgeMNjbJjzH4Ij/YoX3Gvu+kaouJRIlVdTHHCREADYf+ZteA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.0.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^3.0.0", + "@sigstore/tuf": "^3.0.0", + "@sigstore/verify": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz", + "integrity": "sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tailwindcss/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tailwindcss/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/terser": { + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.0.1.tgz", + "integrity": "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tuf-js/node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tuf-js/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/tuf-js/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tuf-js/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/tuf-js/node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/tuf-js/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.0.tgz", + "integrity": "sha512-2v6aXUXwLP1Epd/gc32HAMIWoczx+fZwEPRHm/VwtrJzRGwR1qGZXEYV3Zp8ZjjbwaZhMrM6uHV4KVkk+XCc2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/tuf-js/node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/tuf-js/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/tuf-js/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.39", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.39.tgz", + "integrity": "sha512-IZ6acm6RhQHNibSt7+c09hhvsKy9WUr4DVbeq9U8o71qxyYtJpQeDxQnMrVqnIFMLcQjHO0I9wgfO2vIahht4w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz", + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack": { + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.1.0.tgz", + "integrity": "sha512-aQpaN81X6tXie1FoOB7xlMfCsN19pSvRAeYUHOdFWOlhpQ/LlbfTqYwwmEDFV0h8GGuqmCmKmT+pxcUV/Nt2gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", + "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==", + "license": "MIT" + } + } +} diff --git a/frontend-web/Frontend/package.json b/frontend-web/Frontend/package.json new file mode 100644 index 000000000..4af964494 --- /dev/null +++ b/frontend-web/Frontend/package.json @@ -0,0 +1,39 @@ +{ + "name": "frontend", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.0", + "@angular/forms": "^19.0.0", + "@angular/platform-browser": "^19.0.0", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.0.1", + "@angular/cli": "^19.0.1", + "@angular/compiler-cli": "^19.0.0", + "@types/jasmine": "~5.1.0", + "jasmine-core": "~5.4.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "tailwindcss": "^3.4.15", + "typescript": "~5.6.2" + } +} diff --git a/frontend-web/Frontend/public/favicon.ico b/frontend-web/Frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 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 Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/frontend-web/Frontend/src/app/app.component.css b/frontend-web/Frontend/src/app/app.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/app.component.html b/frontend-web/Frontend/src/app/app.component.html new file mode 100644 index 000000000..0680b43f9 --- /dev/null +++ b/frontend-web/Frontend/src/app/app.component.html @@ -0,0 +1 @@ + diff --git a/frontend-web/Frontend/src/app/app.component.spec.ts b/frontend-web/Frontend/src/app/app.component.spec.ts new file mode 100644 index 000000000..ec07c3b8f --- /dev/null +++ b/frontend-web/Frontend/src/app/app.component.spec.ts @@ -0,0 +1,23 @@ +import { TestBed } from '@angular/core/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AppComponent], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have the 'Frontend' title`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('Frontend'); + }); + +}); diff --git a/frontend-web/Frontend/src/app/app.component.ts b/frontend-web/Frontend/src/app/app.component.ts new file mode 100644 index 000000000..e19bf59b4 --- /dev/null +++ b/frontend-web/Frontend/src/app/app.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + standalone: true, + templateUrl: './app.component.html', + styleUrl: './app.component.css' +}) +export class AppComponent { + title = 'Frontend'; +} diff --git a/frontend-web/Frontend/src/app/app.config.ts b/frontend-web/Frontend/src/app/app.config.ts new file mode 100644 index 000000000..c3aa9638a --- /dev/null +++ b/frontend-web/Frontend/src/app/app.config.ts @@ -0,0 +1,14 @@ +import { ApplicationConfig } from '@angular/core'; +import { provideRouter } from '@angular/router'; + +import { routes } from './app.routes'; +import {provideHttpClient, withFetch} from '@angular/common/http'; +import {provideClientHydration} from '@angular/platform-browser'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideRouter(routes), + provideClientHydration(), + provideHttpClient(withFetch()), + ] +}; diff --git a/frontend-web/Frontend/src/app/app.routes.ts b/frontend-web/Frontend/src/app/app.routes.ts new file mode 100644 index 000000000..10002ce1a --- /dev/null +++ b/frontend-web/Frontend/src/app/app.routes.ts @@ -0,0 +1,25 @@ +import { Routes } from '@angular/router'; +import {EditPostComponent} from './component/edit-post/edit-post.component'; +import {PostsComponent} from './component/posts/posts.component'; +import {ConceptPostsComponent} from './component/concept-posts/concept-posts.component'; +import {AddPostComponent} from './component/add-post/add-post.component'; +import {LoginComponent} from './component/login/login.component'; +import {ReviewPostComponent} from './component/review-post/review-post.component'; +import {ReviewDetailsComponent} from './component/review-details/review-details.component'; +import {CommentsComponent} from './component/comments/comments.component'; +import {AddCommentComponent} from './component/add-comment/add-comment.component'; +import {EditCommentComponent} from './component/edit-comment/edit-comment.component'; + +export const routes: Routes = [ + {path: 'editPost/:id', component: EditPostComponent}, + {path: 'posts', component: PostsComponent}, + {path: 'concepts', component: ConceptPostsComponent}, + {path: 'addPost', component: AddPostComponent}, + {path: 'login', component: LoginComponent}, + {path: 'review/:id', component: ReviewPostComponent}, + {path: 'postDetails/:id', component: ReviewDetailsComponent}, + {path: 'comments/:id', component: CommentsComponent}, + {path: 'createComment/:id', component: AddCommentComponent}, + {path: 'editComment/:postId/:id', component: EditCommentComponent}, + {path: '', redirectTo: 'login', pathMatch: 'full'} +]; diff --git a/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.css b/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.html b/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.html new file mode 100644 index 000000000..2c530679d --- /dev/null +++ b/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.html @@ -0,0 +1,23 @@ + +

+ diff --git a/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.spec.ts b/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.spec.ts new file mode 100644 index 000000000..6baaa5d1f --- /dev/null +++ b/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.spec.ts @@ -0,0 +1,73 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { AddCommentComponent } from './add-comment.component'; +import { CommentService } from '../../services/comment.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { of, throwError } from 'rxjs'; +import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { NavbarComponent } from '../navbar/navbar.component'; + +describe('AddCommentComponent', () => { + let component: AddCommentComponent; + let fixture: ComponentFixture; + let commentService: jasmine.SpyObj; + let router: jasmine.SpyObj; + let activatedRoute: ActivatedRoute; + + beforeEach(async () => { + const commentServiceSpy = jasmine.createSpyObj('CommentService', ['addComment']); + const routerSpy = jasmine.createSpyObj('Router', ['navigate']); + + await TestBed.configureTestingModule({ + imports: [ReactiveFormsModule, FormsModule, AddCommentComponent, NavbarComponent], + providers: [ + { provide: CommentService, useValue: commentServiceSpy }, + { provide: Router, useValue: routerSpy }, + { provide: ActivatedRoute, useValue: { snapshot: { params: { id: '1' } } } } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(AddCommentComponent); + component = fixture.componentInstance; + commentService = TestBed.inject(CommentService) as jasmine.SpyObj; + router = TestBed.inject(Router) as jasmine.SpyObj; + activatedRoute = TestBed.inject(ActivatedRoute); + + fixture.detectChanges(); // Ensure component initialization + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should initialize author on ngOnInit', () => { + spyOn(localStorage, 'getItem').and.returnValue('testUser'); + component.ngOnInit(); + expect(component.author).toBe('testUser'); + }); + + it('should call addComment and navigate on success', () => { + spyOn(localStorage, 'getItem').and.returnValue('testUser'); + component.content = 'Test comment'; + const comment = { id: 1, content: 'Test comment', author: 'testUser', postId: 5 }; + commentService.addComment.and.returnValue(of(comment)); + + component.addComment(); + + expect(commentService.addComment).toHaveBeenCalledWith('1', comment); + expect(router.navigate).toHaveBeenCalledWith(['/posts']); + }); + + + it('should log error on addComment failure', () => { + spyOn(localStorage, 'getItem').and.returnValue('testUser'); + component.content = 'Test comment'; + const error = new Error('Test error'); + commentService.addComment.and.returnValue(throwError(error)); + spyOn(console, 'error'); + + component.addComment(); + + expect(commentService.addComment).toHaveBeenCalled(); + expect(console.error).toHaveBeenCalledWith('Error adding comment:', error); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.ts b/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.ts new file mode 100644 index 000000000..d8e32c970 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/add-comment/add-comment.component.ts @@ -0,0 +1,53 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {NavbarComponent} from '../navbar/navbar.component'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {ActivatedRoute, Router, RouterLink} from '@angular/router'; +import {CommentService} from '../../services/comment.service'; +import {Comment} from '../../shared/models/post/comment.model'; + +@Component({ + selector: 'app-add-comment', + imports: [ + NavbarComponent, + ReactiveFormsModule, + RouterLink, + FormsModule + ], + standalone: true, + templateUrl: './add-comment.component.html', + styleUrl: './add-comment.component.css' +}) +export class AddCommentComponent implements OnInit{ + content!: string; + author!: string | null; + route: ActivatedRoute = inject(ActivatedRoute); + router: Router = inject(Router); + comment!: Comment; + + constructor(private readonly commentService: CommentService) {} + + ngOnInit(): void { + this.author = localStorage.getItem('username'); + } + + addComment() { + if (this.author) { + this.comment = { + content: this.content, + author: localStorage.getItem('username'), + postId: this.route.snapshot.params['id'] + } as Comment; + } + + this.commentService.addComment(this.route.snapshot.params['id'], this.comment).subscribe({ + next:(response) => { + console.log('Comment added successfully:', response); + this.router.navigate(['/posts']); + }, + error:(error) => { + console.error('Error adding comment:', error); + } + }); + + } +} diff --git a/frontend-web/Frontend/src/app/component/add-post/add-post.component.css b/frontend-web/Frontend/src/app/component/add-post/add-post.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/add-post/add-post.component.html b/frontend-web/Frontend/src/app/component/add-post/add-post.component.html new file mode 100644 index 000000000..f13c68e60 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/add-post/add-post.component.html @@ -0,0 +1,43 @@ + +
+
+
+ + +
+
+ + +
+
+ +
+
+
+ +
+ +
+ + @if(datePickerVisible){ + + } + +
+ + +
+ +
+ +
+ diff --git a/frontend-web/Frontend/src/app/component/add-post/add-post.component.spec.ts b/frontend-web/Frontend/src/app/component/add-post/add-post.component.spec.ts new file mode 100644 index 000000000..4fc24ecea --- /dev/null +++ b/frontend-web/Frontend/src/app/component/add-post/add-post.component.spec.ts @@ -0,0 +1,78 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { HttpClientModule} from '@angular/common/http'; +import { Router, ActivatedRoute } from '@angular/router'; +import {Observable, of, throwError} from 'rxjs'; +import { AddPostComponent } from './add-post.component'; +import { PostsService } from '../../services/posts.service'; +import { Post } from '../../shared/models/post/post.model'; + +describe('AddPostComponent', () => { + let component: AddPostComponent; + let fixture: ComponentFixture; + let postService: jasmine.SpyObj; + let router: jasmine.SpyObj; + + beforeEach(async () => { + postService = jasmine.createSpyObj('PostsService', ['addPost']); + router = jasmine.createSpyObj('Router', ['navigate']); + + await TestBed.configureTestingModule({ + imports: [AddPostComponent], + providers: [ + { provide: PostsService, useValue: postService }, + { provide: Router, useValue: router }, + { provide: ActivatedRoute, useValue: {snapshot: {params: { id: 1}}} } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(AddPostComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should add a post successfully', () => { + const mockPost: Post = { + id: 1, + title: 'Test Title', + author: 'Test Author', + content: 'Test Content', + date: '2023-01-01', + concept: false + }; + const mockRole = 'editor'; + component.title = mockPost.title; + component.author = mockPost.author; + component.content = mockPost.content; + component.date = mockPost.date; + + postService.addPost.and.returnValue({subscribe: () => {} } as any); + + component.addPost(); + + expect(postService.addPost).toHaveBeenCalledWith(mockPost, mockRole); + expect(router.navigate).toHaveBeenCalledWith(['/posts']); + }); + + it('should handle error when adding a post', () => { + const mockError = new Error('Test Error'); + postService.addPost.and.returnValue(throwError(mockError)); + + component.addPost(); + + expect(postService.addPost).toHaveBeenCalled(); + expect(router.navigate).not.toHaveBeenCalled(); + }); + + it('should toggle datePickerVisible', () => { + expect(component.datePickerVisible).toBeFalse(); + component.showDatePicker(); + expect(component.datePickerVisible).toBeTrue(); + component.showDatePicker(); + expect(component.datePickerVisible).toBeFalse(); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/add-post/add-post.component.ts b/frontend-web/Frontend/src/app/component/add-post/add-post.component.ts new file mode 100644 index 000000000..46999e1ce --- /dev/null +++ b/frontend-web/Frontend/src/app/component/add-post/add-post.component.ts @@ -0,0 +1,59 @@ +import {Component, inject, Input} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {PostsService} from '../../services/posts.service'; +import {Post} from '../../shared/models/post/post.model'; +import {Router, RouterLink} from '@angular/router'; +import {NavbarComponent} from '../navbar/navbar.component'; +import {DatepickerComponent} from '../datepicker/datepicker.component'; + +@Component({ + selector: 'app-add-post', + imports: [ + FormsModule, + RouterLink, + NavbarComponent, + DatepickerComponent + ], + standalone: true, + templateUrl: './add-post.component.html', + styleUrl: './add-post.component.css' +}) +export class AddPostComponent { + router: Router = inject(Router); + author: string = localStorage.getItem('username') || ''; + userRole: string = localStorage.getItem('role') || ''; + title!: string; + content!: string; + date!: string; + post!: Post; + datePickerVisible: boolean = false; + + constructor(private readonly postService: PostsService) { } + + addPost() { + this.post = { + title: this.title, + author: this.author, + content: this.content, + date: this.date + } as Post; + this.postService.addPost(this.post, this.userRole).subscribe({ + next:(response) => { + console.log('Post added successfully:', response); + this.router.navigate(['/posts']); + + }, + error:(error) => { + console.error('Error adding post:', error); + } + }); + } + + + + showDatePicker() { + this.datePickerVisible = !this.datePickerVisible; + } + + +} diff --git a/frontend-web/Frontend/src/app/component/comments/comments.component.css b/frontend-web/Frontend/src/app/component/comments/comments.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/comments/comments.component.html b/frontend-web/Frontend/src/app/component/comments/comments.component.html new file mode 100644 index 000000000..673f8bb17 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/comments/comments.component.html @@ -0,0 +1,27 @@ + +@if (comments.length === 0) { +
+
+
No Comments Yet
+
+
+} +@for (comment of comments; track comment.id) { +
+
+
{{ comment.content }}
+

{{ comment.author }}

+
+ @if(currentUser === comment.author) { + + Edit + + + Delete + + } + +
+
+
+} diff --git a/frontend-web/Frontend/src/app/component/comments/comments.component.spec.ts b/frontend-web/Frontend/src/app/component/comments/comments.component.spec.ts new file mode 100644 index 000000000..11eef28a3 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/comments/comments.component.spec.ts @@ -0,0 +1,82 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommentsComponent } from './comments.component'; +import { ActivatedRoute, Router } from '@angular/router'; +import { of, throwError } from 'rxjs'; +import { CommentService } from '../../services/comment.service'; +import { Comment } from '../../shared/models/post/comment.model'; +import { RouterTestingModule } from '@angular/router/testing'; +import { CommonModule } from '@angular/common'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('CommentsComponent', () => { + let component: CommentsComponent; + let fixture: ComponentFixture; + let mockActivatedRoute: any; + let mockRouter: any; + let mockCommentService: any; + let mockComments: Comment[]; + + beforeEach(async () => { + mockActivatedRoute = { + snapshot: { + params: { id: 1 } + } + }; + + mockRouter = { + navigate: jasmine.createSpy('navigate') + }; + + mockCommentService = jasmine.createSpyObj('CommentService', ['getComments', 'deleteComment']); + + await TestBed.configureTestingModule({ + imports: [ + CommentsComponent, + RouterTestingModule, + CommonModule, + HttpClientTestingModule + ], + providers: [ + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { provide: Router, useValue: mockRouter }, + { provide: CommentService, useValue: mockCommentService } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(CommentsComponent); + component = fixture.componentInstance; + }); + + it('should fetch comments on init', () => { + mockComments = [{ + id: 1, postId: 1, content: 'Test comment', + author: 'ilias' + }]; + mockCommentService.getComments.and.returnValue(of(mockComments)); + component.ngOnInit(); + expect(component.comments.length).toBe(1); + expect(component.comments[0].content).toBe('Test comment'); + fixture.detectChanges(); + }); + + it('should handle error when fetching comments', () => { + mockCommentService.getComments.and.returnValue(throwError('Error')); + spyOn(console, 'error'); + component.ngOnInit(); + expect(console.error).toHaveBeenCalledWith('Error fetching comments:', 'Error'); + }); + + it('should delete comment and navigate to posts', () => { + mockCommentService.deleteComment.and.returnValue(of({})); + component.deleteComment(1); + expect(mockCommentService.deleteComment).toHaveBeenCalledWith(1); + expect(mockRouter.navigate).toHaveBeenCalledWith(['/posts']); + }); + + it('should handle error when deleting comment', () => { + mockCommentService.deleteComment.and.returnValue(throwError('Error')); + spyOn(console, 'error'); + component.deleteComment(1); + expect(console.error).toHaveBeenCalledWith('Error deleting comment:', 'Error'); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/comments/comments.component.ts b/frontend-web/Frontend/src/app/component/comments/comments.component.ts new file mode 100644 index 000000000..0d51b1b0c --- /dev/null +++ b/frontend-web/Frontend/src/app/component/comments/comments.component.ts @@ -0,0 +1,49 @@ +import {Component, inject} from '@angular/core'; +import {ActivatedRoute, Router, RouterLink} from '@angular/router'; +import {CommentService} from '../../services/comment.service'; +import {Comment} from '../../shared/models/post/comment.model'; +import {NavbarComponent} from '../navbar/navbar.component'; +@Component({ + selector: 'app-comments', + imports: [ + NavbarComponent, + RouterLink + ], + standalone: true, + templateUrl: './comments.component.html', + styleUrl: './comments.component.css' +}) +export class CommentsComponent { + route: ActivatedRoute = inject(ActivatedRoute); + router: Router = inject(Router); + comments!: Comment[] + postId!: number; + currentUser = localStorage.getItem('username'); + + constructor(private readonly commentService: CommentService){} + + ngOnInit(): void { + this.postId = this.route.snapshot.params['id']; + this.commentService.getComments().subscribe({ + next:(data) => { + console.log(data); + this.comments = data.filter(comment => comment.postId == this.postId); + }, + error:(error) => { + console.error('Error fetching comments:', error); + } + }); + } + + deleteComment(id: number) { + this.commentService.deleteComment(id).subscribe({ + next:(data) => { + console.log('Comment deleted:', data); + this.router.navigate(['/posts']); + }, + error:(error) => { + console.error('Error deleting comment:', error); + } + }); + } +} diff --git a/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.css b/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.html b/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.html new file mode 100644 index 000000000..e7d562b46 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.html @@ -0,0 +1,22 @@ + +@for (post of conceptPosts; track post.id) { +
+
+ +
{{ post.title }}
+
+

{{ post.content }}

+ +
+
+} + + + diff --git a/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.spec.ts b/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.spec.ts new file mode 100644 index 000000000..1b06fdeef --- /dev/null +++ b/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.spec.ts @@ -0,0 +1,58 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { of, throwError } from 'rxjs'; +import { ConceptPostsComponent } from './concept-posts.component'; +import { PostsService } from '../../services/posts.service'; +import { Post } from '../../shared/models/post/post.model'; + +describe('ConceptPostsComponent', () => { + let component: ConceptPostsComponent; + let fixture: ComponentFixture; + let postService: jasmine.SpyObj; + + beforeEach(async () => { + const postServiceSpy = jasmine.createSpyObj('PostsService', { getConceptPosts: of([]) }); + await TestBed.configureTestingModule({ + imports: [HttpClientTestingModule, RouterTestingModule, ConceptPostsComponent], + providers: [{ provide: PostsService, useValue: postServiceSpy }] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ConceptPostsComponent); + component = fixture.componentInstance; + postService = TestBed.inject(PostsService) as jasmine.SpyObj; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should fetch concept posts on init', () => { + const mockPosts: Post[] = [{ + id: 1, title: 'Test Post', content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false + }]; + postService.getConceptPosts.and.returnValue(of(mockPosts)); + + component.ngOnInit(); + + expect(component.conceptPosts).toEqual(mockPosts); + expect(postService.getConceptPosts).toHaveBeenCalled(); + }); + + it('should handle error when fetching concept posts', () => { + const errorResponse = new Error('Error fetching posts'); + postService.getConceptPosts.and.returnValue(throwError(errorResponse)); + spyOn(console, 'error'); + + component.ngOnInit(); + + expect(component.conceptPosts).toEqual([]); + expect(postService.getConceptPosts).toHaveBeenCalled(); + expect(console.error).toHaveBeenCalledWith('Error fetching posts:', errorResponse); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.ts b/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.ts new file mode 100644 index 000000000..a80794bf7 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/concept-posts/concept-posts.component.ts @@ -0,0 +1,37 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {Post} from '../../shared/models/post/post.model'; +import {PostsService} from '../../services/posts.service'; +import {ActivatedRoute, Router, RouterLink} from '@angular/router'; +import {NavbarComponent} from '../navbar/navbar.component'; + +@Component({ + selector: 'app-concept-posts', + imports: [ + RouterLink, + NavbarComponent, + ], + standalone: true, + templateUrl: './concept-posts.component.html', + styleUrl: './concept-posts.component.css' +}) +export class ConceptPostsComponent implements OnInit { + conceptPosts!: Post[]; + // route: ActivatedRoute = inject(ActivatedRoute); + router: Router = inject(Router); + + constructor(private readonly postService: PostsService) { } + + ngOnInit(): void { + + this.postService.getConceptPosts().subscribe({ + next:(data) => { + this.conceptPosts = data; + console.log('Posts:', data); + }, + error:(error) => { + console.error('Error fetching posts:', error); + } + }); + } + +} diff --git a/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.css b/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.html b/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.html new file mode 100644 index 000000000..37288ef8c --- /dev/null +++ b/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.html @@ -0,0 +1,142 @@ +
+
+ +
+ +
+ + + +
+
+ +
+
+
+
+ Su + Mo + Tu + We + Th + Fr + Sa +
+
+ 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 +
+
+
+
+ + +
+
diff --git a/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.spec.ts b/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.spec.ts new file mode 100644 index 000000000..26f7ac8a2 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.spec.ts @@ -0,0 +1,55 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatepickerComponent } from './datepicker.component'; +import { AddPostComponent } from '../add-post/add-post.component'; +import { SearchbarComponent } from '../searchbar/searchbar.component'; + +describe('DatepickerComponent', () => { + let component: DatepickerComponent; + let fixture: ComponentFixture; + const addPostComponent = jasmine.createSpyObj('AddPostComponent', ['date', 'datePickerVisible']); + const searchBarComponent = jasmine.createSpyObj('SearchbarComponent', ['searchValue', 'showDatePicker']); + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [DatepickerComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DatepickerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set the correct date and update AddPostComponent', () => { + component.addPostComponent = addPostComponent; + component.selectDate(15); + expect(addPostComponent.date).toBe(`${component.year}-${(component.month + 1).toString().padStart(2, '0')}-15`); + expect(addPostComponent.datePickerVisible).toBeFalse(); + }); + + it('should set the correct date and update SearchbarComponent', () => { + component.searchBarComponent = searchBarComponent; + component.selectDate(15); + expect(searchBarComponent.searchValue).toBe(`${component.year}-${(component.month + 1).toString().padStart(2, '0')}-15`); + expect(searchBarComponent.showDatePicker).toBeFalse(); + }); + + it('should increment month and year correctly', () => { + component.month = 11; // December + component.year = 2023; + component.nextMonth(); + expect(component.month).toBe(12); // January + expect(component.year).toBe(2024); + }); + + it('should decrement month and year correctly', () => { + component.month = 0; // January + component.year = 2024; + component.previousMonth(); + expect(component.month).toBe(-1); // December + expect(component.year).toBe(2023); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.ts b/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.ts new file mode 100644 index 000000000..08bd98e73 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/datepicker/datepicker.component.ts @@ -0,0 +1,56 @@ +import {Component, Input} from '@angular/core'; +import {AddPostComponent} from '../add-post/add-post.component'; +import {SearchbarComponent} from '../searchbar/searchbar.component'; + +@Component({ + selector: 'app-datepicker', + imports: [], + standalone: true, + templateUrl: './datepicker.component.html', + styleUrl: './datepicker.component.css' +}) +export class DatepickerComponent { + @Input() addPostComponent!: AddPostComponent; + @Input() searchBarComponent!: SearchbarComponent; + month: number = new Date().getMonth(); + monthString: string = new Date().toLocaleString('default', {month: 'long'}); + year: number = new Date().getFullYear(); + date: string = ''; + returnMonth!: number; + + selectDate(day: number){ + if(this.month + 1 > 12){ + this.returnMonth = 1; + }else{ + this.returnMonth = this.month + 1; + } + this.date = `${this.year}-${this.returnMonth.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; + + if(this.addPostComponent != null){ + this.addPostComponent.date = this.date; + this.addPostComponent.datePickerVisible = false; + }else if(this.searchBarComponent != null){ + this.searchBarComponent.searchValue = this.date; + this.searchBarComponent.showDatePicker = false; + } + + console.log(this.date); + } + + nextMonth() { + this.monthString = new Date(this.year, this.month + 1).toLocaleString('default', {month: 'long'}); + this.month = this.month + 1; + + if(this.monthString === 'January') { + this.year = this.year + 1; + } + } + + previousMonth() { + this.monthString = new Date(this.year, this.month - 1).toLocaleString('default', {month: 'long'}); + this.month = this.month - 1; + if(this.monthString === 'December') { + this.year = this.year - 1; + } + } +} diff --git a/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.css b/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.html b/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.html new file mode 100644 index 000000000..03d48004e --- /dev/null +++ b/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.html @@ -0,0 +1,23 @@ + +
+
+
+ + +
+
+ + +
+ +
+ +
+ diff --git a/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.spec.ts b/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.spec.ts new file mode 100644 index 000000000..ef9c50df4 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.spec.ts @@ -0,0 +1,103 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { EditCommentComponent } from './edit-comment.component'; +import { CommentService } from '../../services/comment.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { of, throwError } from 'rxjs'; +import { Comment } from '../../shared/models/post/comment.model'; + +describe('EditCommentComponent', () => { + let component: EditCommentComponent; + let fixture: ComponentFixture; + let commentServiceMock: any; + let routerMock: any; + let activatedRouteMock: any; + + beforeEach(async () => { + commentServiceMock = { + getCommentById: jasmine.createSpy('getCommentById').and.returnValue(of({})), + updateComment: jasmine.createSpy('updateComment').and.returnValue(of({})) + }; + + routerMock = { + navigate: jasmine.createSpy('navigate') + }; + + activatedRouteMock = { + snapshot: { + params: { + id: '1' + } + } + }; + + await TestBed.configureTestingModule({ + imports: [EditCommentComponent], + providers: [ + { provide: CommentService, useValue: commentServiceMock }, + { provide: Router, useValue: routerMock }, + { provide: ActivatedRoute, useValue: activatedRouteMock } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(EditCommentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should fetch comment on init', () => { + const comment: Comment = { id: 1, content: 'Test content', author: 'Test author', postId: 123 }; + commentServiceMock.getCommentById.and.returnValue(of(comment)); + + component.ngOnInit(); + + expect(commentServiceMock.getCommentById).toHaveBeenCalledWith('1'); + expect(component.comment).toEqual(comment); + expect(component.content).toBe('Test content'); + expect(component.author).toBe('Test author'); + }); + + it('should handle error when fetching comment', () => { + const error = new Error('Error fetching comment'); + commentServiceMock.getCommentById.and.returnValue(throwError(error)); + spyOn(console, 'error'); + + component.ngOnInit(); + + expect(commentServiceMock.getCommentById).toHaveBeenCalledWith('1'); + expect(console.error).toHaveBeenCalledWith('Error fetching comment:', error); + }); + + it('should update comment', () => { + const comment: Comment = { id: 1, content: 'Updated content', author: 'Updated author', postId: 123 }; + component.comment = comment; + component.content = 'Updated content'; + component.author = 'Updated author'; + commentServiceMock.updateComment.and.returnValue(of(comment)); + + component.updateComment(); + + expect(commentServiceMock.updateComment).toHaveBeenCalledWith('1', comment); + expect(routerMock.navigate).toHaveBeenCalledWith(['/posts']); + }); + + it('should handle error when updating comment', () => { + const error = new Error('Error updating comment'); + commentServiceMock.updateComment.and.returnValue(throwError(error)); + spyOn(console, 'error'); + + component.updateComment(); + + expect(commentServiceMock.updateComment).toHaveBeenCalledWith('1', component.comment); + expect(console.error).toHaveBeenCalledWith('Error updating comment:', error); + }); + + it('should navigate to posts on cancel', () => { + component.cancelEdit(); + + expect(routerMock.navigate).toHaveBeenCalledWith(['/posts']); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.ts b/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.ts new file mode 100644 index 000000000..135dad11c --- /dev/null +++ b/frontend-web/Frontend/src/app/component/edit-comment/edit-comment.component.ts @@ -0,0 +1,58 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {NavbarComponent} from "../navbar/navbar.component"; +import {FormsModule, ReactiveFormsModule} from "@angular/forms"; +import {ActivatedRoute, Router} from '@angular/router'; +import {CommentService} from '../../services/comment.service'; +import {Comment} from '../../shared/models/post/comment.model'; + +@Component({ + selector: 'app-edit-comment', + imports: [ + NavbarComponent, + ReactiveFormsModule, + FormsModule + ], + standalone: true, + templateUrl: './edit-comment.component.html', + styleUrl: './edit-comment.component.css' +}) +export class EditCommentComponent implements OnInit { + router: Router = inject(Router); + route: ActivatedRoute = inject(ActivatedRoute); + comment!: Comment; + author!: string; + content!: string; + constructor(private readonly commentService: CommentService) {} + + ngOnInit() { + this.commentService.getCommentById(this.route.snapshot.params['id']).subscribe({ + next:(data) => { + console.log(data); + this.comment = data; + this.content = this.comment.content; + this.author = this.comment.author; + }, + error:(error) => { + console.error('Error fetching comment:', error); + } + }); + } + updateComment() { + this.comment.content = this.content; + this.comment.author = this.author; + console.log(this.comment); + this.commentService.updateComment(this.route.snapshot.params['id'], this.comment).subscribe({ + next:(data) => { + console.log('Comment updated:', data); + this.router.navigate(['/posts']); + }, + error:(error) => { + console.error('Error updating comment:', error); + } + }); + } + + cancelEdit() { + this.router.navigate(['/posts']); + } +} diff --git a/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.css b/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.html b/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.html new file mode 100644 index 000000000..046467de1 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.html @@ -0,0 +1,31 @@ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ diff --git a/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.spec.ts b/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.spec.ts new file mode 100644 index 000000000..fce6ed4c0 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.spec.ts @@ -0,0 +1,107 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ActivatedRoute, Router } from '@angular/router'; +import { of, throwError } from 'rxjs'; +import { EditPostComponent } from './edit-post.component'; +import { PostsService } from '../../services/posts.service'; +import { ReviewService } from '../../services/review.service'; +import { DatePipe } from '@angular/common'; +import { Post } from '../../shared/models/post/post.model'; + +describe('EditPostComponent', () => { + let component: EditPostComponent; + let fixture: ComponentFixture; + let mockPostsService: jasmine.SpyObj; + let mockReviewService: jasmine.SpyObj; + let mockRouter: jasmine.SpyObj; + let mockActivatedRoute: any; + + beforeEach(async () => { + mockPostsService = jasmine.createSpyObj('PostsService', ['getPostById', 'updatePost']); + mockReviewService = jasmine.createSpyObj('ReviewService', ['']); + mockRouter = jasmine.createSpyObj('Router', ['navigate']); + mockActivatedRoute = { + snapshot: { + params: { id: 1 } + } + }; + + await TestBed.configureTestingModule({ + imports: [EditPostComponent], + providers: [ + { provide: PostsService, useValue: mockPostsService }, + { provide: ReviewService, useValue: mockReviewService }, + { provide: Router, useValue: mockRouter }, + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + DatePipe + ] + }).compileComponents(); + + fixture = TestBed.createComponent(EditPostComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should fetch post on init', () => { + const post: Post = { id: 1, title: 'Test', content: 'Test content', author: 'Author', date: '2023-01-01', concept: false }; + mockPostsService.getPostById.and.returnValue(of(post)); + + component.ngOnInit(); + + expect(mockPostsService.getPostById).toHaveBeenCalledWith(1); + expect(component.post).toEqual(post); + expect(component.newTitle).toBe(post.title); + expect(component.newContent).toBe(post.content); + expect(component.newAuthor).toBe(post.author); + expect(component.newDate).toBe('2023-01-01'); + expect(component.concept).toBe(post.concept); + }); + + it('should handle error when fetching post', () => { + mockPostsService.getPostById.and.returnValue(throwError('Error')); + + component.ngOnInit(); + + expect(mockPostsService.getPostById).toHaveBeenCalledWith(1); + expect(component.post).toBeUndefined(); + }); + + it('should update post and navigate', () => { + const post: Post = { id: 1, title: 'Test', content: 'Test content', author: 'Author', date: '2023-01-01', concept: false }; + component.post = post; + component.newTitle = 'Updated Title'; + component.newContent = 'Updated Content'; + component.newAuthor = 'Updated Author'; + component.newDate = '2023-01-02'; + mockPostsService.updatePost.and.returnValue(of(post)); + + component.updatePost(); + + expect(mockPostsService.updatePost).toHaveBeenCalledWith(post, component.userRole); + expect(mockRouter.navigate).toHaveBeenCalledWith(['/posts']); + }); + + it('should handle error when updating post', () => { + const post: Post = { id: 1, title: 'Test', content: 'Test content', author: 'Author', date: '2023-01-01', concept: false }; + component.post = post; + mockPostsService.updatePost.and.returnValue(throwError('Error')); + + component.updatePost(); + + expect(mockPostsService.updatePost).toHaveBeenCalledWith(post, component.userRole); + expect(mockRouter.navigate).not.toHaveBeenCalled(); + }); + + it('should navigate to concepts or posts on cancelEdit', () => { + component.post = { id: 1, title: 'Test', content: 'Test content', author: 'Author', date: '2023-01-01', concept: true }; + component.cancelEdit(); + expect(mockRouter.navigate).toHaveBeenCalledWith(['/concepts']); + + component.post.concept = false; + component.cancelEdit(); + expect(mockRouter.navigate).toHaveBeenCalledWith(['/posts']); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.ts b/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.ts new file mode 100644 index 000000000..df75bb924 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/edit-post/edit-post.component.ts @@ -0,0 +1,82 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Post} from '../../shared/models/post/post.model'; +import {FormsModule} from '@angular/forms'; +import {PostsService} from '../../services/posts.service'; +import {DatePipe} from '@angular/common'; +import {NavbarComponent} from '../navbar/navbar.component'; +import {ReviewService} from '../../services/review.service'; + +@Component({ + selector: 'app-edit-post', + imports: [ + FormsModule, + NavbarComponent + ], + standalone: true, + templateUrl: './edit-post.component.html', + styleUrl: './edit-post.component.css', + providers: [DatePipe] +}) +export class EditPostComponent implements OnInit { + route: ActivatedRoute = inject(ActivatedRoute); + post!: Post; + router: Router = inject(Router); + userRole: string = localStorage.getItem('role') || ''; + postId!: number; + newTitle!: string; + newContent!: string; + newAuthor!: string; + newDate!: string; + concept!: boolean; + + constructor(private readonly postService: PostsService, private readonly reviewService: ReviewService ,private readonly datePipe: DatePipe) {} + + ngOnInit(): void { + console.log(this.route.snapshot.params['id']); + this.postId = this.route.snapshot.params['id']; + this.postService.getPostById(this.postId).subscribe({ + next:(data) => { + console.log(data); + this.post = data; + this.newTitle = this.post.title; + this.newContent = this.post.content; + this.newAuthor = this.post.author; + this.newDate = this.datePipe.transform(this.post.date, 'yyyy-MM-dd')!; + this.concept = this.post.concept; + }, + error:(error) => { + console.error('Error fetching post:', error); + } + }); + } + + updatePost() { + this.post.title = this.newTitle; + this.post.content = this.newContent; + this.post.author = this.newAuthor; + this.post.date = this.newDate; + console.log(this.post); + this.postService.updatePost(this.post, this.userRole).subscribe({ + next:(data) => { + console.log('Post updated:', data); + if (this.post.concept) { + this.router.navigate(['/concepts']); + } else { + this.router.navigate(['/posts']); + } + }, + error:(error) => { + console.error('Error updating post:', error); + } + }); + } + + cancelEdit() { + if (this.post.concept != null) { + this.router.navigate(['/concepts']); + } else { + this.router.navigate(['/posts']); + } + } +} diff --git a/frontend-web/Frontend/src/app/component/login/login.component.css b/frontend-web/Frontend/src/app/component/login/login.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/login/login.component.html b/frontend-web/Frontend/src/app/component/login/login.component.html new file mode 100644 index 000000000..a728efef0 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/login/login.component.html @@ -0,0 +1,33 @@ + +
+
+
+
+

+ Sign in to your account +

+
+
+ + +
+
+

Role

+
+ + +
+
+ + +
+
+
+
+ +
+
+
+
+
+ diff --git a/frontend-web/Frontend/src/app/component/login/login.component.spec.ts b/frontend-web/Frontend/src/app/component/login/login.component.spec.ts new file mode 100644 index 000000000..692db2793 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/login/login.component.spec.ts @@ -0,0 +1,49 @@ +import { AuthService } from '../../services/auth.service'; +import { Router } from '@angular/router'; +import { FormsModule } from '@angular/forms'; +import { of } from 'rxjs'; +import {LoginComponent} from './login.component'; +import {ComponentFixture, TestBed} from '@angular/core/testing'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + let authService: AuthService; + let router: Router; + + beforeEach(async () => { + const authServiceSpy = jasmine.createSpyObj('AuthService', ['logIn']); + const routerSpy = jasmine.createSpyObj('Router', ['navigate']); + + await TestBed.configureTestingModule({ + imports: [FormsModule, LoginComponent], + providers: [ + { provide: AuthService, useValue: authServiceSpy }, + { provide: Router, useValue: routerSpy } + ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + authService = TestBed.inject(AuthService); + router = TestBed.inject(Router); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should call authService.logIn with correct parameters', () => { + component.username = 'testUser'; + component.isEditor = true; + component.logIn(); + expect(authService.logIn).toHaveBeenCalledWith('testUser', true); + }); + + it('should navigate to /posts after login', () => { + component.logIn(); + expect(router.navigate).toHaveBeenCalledWith(['/posts']); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/login/login.component.ts b/frontend-web/Frontend/src/app/component/login/login.component.ts new file mode 100644 index 000000000..a0f293195 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/login/login.component.ts @@ -0,0 +1,27 @@ +import {Component} from '@angular/core'; +import {Router, RouterLink} from '@angular/router'; +import {FormsModule} from '@angular/forms'; +import {AuthService} from '../../services/auth.service'; + +@Component({ + selector: 'app-login', + imports: [ + FormsModule + ], + standalone: true, + templateUrl: './login.component.html', + styleUrl: './login.component.css' +}) +export class LoginComponent { + isUser!: boolean; + isEditor: boolean = true; + username!: string; + + constructor(private readonly authService: AuthService, private readonly router: Router) {} + + logIn(){ + this.authService.logIn(this.username, this.isEditor); + this.router.navigate(['/posts']); + } + +} diff --git a/frontend-web/Frontend/src/app/component/navbar/navbar.component.css b/frontend-web/Frontend/src/app/component/navbar/navbar.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/navbar/navbar.component.html b/frontend-web/Frontend/src/app/component/navbar/navbar.component.html new file mode 100644 index 000000000..81b893896 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/navbar/navbar.component.html @@ -0,0 +1,59 @@ + + diff --git a/frontend-web/Frontend/src/app/component/navbar/navbar.component.spec.ts b/frontend-web/Frontend/src/app/component/navbar/navbar.component.spec.ts new file mode 100644 index 000000000..cd0a7cad3 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/navbar/navbar.component.spec.ts @@ -0,0 +1,62 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Router } from '@angular/router'; +import { AuthService } from '../../services/auth.service'; +import { NotificationService } from '../../services/notification.service'; +import { NavbarComponent } from './navbar.component'; +import { ActivatedRoute } from '@angular/router'; +import { of } from 'rxjs'; + +describe('NavbarComponent', () => { + let component: NavbarComponent; + let fixture: ComponentFixture; + let authService: jasmine.SpyObj; + let notificationService: jasmine.SpyObj; + let router: jasmine.SpyObj; + + beforeEach(async () => { + const authServiceSpy = jasmine.createSpyObj('AuthService', ['logOut']); + const notificationServiceSpy = jasmine.createSpyObj('NotificationService', ['getNotifications']); + const routerSpy = jasmine.createSpyObj('Router', ['navigate']); + + await TestBed.configureTestingModule({ + imports: [NavbarComponent], + providers: [ + { provide: AuthService, useValue: authServiceSpy }, + { provide: NotificationService, useValue: notificationServiceSpy }, + { provide: Router, useValue: routerSpy }, + { provide: ActivatedRoute, useValue: { snapshot: { params: { id: 1 } } } } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(NavbarComponent); + component = fixture.componentInstance; + authService = TestBed.inject(AuthService) as jasmine.SpyObj; + notificationService = TestBed.inject(NotificationService) as jasmine.SpyObj; + router = TestBed.inject(Router) as jasmine.SpyObj; + + notificationService.getNotifications.and.returnValue(['Notification 1', 'Notification 2']); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should initialize notifications on init', () => { + expect(component.notifications).toEqual(['Notification 1', 'Notification 2']); + }); + + it('should log out and navigate to login', () => { + component.logOut(); + expect(authService.logOut).toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith(['/login']); + }); + + it('should toggle dropdown visibility', () => { + expect(component.isDropdownVisible).toBeFalse(); + component.toggleDropdown(); + expect(component.isDropdownVisible).toBeTrue(); + component.toggleDropdown(); + expect(component.isDropdownVisible).toBeFalse(); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/navbar/navbar.component.ts b/frontend-web/Frontend/src/app/component/navbar/navbar.component.ts new file mode 100644 index 000000000..c473a37f2 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/navbar/navbar.component.ts @@ -0,0 +1,38 @@ +import {Component, OnInit} from '@angular/core'; +import {Router, RouterLink} from '@angular/router'; +import {AuthService} from '../../services/auth.service'; +import {NotificationService} from '../../services/notification.service'; +import {of} from 'rxjs'; +import {NgClass} from '@angular/common'; + +@Component({ + selector: 'app-navbar', + imports: [ + RouterLink, + NgClass + ], + standalone: true, + templateUrl: './navbar.component.html', + styleUrl: './navbar.component.css' +}) +export class NavbarComponent implements OnInit { + role = localStorage.getItem('role'); + notifications!: string[]; + isDropdownVisible: boolean = false; + + constructor(private readonly router: Router, private readonly authService: AuthService, private readonly notificationService: NotificationService) {} + + ngOnInit(): void { + this.notifications = this.notificationService.getNotifications(); + console.log('Notifications:', this.notifications); + } + + logOut() { + this.authService.logOut(); + this.router.navigate(['/login']); + } + + toggleDropdown() { + this.isDropdownVisible = !this.isDropdownVisible; + } +} diff --git a/frontend-web/Frontend/src/app/component/posts/posts.component.css b/frontend-web/Frontend/src/app/component/posts/posts.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/posts/posts.component.html b/frontend-web/Frontend/src/app/component/posts/posts.component.html new file mode 100644 index 000000000..95ce8249c --- /dev/null +++ b/frontend-web/Frontend/src/app/component/posts/posts.component.html @@ -0,0 +1,34 @@ + + +
+ @if(role === 'editor') { + + add + + } +
+@for (post of allPosts; track post.id) { +
+
+
{{ post.title }}
+

{{ post.content }}

+
+ + Comment + + @if(role === 'editor') { + + Edit + + } + + View Comments + +
+
+
+} + + + + diff --git a/frontend-web/Frontend/src/app/component/posts/posts.component.spec.ts b/frontend-web/Frontend/src/app/component/posts/posts.component.spec.ts new file mode 100644 index 000000000..5cc311cfe --- /dev/null +++ b/frontend-web/Frontend/src/app/component/posts/posts.component.spec.ts @@ -0,0 +1,68 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { of, throwError } from 'rxjs'; +import { PostsComponent } from './posts.component'; +import { PostsService } from '../../services/posts.service'; +import { Post } from '../../shared/models/post/post.model'; +import { ActivatedRoute } from '@angular/router'; + +describe('PostsComponent', () => { + let component: PostsComponent; + let fixture: ComponentFixture; + let mockPostsService: jasmine.SpyObj; + + beforeEach(async () => { + mockPostsService = jasmine.createSpyObj('PostsService', ['getPublishedPosts']); + + await TestBed.configureTestingModule({ + imports: [PostsComponent], + providers: [ + { provide: PostsService, useValue: mockPostsService }, + { provide: ActivatedRoute, useValue: { snapshot: { params: { id: 1 } } } } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(PostsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should fetch and set allPosts on init', () => { + const mockPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'Author', + date: '2025-01-01', + concept: true + }]; + mockPostsService.getPublishedPosts.and.returnValue(of(mockPosts)); + + component.ngOnInit(); + + expect(component.allPosts).toEqual(mockPosts); + expect(mockPostsService.getPublishedPosts).toHaveBeenCalled(); + }); + + it('should log error when fetching posts fails', () => { + const consoleErrorSpy = spyOn(console, 'error'); + mockPostsService.getPublishedPosts.and.returnValue(throwError('Error')); + + component.ngOnInit(); + + expect(consoleErrorSpy).toHaveBeenCalledWith('Error fetching posts:', 'Error'); + }); + + it('should set loggedInUser and role from localStorage', () => { + localStorage.setItem('username', 'testUser'); + localStorage.setItem('role', 'admin'); + + component.ngOnInit(); + + expect(component.loggedInUser).toBe('testUser'); + expect(component.role).toBe('admin'); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/posts/posts.component.ts b/frontend-web/Frontend/src/app/component/posts/posts.component.ts new file mode 100644 index 000000000..ae26e9f0a --- /dev/null +++ b/frontend-web/Frontend/src/app/component/posts/posts.component.ts @@ -0,0 +1,39 @@ +import {Component, OnInit} from '@angular/core'; +import {SearchbarComponent} from '../searchbar/searchbar.component'; +import {PostsService} from '../../services/posts.service'; +import {Post} from '../../shared/models/post/post.model'; +import {RouterLink} from '@angular/router'; +import {NavbarComponent} from '../navbar/navbar.component'; + +@Component({ + selector: 'app-posts', + imports: [ + SearchbarComponent, + RouterLink, + NavbarComponent + ], + templateUrl: './posts.component.html', + standalone: true, + styleUrl: './posts.component.css' +}) +export class PostsComponent implements OnInit { + allPosts!: Post[]; + loggedInUser = localStorage.getItem('username'); + role = localStorage.getItem('role'); + + constructor(private readonly postService: PostsService) { } + + ngOnInit(): void { + this.postService.getPublishedPosts().subscribe({ + next:(data) => { + this.allPosts = data; + console.log('Posts:', data); + console.log('Logged post:', this.loggedInUser); + console.log('Role:', this.role); + }, + error:(error) => { + console.error('Error fetching posts:', error); + } + }); + } +} diff --git a/frontend-web/Frontend/src/app/component/review-details/review-details.component.css b/frontend-web/Frontend/src/app/component/review-details/review-details.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/review-details/review-details.component.html b/frontend-web/Frontend/src/app/component/review-details/review-details.component.html new file mode 100644 index 000000000..f4189fb69 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/review-details/review-details.component.html @@ -0,0 +1,41 @@ + +
+
+
{{ post.title }}
+

{{ post.author }}

+

{{ post.date }}

+

{{ post.content }}

+
+
+
+
+ +@for (review of reviews; track review) { + @if (review != null ) { +
+
+ @if(review.approved){ +

Approved

+

{{ review.description }}

+ } @else if(review.description != null && !review.approved) { +

Rejected

+

{{ review.description }}

+ } @else { +

Not reviewed yet

+ } +
+
+
+
+ } @else { +
+
+

Not reviewed yet

+
+
+
+
+ } +} + + diff --git a/frontend-web/Frontend/src/app/component/review-details/review-details.component.spec.ts b/frontend-web/Frontend/src/app/component/review-details/review-details.component.spec.ts new file mode 100644 index 000000000..ad2f97f62 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/review-details/review-details.component.spec.ts @@ -0,0 +1,92 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { of, throwError } from 'rxjs'; +import { ActivatedRoute } from '@angular/router'; +import { PostsService } from '../../services/posts.service'; +import { ReviewService } from '../../services/review.service'; +import { Post } from '../../shared/models/post/post.model'; +import { Review } from '../../shared/models/post/review.model'; +import { ReviewDetailsComponent } from './review-details.component'; + +describe('ReviewDetailsComponent', () => { + let component: ReviewDetailsComponent; + let fixture: ComponentFixture; + let mockPostsService: jasmine.SpyObj; + let mockReviewService: jasmine.SpyObj; + let mockActivatedRoute: any; + + beforeEach(async () => { + mockPostsService = jasmine.createSpyObj('PostsService', ['getPostById']); + mockReviewService = jasmine.createSpyObj('ReviewService', ['getReviews']); + mockActivatedRoute = { + snapshot: { + params: { + id: '123' + } + } + }; + + await TestBed.configureTestingModule({ + imports: [ReviewDetailsComponent], + providers: [ + { provide: PostsService, useValue: mockPostsService }, + { provide: ReviewService, useValue: mockReviewService }, + { provide: ActivatedRoute, useValue: mockActivatedRoute } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(ReviewDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should fetch post on init', () => { + const post: Post = { + id: 123, + title: 'Test Post', + content: 'Test Content', + author: 'Author', + date: '2025-01-01', + concept: true + }; + mockPostsService.getPostById.and.returnValue(of(post)); + + component.ngOnInit(); + + expect(mockPostsService.getPostById).toHaveBeenCalledWith(123); + expect(component.post).toEqual(post); + }); + + it('should handle error when fetching post', () => { + mockPostsService.getPostById.and.returnValue(throwError('Error fetching post')); + + spyOn(console, 'error'); + component.ngOnInit(); + + expect(mockPostsService.getPostById).toHaveBeenCalledWith(123); + expect(console.error).toHaveBeenCalledWith('Error fetching post:', 'Error fetching post'); + }); + + it('should fetch reviews on init', () => { + const reviews: Review[] = [{ description: 'Great review', approved: true }]; + mockReviewService.getReviews.and.returnValue(of(reviews)); + + component.ngOnInit(); + + expect(mockReviewService.getReviews).toHaveBeenCalledWith(123); + expect(component.reviews).toEqual(reviews); + }); + + it('should handle error when fetching reviews', () => { + mockReviewService.getReviews.and.returnValue(throwError('Error fetching review')); + + spyOn(console, 'error'); + component.ngOnInit(); + + expect(mockReviewService.getReviews).toHaveBeenCalledWith(123); + expect(console.error).toHaveBeenCalledWith('Error fetching review:', 'Error fetching review'); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/review-details/review-details.component.ts b/frontend-web/Frontend/src/app/component/review-details/review-details.component.ts new file mode 100644 index 000000000..dd043fb10 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/review-details/review-details.component.ts @@ -0,0 +1,45 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; +import {PostsService} from '../../services/posts.service'; +import {ReviewService} from '../../services/review.service'; +import {Post} from '../../shared/models/post/post.model'; +import {Review} from '../../shared/models/post/review.model'; +import {NavbarComponent} from '../navbar/navbar.component'; + +@Component({ + selector: 'app-review-details', + imports: [ + NavbarComponent + ], + standalone: true, + templateUrl: './review-details.component.html', + styleUrl: './review-details.component.css' +}) +export class ReviewDetailsComponent implements OnInit { + route: ActivatedRoute = inject(ActivatedRoute); + post!: Post; + reviews!: Review[]; + + constructor(private readonly postService: PostsService, private readonly reviewService: ReviewService) {} + + ngOnInit(): void { + this.postService.getPostById(this.route.snapshot.params['id']).subscribe({ + next:(data) => { + this.post = data; + }, + error:(error) => { + console.error('Error fetching post:', error); + } + }); + + this.reviewService.getReviews(this.route.snapshot.params['id']).subscribe({ + next:(data) => { + this.reviews = data; + }, + error:(error) => { + console.error('Error fetching review:', error); + } + }); + } + +} diff --git a/frontend-web/Frontend/src/app/component/review-post/review-post.component.css b/frontend-web/Frontend/src/app/component/review-post/review-post.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/review-post/review-post.component.html b/frontend-web/Frontend/src/app/component/review-post/review-post.component.html new file mode 100644 index 000000000..d82d20856 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/review-post/review-post.component.html @@ -0,0 +1,39 @@ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ + +
+ +
+ +
+ diff --git a/frontend-web/Frontend/src/app/component/review-post/review-post.component.spec.ts b/frontend-web/Frontend/src/app/component/review-post/review-post.component.spec.ts new file mode 100644 index 000000000..712cbd1ed --- /dev/null +++ b/frontend-web/Frontend/src/app/component/review-post/review-post.component.spec.ts @@ -0,0 +1,103 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReviewPostComponent } from './review-post.component'; +import { PostsService } from '../../services/posts.service'; +import { ReviewService } from '../../services/review.service'; +import { NotificationService } from '../../services/notification.service'; +import { DatePipe } from '@angular/common'; +import { ActivatedRoute, Router } from '@angular/router'; +import { of, throwError } from 'rxjs'; + +describe('ReviewPostComponent', () => { + let component: ReviewPostComponent; + let fixture: ComponentFixture; + let postsService: jasmine.SpyObj; + let reviewService: jasmine.SpyObj; + let notificationService: jasmine.SpyObj; + let router: jasmine.SpyObj; + let activatedRoute: ActivatedRoute; + + beforeEach(async () => { + const postsServiceSpy = jasmine.createSpyObj('PostsService', ['getPostById']); + const reviewServiceSpy = jasmine.createSpyObj('ReviewService', ['reviewPost']); + const notificationServiceSpy = jasmine.createSpyObj('NotificationService', ['addNotification']); + const routerSpy = jasmine.createSpyObj('Router', ['navigate']); + + await TestBed.configureTestingModule({ + imports: [ReviewPostComponent], + providers: [ + DatePipe, + { provide: PostsService, useValue: postsServiceSpy }, + { provide: ReviewService, useValue: reviewServiceSpy }, + { provide: NotificationService, useValue: notificationServiceSpy }, + { provide: Router, useValue: routerSpy }, + //{ provide: ActivatedRoute, useValue: { snapshot: { params: { id: 1 } } } }, + { provide: ActivatedRoute, useValue: { snapshot: { params: { id: 1 } }, params: of({ id: 1 }) } } + ] + }).compileComponents(); + + fixture = TestBed.createComponent(ReviewPostComponent); + component = fixture.componentInstance; + postsService = TestBed.inject(PostsService) as jasmine.SpyObj; + reviewService = TestBed.inject(ReviewService) as jasmine.SpyObj; + notificationService = TestBed.inject(NotificationService) as jasmine.SpyObj; + router = TestBed.inject(Router) as jasmine.SpyObj; + activatedRoute = TestBed.inject(ActivatedRoute); + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should fetch post on init', () => { + const post = { id: 1, title: 'Test Post', content: 'Test Content', author: 'Author', date: '2025-01-01', concept: true }; + postsService.getPostById.and.returnValue(of(post)); + + component.ngOnInit(); + + expect(postsService.getPostById).toHaveBeenCalledWith(1); + expect(component.post).toEqual(post); + }); + + it('should handle error when fetching post', () => { + postsService.getPostById.and.returnValue(throwError('Error')); + + component.ngOnInit(); + + expect(postsService.getPostById).toHaveBeenCalledWith(1); + expect(component.post).toBeUndefined(); + }); + + it('should approve post', () => { + component.reviewMessage = 'Approved'; + component.post = { id: 1, title: 'Test Post', content: 'Test Content', author: 'Author', date: '2025-01-01', concept: true }; + // reviewService.reviewPost.and.returnValue(of({})); + + component.approvePost(); + + expect(component.review.approved).toBeTrue(); + expect(notificationService.addNotification).toHaveBeenCalledWith('Test Post has been approved'); + expect(reviewService.reviewPost).toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith(['/posts']); + }); + + it('should reject post', () => { + component.reviewMessage = 'Rejected'; + component.post = { id: 1, title: 'Test Post', content: 'Test Content', author: 'Author', date: '2025-01-01', concept: true }; + //reviewService.reviewPost.and.returnValue(of({})); + + component.rejectPost(); + + expect(component.review.approved).toBeFalse(); + expect(notificationService.addNotification).toHaveBeenCalledWith('Test Post has been rejected'); + expect(reviewService.reviewPost).toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith(['/concepts']); + }); + + it('should navigate to concepts on cancel', () => { + component.cancelReview(); + + expect(router.navigate).toHaveBeenCalledWith(['/concepts']); + }); +}); diff --git a/frontend-web/Frontend/src/app/component/review-post/review-post.component.ts b/frontend-web/Frontend/src/app/component/review-post/review-post.component.ts new file mode 100644 index 000000000..0ebdc84cb --- /dev/null +++ b/frontend-web/Frontend/src/app/component/review-post/review-post.component.ts @@ -0,0 +1,94 @@ +import {Component, inject, OnInit} from '@angular/core'; +import {NavbarComponent} from '../navbar/navbar.component'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Post} from '../../shared/models/post/post.model'; +import {PostsService} from '../../services/posts.service'; +import {DatePipe} from '@angular/common'; +import {ReviewService} from '../../services/review.service'; +import {Review} from '../../shared/models/post/review.model'; +import {NotificationService} from '../../services/notification.service'; + +@Component({ + selector: 'app-review-post', + imports: [ + NavbarComponent, + ReactiveFormsModule, + FormsModule + ], + providers: [DatePipe], + standalone: true, + templateUrl: './review-post.component.html', + styleUrl: './review-post.component.css' +}) +export class ReviewPostComponent implements OnInit { + route: ActivatedRoute = inject(ActivatedRoute); + post!: Post; + router: Router = inject(Router); + userRole: string = localStorage.getItem('role') || ''; + postId!: number; + newTitle!: string; + newContent!: string; + newAuthor!: string; + newDate!: string; + concept!: boolean; + reviewMessage!: string; + review: Review = {description: '', approved: false}; + + constructor(private readonly postService: PostsService, private readonly reviewService: ReviewService ,private readonly datePipe: DatePipe, private readonly notificationService: NotificationService) {} + + ngOnInit(): void { + console.log(this.route.snapshot.params['id']); + this.postId = this.route.snapshot.params['id']; + this.postService.getPostById(this.postId).subscribe({ + next: (data) => { + console.log(data); + this.post = data; + this.newTitle = this.post.title; + this.newContent = this.post.content; + this.newAuthor = this.post.author; + this.newDate = this.datePipe.transform(this.post.date, 'yyyy-MM-dd')!; + this.concept = this.post.concept; + }, + error: (error) => { + console.error('Error fetching post:', error); + } + }); + } + + approvePost() { + this.review.approved = true; + this.review.description = this.reviewMessage; + this.notificationService.addNotification(this.post.title + ' has been approved'); + console.log(this.review); + this.reviewService.reviewPost(this.postId, this.review, this.userRole).subscribe({ + next: (data) => { + console.log('Post reviewed:', data); + this.router.navigate(['/posts']) + }, + error: (error) => { + console.error('Error reviewing post:', error); + } + }); + } + + rejectPost() { + this.review.approved = false; + this.review.description = this.reviewMessage; + this.notificationService.addNotification(this.post.title + ' has been rejected'); + console.log(this.review); + this.reviewService.reviewPost(this.postId, this.review, this.userRole).subscribe({ + next: (data) => { + console.log('Post reviewed:', data); + this.router.navigate(['/concepts']) + }, + error: (error) => { + console.error('Error reviewing post:', error); + } + }); + } + + cancelReview() { + this.router.navigate(['/concepts']); + } +} diff --git a/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.css b/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.html b/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.html new file mode 100644 index 000000000..1c04777eb --- /dev/null +++ b/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.html @@ -0,0 +1,35 @@ +
+
+ + +
+ + +
+ @if (this.showDatePicker) { + + } +
+
diff --git a/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.spec.ts b/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.spec.ts new file mode 100644 index 000000000..3ec322091 --- /dev/null +++ b/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.spec.ts @@ -0,0 +1,114 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { SearchbarComponent } from './searchbar.component'; +import { PostsService } from '../../services/posts.service'; +import { of, throwError } from 'rxjs'; +import { PostsComponent } from '../posts/posts.component'; +import { Router } from '@angular/router'; + +describe('SearchbarComponent', () => { + let component: SearchbarComponent; + let fixture: ComponentFixture; + let postsService: jasmine.SpyObj; + let router: jasmine.SpyObj; + + beforeEach(async () => { + const postsServiceSpy = jasmine.createSpyObj('PostsService', ['getPublishedPosts', 'getAllPostsByTitle', 'getPostByAuthor', 'getPostByContent', 'getPostByDate']); + const routerSpy = jasmine.createSpyObj('Router', ['navigate']); + + await TestBed.configureTestingModule({ + imports: [SearchbarComponent], + providers: [ + { provide: PostsService, useValue: postsServiceSpy }, + { provide: Router, useValue: routerSpy } + ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SearchbarComponent); + component = fixture.componentInstance; + postsService = TestBed.inject(PostsService) as jasmine.SpyObj; + router = TestBed.inject(Router) as jasmine.SpyObj; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should toggle dropdown visibility', () => { + component.isDropdownVisible = false; + component.toggleDropdown(); + expect(component.isDropdownVisible).toBeTrue(); + component.toggleDropdown(); + expect(component.isDropdownVisible).toBeFalse(); + }); + + it('should set filter and reset search value', () => { + component.setFilter('Titel'); + expect(component.filter).toBe('Titel'); + expect(component.searchValue).toBe(''); + expect(component.showDatePicker).toBeFalse(); + + component.setFilter('Datum'); + expect(component.filter).toBe('Datum'); + expect(component.searchValue).toBe(''); + expect(component.showDatePicker).toBeTrue(); + }); + + it('should fetch published posts on init', () => { + const mockPosts = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false + }]; + postsService.getPublishedPosts.and.returnValue(of(mockPosts)); + + component.ngOnInit(); + + expect(postsService.getPublishedPosts).toHaveBeenCalled(); + expect(component.postsComponent.allPosts).toEqual(mockPosts); + }); + + it('should handle error when fetching published posts', () => { + const error = new Error('Error fetching posts'); + postsService.getPublishedPosts.and.returnValue(throwError(error)); + + spyOn(console, 'error'); + component.ngOnInit(); + + expect(postsService.getPublishedPosts).toHaveBeenCalled(); + expect(console.error).toHaveBeenCalledWith('Error fetching posts:', error); + }); + + it('should search posts by title', () => { + const mockPosts = [{ id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false }]; + component.searchValue = 'Test'; + postsService.getAllPostsByTitle.and.returnValue(of(mockPosts)); + + component.searchOnFilter('Titel'); + + expect(postsService.getAllPostsByTitle).toHaveBeenCalledWith('Test'); + expect(component.postsComponent.allPosts).toEqual(mockPosts); + }); + + it('should handle error when searching posts by title', () => { + const error = new Error('Error fetching post'); + component.searchValue = 'Test'; + postsService.getAllPostsByTitle.and.returnValue(throwError(error)); + + spyOn(console, 'error'); + component.searchOnFilter('Titel'); + + expect(postsService.getAllPostsByTitle).toHaveBeenCalledWith('Test'); + expect(console.error).toHaveBeenCalledWith('Error fetching post:', error); + }); + +}); diff --git a/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.ts b/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.ts new file mode 100644 index 000000000..162aaa3ed --- /dev/null +++ b/frontend-web/Frontend/src/app/component/searchbar/searchbar.component.ts @@ -0,0 +1,106 @@ +import {Component, inject, Input, OnInit} from '@angular/core'; +import {NgClass} from '@angular/common'; +import {PostsService} from '../../services/posts.service'; +import {Post} from '../../shared/models/post/post.model'; +import {FormsModule} from '@angular/forms'; +import {Router} from '@angular/router'; +import {PostsComponent} from '../posts/posts.component'; +import {DatepickerComponent} from '../datepicker/datepicker.component'; + +@Component({ + selector: 'app-searchbar', + imports: [ + NgClass, + FormsModule, + DatepickerComponent + ], + standalone: true, + templateUrl: './searchbar.component.html', + styleUrl: './searchbar.component.css' +}) +export class SearchbarComponent implements OnInit { + router: Router = inject(Router); + isDropdownVisible: boolean = false; + filter: string = "Filter"; + searchValue!: string; + posts!: Post[]; + dateValue!: string; + @Input() postsComponent!: PostsComponent; + showDatePicker: boolean = false; + + constructor(private readonly postService: PostsService) { + } + + ngOnInit(): void { + this.postService.getPublishedPosts().subscribe({ + next: (data) => { + this.postsComponent.allPosts = data; + console.log('Posts:', data); + }, + error: (error) => { + console.error('Error fetching posts:', error); + } + }); + } + + toggleDropdown() { + this.isDropdownVisible = !this.isDropdownVisible; + } + + setFilter(filter: string) { + this.filter = filter; + this.searchValue = ''; + if(filter === 'Datum'){ + this.showDatePicker = true; + } + this.isDropdownVisible = false; + + } + + searchOnFilter(filter: string) { + if (filter === 'Titel'){ + this.postService.getAllPostsByTitle(this.searchValue).subscribe({ + next: (data) => { + console.log(data); + this.postsComponent.allPosts = data; + }, + error: (error) => { + console.error('Error fetching post:', error); + } + }); + }else if(filter === 'Auteur'){ + this.postService.getPostByAuthor(this.searchValue).subscribe({ + next: (data) => { + console.log(data); + this.postsComponent.allPosts = data; + }, + error: (error) => { + console.error('Error fetching post:', error); + } + }); + }else if(filter === 'Inhoud'){ + this.postService.getPostByContent(this.searchValue).subscribe({ + next: (data) => { + console.log(data); + this.postsComponent.allPosts = data; + }, + error: (error) => { + console.error('Error fetching post:', error); + } + }); + + }else if(filter === 'Datum'){ + this.dateValue = this.searchValue; + this.postService.getPostByDate(this.dateValue).subscribe({ + next: (data) => { + console.log(data); + this.postsComponent.allPosts = data; + }, + error: (error) => { + console.error('Error fetching post:', error); + } + }); + } + + } +} diff --git a/frontend-web/Frontend/src/app/services/auth.service.spec.ts b/frontend-web/Frontend/src/app/services/auth.service.spec.ts new file mode 100644 index 000000000..0f9748293 --- /dev/null +++ b/frontend-web/Frontend/src/app/services/auth.service.spec.ts @@ -0,0 +1,39 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AuthService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should have a login method', () => { + expect(service.logIn).toBeTruthy(); + }); + + it('should have a logout method', () => { + expect(service.logOut).toBeTruthy(); + }); + + it('should store username and role on login', () => { + service.logIn('testUser', true); + expect(localStorage.getItem('username')).toBe('testUser'); + expect(localStorage.getItem('role')).toBe('editor'); + }); + + it('should remove username and role on logout', () => { + localStorage.setItem('username', 'testUser'); + localStorage.setItem('role', 'editor'); + service.logOut(); + expect(localStorage.getItem('username')).toBeNull(); + expect(localStorage.getItem('role')).toBeNull(); + }); + +}); diff --git a/frontend-web/Frontend/src/app/services/auth.service.ts b/frontend-web/Frontend/src/app/services/auth.service.ts new file mode 100644 index 000000000..8f394f982 --- /dev/null +++ b/frontend-web/Frontend/src/app/services/auth.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + + + constructor() { } + + logIn(username: string, isEditor: boolean) { + localStorage.setItem('username', username); + localStorage.setItem('role', isEditor ? 'editor' : 'user'); + } + + logOut(){ + localStorage.removeItem('username'); + localStorage.removeItem('role'); + } +} diff --git a/frontend-web/Frontend/src/app/services/comment.service.spec.ts b/frontend-web/Frontend/src/app/services/comment.service.spec.ts new file mode 100644 index 000000000..3fcba87d2 --- /dev/null +++ b/frontend-web/Frontend/src/app/services/comment.service.spec.ts @@ -0,0 +1,102 @@ +import { TestBed } from '@angular/core/testing'; +import { CommentService } from './comment.service'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { Comment } from '../shared/models/post/comment.model'; + +describe('CommentService', () => { + let service: CommentService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + providers: [CommentService] + }); + service = TestBed.inject(CommentService); + httpMock = TestBed.inject(HttpTestingController); + }); + + afterEach(() => { + httpMock.verify(); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should retrieve comments', () => { + const dummyComments: Comment[] = [ + { id: 1, content: 'Test Comment 1', author: 'Author 1', postId: 1 }, + { id: 2, content: 'Test Comment 2', author: 'Author 2', postId: 1 } + ]; + + service.getComments().subscribe(comments => { + expect(comments.length).toBe(2); + expect(comments).toEqual(dummyComments); + }); + + const req = httpMock.expectOne(service['apiUrl']); + expect(req.request.method).toBe('GET'); + req.flush(dummyComments); + }); + + it('should add a comment', () => { + const newComment: Comment = { id: 3, content: 'New Comment', author: 'Author 3', postId: 1 }; + + service.addComment('1', newComment).subscribe(comment => { + expect(comment).toEqual(newComment); + }); + + const req = httpMock.expectOne(`${service['apiUrl']}/1`); + expect(req.request.method).toBe('POST'); + req.flush(newComment); + }); + + it('should retrieve a comment by id', () => { + const dummyComment: Comment = { id: 1, content: 'Test Comment', author: 'Author 1', postId: 1 }; + + service.getCommentById(1).subscribe(comment => { + expect(comment).toEqual(dummyComment); + }); + + const req = httpMock.expectOne(`${service['apiUrl']}/1`); + expect(req.request.method).toBe('GET'); + req.flush(dummyComment); + }); + + it('should retrieve a comment by author', () => { + const dummyComment: Comment = { id: 1, content: 'Test Comment', author: 'Author 1', postId: 1 }; + + service.getCommentByAuthor('Author 1').subscribe(comment => { + expect(comment).toEqual(dummyComment); + }); + + const req = httpMock.expectOne(`${service['apiUrl']}/findByAuthor?author=Author 1`); + expect(req.request.method).toBe('GET'); + req.flush(dummyComment); + }); + + it('should update a comment', () => { + const updatedComment: Comment = { id: 1, content: 'Updated Comment', author: 'Author 1', postId: 1 }; + + service.updateComment(1, updatedComment).subscribe(comment => { + expect(comment).toEqual(updatedComment); + }); + + const req = httpMock.expectOne(`${service['apiUrl']}/1`); + expect(req.request.method).toBe('PUT'); + req.flush(updatedComment); + }); + + it('should delete a comment', () => { + const dummyComment: Comment = { id: 1, content: 'Test Comment', author: 'Author 1', postId: 1 }; + + service.deleteComment(1).subscribe(comment => { + expect(comment).toEqual(dummyComment); + }); + + const req = httpMock.expectOne(`${service['apiUrl']}/1`); + expect(req.request.method).toBe('DELETE'); + req.flush(dummyComment); + }); +}); diff --git a/frontend-web/Frontend/src/app/services/comment.service.ts b/frontend-web/Frontend/src/app/services/comment.service.ts new file mode 100644 index 000000000..52abfe15c --- /dev/null +++ b/frontend-web/Frontend/src/app/services/comment.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {Observable} from 'rxjs'; +import {Post} from '../shared/models/post/post.model'; +import {Comment} from '../shared/models/post/comment.model'; + +@Injectable({ + providedIn: 'root' +}) +export class CommentService { + private readonly apiUrl = "http://localhost:8095/comment/api/comments" + constructor(private readonly http: HttpClient) { } + + getComments(): Observable { + return this.http.get(this.apiUrl); + } + + addComment(postId: string, comment: Comment): Observable { + return this.http.post(`${this.apiUrl}/${postId}`, comment); + } + + getCommentById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + getCommentByAuthor(author: string): Observable { + return this.http.get(`${this.apiUrl}/findByAuthor?author=${author}`); + } + + updateComment(commentId: number, comment: Comment): Observable { + return this.http.put(`${this.apiUrl}/${commentId}`, comment); + } + + deleteComment(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } + +} diff --git a/frontend-web/Frontend/src/app/services/notification.service.spec.ts b/frontend-web/Frontend/src/app/services/notification.service.spec.ts new file mode 100644 index 000000000..c4f2cd67e --- /dev/null +++ b/frontend-web/Frontend/src/app/services/notification.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { NotificationService } from './notification.service'; + +describe('NotificationService', () => { + let service: NotificationService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(NotificationService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/frontend-web/Frontend/src/app/services/notification.service.ts b/frontend-web/Frontend/src/app/services/notification.service.ts new file mode 100644 index 000000000..3c94ab932 --- /dev/null +++ b/frontend-web/Frontend/src/app/services/notification.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class NotificationService { + notifications: string[] = []; + + constructor() { } + + addNotification(notification: string): void { + this.notifications.push(notification); + } + + getNotifications(): string[] { + return this.notifications; + } +} diff --git a/frontend-web/Frontend/src/app/services/posts.service.spec.ts b/frontend-web/Frontend/src/app/services/posts.service.spec.ts new file mode 100644 index 000000000..3e81c2e5e --- /dev/null +++ b/frontend-web/Frontend/src/app/services/posts.service.spec.ts @@ -0,0 +1,213 @@ +import { TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { PostsService } from './posts.service'; +import { Post } from '../shared/models/post/post.model'; + +describe('PostsService', () => { + let service: PostsService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + providers: [PostsService] + }); + service = TestBed.inject(PostsService); + httpMock = TestBed.inject(HttpTestingController); + }); + + afterEach(() => { + httpMock.verify(); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should fetch posts', () => { + const dummyPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false + }]; + service.getPosts().subscribe(posts => { + expect(posts.length).toBe(1); + expect(posts).toEqual(dummyPosts); + }); + const req = httpMock.expectOne(service['apiUrl']); + expect(req.request.method).toBe('GET'); + req.flush(dummyPosts); + }); + + it('should fetch concept posts', () => { + const dummyPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false + }]; + service.getConceptPosts().subscribe(posts => { + expect(posts.length).toBe(1); + expect(posts).toEqual(dummyPosts); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/concept`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPosts); + }); + + it('should fetch published posts', () => { + const dummyPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false }]; + service.getPublishedPosts().subscribe(posts => { + expect(posts.length).toBe(1); + expect(posts).toEqual(dummyPosts); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/published`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPosts); + }); + + it('should add a post', () => { + const newPost: Post = { + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false }; + service.addPost(newPost, 'admin').subscribe(post => { + expect(post).toEqual(newPost); + }); + const req = httpMock.expectOne(service['apiUrl']); + expect(req.request.method).toBe('POST'); + expect(req.request.headers.get('User-Role')).toBe('admin'); + req.flush(newPost); + }); + + it('should fetch post by title', () => { + const dummyPost: Post = { + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false}; + service.getPostByTitle('Test Post').subscribe(post => { + expect(post).toEqual(dummyPost); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/findByTitle?title=Test Post`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPost); + }); + + it('should fetch post by id', () => { + const dummyPost: Post = { + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false}; + service.getPostById(1).subscribe(post => { + expect(post).toEqual(dummyPost); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/findById/1`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPost); + }); + + it('should fetch all posts by title', () => { + const dummyPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false }]; + service.getAllPostsByTitle('Test Post').subscribe(posts => { + expect(posts.length).toBe(1); + expect(posts).toEqual(dummyPosts); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/findAllPostWithTitle?title=Test Post`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPosts); + }); + + it('should fetch posts by author', () => { + const dummyPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false }]; + service.getPostByAuthor('Author').subscribe(posts => { + expect(posts.length).toBe(1); + expect(posts).toEqual(dummyPosts); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/findByAuthor?author=Author`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPosts); + }); + + it('should fetch posts by content', () => { + const dummyPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false}]; + service.getPostByContent('Test Content').subscribe(posts => { + expect(posts.length).toBe(1); + expect(posts).toEqual(dummyPosts); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/findByContent?content=Test Content`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPosts); + }); + + it('should fetch posts by date', () => { + const dummyPosts: Post[] = [{ + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false }]; + service.getPostByDate('2023-01-01').subscribe(posts => { + expect(posts.length).toBe(1); + expect(posts).toEqual(dummyPosts); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/findByDate?date=2023-01-01`); + expect(req.request.method).toBe('GET'); + req.flush(dummyPosts); + }); + + it('should update a post', () => { + const updatedPost: Post = { + id: 1, + title: 'Test Post', + content: 'Test Content', + author: 'ilias', + date: '2025-01-01', + concept: false }; + service.updatePost(updatedPost, 'admin').subscribe(post => { + expect(post).toEqual(updatedPost); + }); + const req = httpMock.expectOne(`${service['apiUrl']}/update/1`); + expect(req.request.method).toBe('POST'); + expect(req.request.headers.get('User-Role')).toBe('admin'); + req.flush(updatedPost); + }); +}); diff --git a/frontend-web/Frontend/src/app/services/posts.service.ts b/frontend-web/Frontend/src/app/services/posts.service.ts new file mode 100644 index 000000000..eb1c1ebed --- /dev/null +++ b/frontend-web/Frontend/src/app/services/posts.service.ts @@ -0,0 +1,56 @@ +import { Injectable } from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {Observable} from 'rxjs'; +import {Post} from '../shared/models/post/post.model'; + +@Injectable({ + providedIn: 'root' +}) +export class PostsService { + private readonly apiUrl = "http://localhost:8095/post/api/posts" + constructor(private readonly http: HttpClient) { } + + getPosts(): Observable { + return this.http.get(this.apiUrl); + } + + getConceptPosts(): Observable { + return this.http.get(this.apiUrl + "/concept"); + } + + getPublishedPosts(): Observable { + return this.http.get(this.apiUrl + "/published"); + } + + addPost(post: Post, userRole: string): Observable { + return this.http.post(this.apiUrl, post, {headers : {'User-Role': userRole}}); + } + + getPostByTitle(title: string): Observable { + return this.http.get(`${this.apiUrl}/findByTitle?title=${title}`); + } + + getPostById(id: number): Observable { + return this.http.get(`${this.apiUrl}/findById/${id}`); + } + + getAllPostsByTitle(title: string): Observable { + return this.http.get(`${this.apiUrl}/findAllPostWithTitle?title=${title}`); + } + + getPostByAuthor(author: string): Observable { + return this.http.get(`${this.apiUrl}/findByAuthor?author=${author}`); + } + + getPostByContent(concept: string): Observable { + return this.http.get(`${this.apiUrl}/findByContent?content=${concept}`); + } + + getPostByDate(date: string): Observable { + return this.http.get(`${this.apiUrl}/findByDate?date=${date}`); + } + + updatePost(post: Post, userRole: string): Observable { + return this.http.post(`${this.apiUrl}/update/${post.id}`, post, {headers : {'User-Role': userRole}}); + } +} diff --git a/frontend-web/Frontend/src/app/services/review.service.spec.ts b/frontend-web/Frontend/src/app/services/review.service.spec.ts new file mode 100644 index 000000000..d376549d4 --- /dev/null +++ b/frontend-web/Frontend/src/app/services/review.service.spec.ts @@ -0,0 +1,67 @@ +import { TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { ReviewService } from './review.service'; +import { Review } from '../shared/models/post/review.model'; + +describe('ReviewService', () => { + let service: ReviewService; + let httpMock: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule], + providers: [ReviewService] + }); + service = TestBed.inject(ReviewService); + httpMock = TestBed.inject(HttpTestingController); + }); + + afterEach(() => { + httpMock.verify(); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should fetch reviews', () => { + const dummyReviews: Review[] = [ + { description: 'Great post!', approved: true }, + { description: 'Very informative.', approved: true } + ]; + + service.getReviews(1).subscribe(reviews => { + expect(reviews.length).toBe(2); + expect(reviews).toEqual(dummyReviews); + }); + + const req = httpMock.expectOne('http://localhost:8095/review/api/reviews/1'); + expect(req.request.method).toBe('GET'); + req.flush(dummyReviews); + }); + + it('should review a post', () => { + const dummyReview: Review = { description: 'Great post!', approved: true }; + + service.reviewPost(1, dummyReview, 'admin').subscribe(review => { + expect(review).toEqual(dummyReview); + }); + + const req = httpMock.expectOne('http://localhost:8095/review/api/reviews/review/1'); + expect(req.request.method).toBe('PUT'); + expect(req.request.headers.get('User-Role')).toBe('admin'); + req.flush(dummyReview); + }); + + it('should delete a review', () => { + const dummyReview: Review = { description: 'Great post!', approved: true }; + + service.deleteReview(1).subscribe(review => { + expect(review).toEqual(dummyReview); + }); + + const req = httpMock.expectOne('http://localhost:8095/review/api/reviews/1'); + expect(req.request.method).toBe('DELETE'); + req.flush(dummyReview); + }); +}); diff --git a/frontend-web/Frontend/src/app/services/review.service.ts b/frontend-web/Frontend/src/app/services/review.service.ts new file mode 100644 index 000000000..d35e8eb9d --- /dev/null +++ b/frontend-web/Frontend/src/app/services/review.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {Observable} from 'rxjs'; +import {Post} from '../shared/models/post/post.model'; +import {Review} from '../shared/models/post/review.model'; + +@Injectable({ + providedIn: 'root' +}) +export class ReviewService { + private readonly apiUrl = "http://localhost:8095/review/api/reviews" + constructor(private readonly http: HttpClient) { } + + getReviews(postId: number): Observable { + return this.http.get(`${this.apiUrl}/${postId}`); + } + + reviewPost(postId: number, review: Review, userRole: string): Observable { + return this.http.put(`${this.apiUrl}/review/${postId}`, review, {headers : {'User-Role': userRole}}); + } + + deleteReview(postId: number): Observable { + return this.http.delete(`${this.apiUrl}/${postId}`); + } + + +} diff --git a/frontend-web/Frontend/src/app/shared/models/post/comment.model.ts b/frontend-web/Frontend/src/app/shared/models/post/comment.model.ts new file mode 100644 index 000000000..df9f83b63 --- /dev/null +++ b/frontend-web/Frontend/src/app/shared/models/post/comment.model.ts @@ -0,0 +1,6 @@ +export interface Comment { + id: number; + author: string; + content: string; + postId: number; +} diff --git a/frontend-web/Frontend/src/app/shared/models/post/post.model.ts b/frontend-web/Frontend/src/app/shared/models/post/post.model.ts new file mode 100644 index 000000000..4b2bf0f0b --- /dev/null +++ b/frontend-web/Frontend/src/app/shared/models/post/post.model.ts @@ -0,0 +1,9 @@ + +export interface Post { + id: number; + title: string; + author: string; + content: string; + date: string; + concept: boolean; +} diff --git a/frontend-web/Frontend/src/app/shared/models/post/review.model.ts b/frontend-web/Frontend/src/app/shared/models/post/review.model.ts new file mode 100644 index 000000000..924989a99 --- /dev/null +++ b/frontend-web/Frontend/src/app/shared/models/post/review.model.ts @@ -0,0 +1,4 @@ +export interface Review { + description: string; + approved: boolean; +} diff --git a/frontend-web/Frontend/src/assets/asta.png b/frontend-web/Frontend/src/assets/asta.png new file mode 100644 index 0000000000000000000000000000000000000000..1f36fedfd29191eed49348cc6625fe0066113e67 GIT binary patch literal 30540 zcmV(vKF?#gxc{O53H`(V zzxeNvU&cR`e}ewu{xAJc_b=U#s~?^JiT<0t*JA%o{{Q^XurIMcQ2$B(3;hTFFY#WI zKiz+d^-uJF@IUVV&3;CGfd4N3r~bS9-|tuW|NsB|zV832;NSTF`X9A_06);b!hh2L zQTdznsr?uJAM=0fKXJXa{)zru{{Q)(_CL12VL#2kvVXn*3I3D+fB8@U|NQ)ye)|9a z|Nrqr``U6kbLlz*x{0gH_z1!e0ud3dd)3kpVB``(VA(UNjESYcDmQ*-<|s@6yC2;&UXa3#Kx8fpyJugH z*Z=Bg=WM2=`n<_kr}c2xy=Er8h@_)SQ+n%jP;1o6^4(JBjmRs}cM=#$^BJ22+|bJd zg|Aq?r&Q5{i%okm;-F=Rkip z`n_j@PXGTILH<>`9dPaZf&-gS9B6-i$}uiBo*5gBg4A_!`1i#W;qA#5t@{^W)qgVM z-M#}GG+ClpK2j(M*{n{ z-uL^hZRBMkvdB>ym)ZS4{%DGN@}ZZrVCQ-`5&HcbddTo{&hm4xFQI}WY0d_S&P28W z;fpoo>pYeXW^pr>LjiKNw+>ey=1!fBh5s$!%PMxzR=|ZM;h$1A=ogW2v$q1H8H>J| zKql~{i0+R=L3jN?S1oIi&x7aI+Zcy<*O_&jxq6%Qwsn-=Rb3DP=F3;l4$BRFkUn=l zs!RqIIOaNj2JJr<542$=|5t*jXlzPxFMKtR`M0#esyk;B@PK0-z5m{n^Jl9Ctu;@gZosA`-yD_h@6o=(jbH54DchzWhHRaJ2_ ziAbwcm_hm;Apf#8)V(BLYd~~QF<>i39GLq#G9YnCxS+MSDSHOk41$SATuA}DxGMqO zhzv|TKMfymmwxGcpa){?9FX?|^V+K`OL;*Rn5KK}4f}%(*z77IVu{ckZ@gT zgW}v3*lF`v7cmtrPzpG^DYM=LM{v726?CFe>BIjC-GEfNLqzf7=@?f$ z;8aukmz55pY8l|MDa0ppSyFD=>8a^Ciu5M4zk2xu#cHEAkHX6 zc9sOkQ!__J>s$L|bs6mM(H`K52eSj*No$h>Ateih8J2IV=7C zc6dnT|9i7|j(DZ$`*^mxyz?c0C?D3Jt<pB_OE24{ zNfwoX-3p!6BYCy=GJE^4+NAKrivfM~g^iwPL-ErMQ^HyRt+&;~dSW`f{h<%iXb+GZ z;1Y@a4a+rVk4OEU3=mwB`b+@59zXgq1D2D3wV#i76CB*#*T)DD4%8u@B|by~^y9}a zg`$t!W}9^Ty1pw;3K%=JP1oYmvk+ZMjs|fL0{J{m;SjR0Bq6VY60nA)&OPc1b(c(L&{5W=e*DT?RLQexPyd2m6aL>tC+k*vwm5<}y&11p+-2yi1(C=<{&la)Cz+IGO$%LF) zCC{?p*7s4G$rWv4?#Hj(&EJj6`bp~CBmsi@*Uj!r$2t5Q!vGF}ABeqfkfhe~cyDUf zYO&V30~)8|KoM7<$jEa#F0M#s-`6DYEyo>ma)n@VmNdF>ErP0RFT6O?oRx)L>|y(9 z>>XALs0}NRa6=_3z27cCXt^0GVQP*f_6io^Qt5W5F_~M8dv6NGK>Rr7@yn*VPUD?q z=%X+z&4(+e#`_@;;PhRNz3NDdZ|7SSNydCs7kU1gE%u+PazLxC!Zo7NHI;#OR8k;4 zAhdMB%%7udXx$E>l!M%wi8o;u&Z$!O=Er!c?{1yzZn?qe4ok0n9@DIT=oE6+?FnHV zNtaI2w%*8~ev0g{yj~?LS1RCDVRpo@VeD{v91(xuZO_gGUFsw5o}Ge&Dz6~*DeQ-e zXL2{!~d>?_LaXbH2pz`DZs+dL$TNMaG+E1kavOcjt zPD!31u<8-YAWKz{Ll`!{3Ce;=2q(hUt&J&Ar!~gozES~8zEjqakB~HJ zmxb)CRMx&VbOJkFBqpiGho?)RW8b#WNGpM7R@9SX(3 z>X3Z-xTY|ZU(_?fUvq&t&r-~+xf!xwv9bszw+g6N{@*6ERaWD>P=j2TO|Sjc;*U7+ z2$u=vAxqyfd34kNG&8Gm|DcDj&06#UkS)DNZTQ^Od!uydf3}NvIqkSrPRav~z+>vJ z-NStZ4^A`wrD6aI+Ac-Q-mQdb-;Y~{3TK(7Sr!mb(X5KH=m)ruV65!vdPql%WBHAz zSy53Tk2`)S!}(Pi(G2r0NgM)?*4_U|tm#@fyR0 zMF;@?_Y3Zo%b-S(93Y}x&@L%$5btssln66=klYp}>c8d^Z5@eL;Gwy`2Vpx*l$Cce zS=3K{&kc2Nt<_vt(6*WaXcs01^E6)_xK68XB{oF0>Rhxnmp@PWed%0V!}dA>RiPC* zCQb?H?V5a`=3RU2fz0_p;tEj~`hdM1H{erwFR{1U0jv3Y>+PREF*+KR?JHEwnif%0 zrBqH{P~;!q!x~~P$V8@wS;seiK$6cDl`pXMHs`Szz-b_7Y+1TLBr7GZET;~ZigKKF z-lu_uovsg(u;knUBrnJRQ_Hg?krCi!*m=L@WgvpK(1cs=<6zGwk<_?vV*#za zMU%!?AljpFGAaZ-vRFF-zv@!2P1&q)RNYO?Zdqai%&nV?ch3?+Su|;npx*aV?SXM^ zwY;s{Ca-w>y4*AxR=dCtZPhv5EKF26{QEbF@^$^I?7Du{X~wnUW;d4ZKYD+IJCP|r zAyCQ|f?b%1U>ThcMHx9dOzdWQh&=K^*x|35pXO9q&R;K;*g$`yx=mn?U5?1(NE(*) zut}B8eI6iCiyU=_LyE2o*R_3{wFdV#el4(c+t84)eEmgNGb~x}vAc%!KMQ_tiA&%LA`<(*xPbL_l6NcE zT`6NOsA*3;_=iV77+H|ae_(g2PjbMysw%Z#nxnLo3zQb>PFie&L2=sWnMqY7;@^uF zAXOa?&ax*H^BJc)`r{<4N%a6mq8FG?Lxh0mT!;7G_*mOY$P!{EwNmi*1f4KEr%dr< z4atbdDkp@h0F%x|R zD$mzuJ~~K5q_S>yi3eNq!&CDH`2l{0S8%~j&4V!ARZ%<$U|M+$N`br`DwE|gxqsgM z%=5QLwb{x5;`gjvfaWvjWL5pU9HRYHOj;=6WrOL5ZEn9!L%5;1nbi@xJ>h@!JzkAA zv7HBo^Kkk%^1SK!njFjB(i1}=o_|nB``F&z+wOJ@`d2~EbSEfkN5|eYD-HZmtVg$T z>1*r4kc0OdfJo_TyibGi8I(;t?7aIB{s#d}&IjOyv9I?zmC#79(z!kxi|zA$KgHk# zIMWFxq!;{ab(Am2HrhLnuuDFn;U6c=OlkUF>33vfe;{P`E3M_Q-*-Xh(>U4u{)42i z9J1TYgrDg=NF(sZk@x-lTcRmGYvRsCtInlF>QcT3$YUPNeeCjSi$I1r4(D%6eNu2E zFvk05Z%)O($I8;J6uRd0=UfhuMjY_Db>)L$+#~pnteOY3Ym@<@Qp}9IZB{GR=7FuKiUb}5>n0eq-jCWP31^O!R{XAAB?h&hHx^zH;|*h+WWYy*MGB6+ zb~(@0J9nxY5lz(@=PV0}Hrav~Zf_;*GRj;-jBMa`vxvH{SCosITGyIWx~WK`w#0IN z0PC(7-^yBsZ1%OgD={t3 zHMgYe6V-hu6ChCaf2zLBwkD%XB?b^Y=57*hjvoM&3r`Yn#0B)sfY9ht&z6z8_^)|I ztCK=;Y}?30afAPokl1@*})iOt4Eg+hjO{ z!@}Ro0oR=Wv0C?tWPMn1;C2!G+N~DOEeT)D%;<$FUQ8SzD^yOC{X(2aAVXaJvW1{- z57i&>g0G4Pp$luzg;!`OB;=Hp&`8b1leBtw;LFnyO*?tDKL;F4_D-(Tf7+F`L(^vO zojv24FF_7>%L##d<`61Yq(H)0njowRTVD^#?RaixmvIBEeGeqVuc2^-6Kaa6Q$hwE z{e}QoIE4I-Y0rB23nmh(yPp_ew)rjHkRwO?B84OTG`AuV`^(W{t`gHRzJ@}+OhwS1 z(={KR+uU{?4S3jxlUEyj2^=cGSqHIQhLyI@o^K?AAmUm82!mIo_W5<+=eV7eBpg@F zKSZfMfVT6BiHz{_6?kNCiYbm#+c+MjT)3IduN#C07c%Hx5nrzdrn#o2*g5BXeNc%u75d`o%FwX>(5ITfjPae_BlNu1q_ExW?Wvp>^D_aHME z=GB-nWON?F=TU5_3%^X&9Garg=WuWSfGH!8BZScV$_;D23LDO4FDb@$u`YD5mRaPO z{%`r#iY(c^OUs}*x_Q*s}zYU@#>V*VB*SW^xP|dBYLXZ>ip58ba=)YTM3={M7<1jd`D1(4AgMNU~?XS zF3I9$3V{gRs9Kf!Ax1QQ72BcJ&5Y$k)tp3&3; zII=dY`Y^0$sT*AU8@gL?Vl!ZyY)s`n4-LytI{r`^?F~n3|Nr^p;&rILAK%c|xvv=I zve?sr;1X3A?f9+LXGRJGPFgJGD(CU5(_=AdQzE*+@jC674?_(qI-VVtW_lC9!H>=B z1vfe;kQo_cPxri~J$GDi%P6MefvbfhNb2*w0dkU0s)4Q&F|^ee0JMa(e}52k<16&l z$v5bTT)i&6u%7&7*Tc!c78OXrz( z19^6s-+wD7(s{9MHAl7@y{OViDC*I#52#@`S3`RIKERp_@mbc7gxpZCewI7t_>IhU5gpr0<7^ z|4|P2*9a|6CWW@B8sDP$a#~#>?+M~nS#?>>P39>#j2UXJW_-cD)+A>B4o{qYr=?oCF8Q~^xc-M=t@X~yx&S3p8?>ODY@kc8 zY^I6@uff{vw81`Vs4F-5MWgN`8*nH1dZy0FoimadC5G)Af7ec zy6`h8)wn?yp~ln$Q<=zZ?-j!gIM%;`mmgK0`FBcox?^pe$%Go^F)n(De;6Y@yE#@C zg*s__4jTtUsMAu>_`b6gslf6)5>mnZbARhfQfbHK*73+)J3K6a7yZ&)Yd+1L@Pr&R z!7s0=_aS({O-CX#I4upCiM>R;z|GhicLWIHz&sU}Q?9cvm&1me&YS&nje3E1rhvT= zujUVx8HNcKapV7Xn*?-dQfFWA$b8#C;djVb-@uCsI>**QVnVQ9Sx|Tr_Or6^n?>t=3u4GCi-siDEvIOR-ya3WLMyDuC;_L^&4de= zOQ!7@ow`J=g{0A4x}k_2SLqHQS0p%%dBgp@0-)-c9z^IM1tBe&F|Lud3-ur=Dt4L+ zOO{y7>jw5-8g-{VxUx z8ePL9yDS!mgh+xuM^C0*y5&JdX!HdsWRt08liZ6as)bL{9JA$!v;7!u4#vMn=JNRu zp+8;MqfG-BvAk2J6oh|xDbL?V63%E^e=<(DDc^^Ic__Hr&1ihNt%yf{TL2|o48IxY zugFeyERQ=Qy-RCF7Sxy5D_nHRsZgHl%qMAP`JU`70Q`sR$aN_sI%ox8@gp z@%oBz&}2*D!AR4*g=1pnBs$}g|J=!|bCcN}hQJ=l@X$nJfw~7Y^CGOfqjQg{N<|K6 zkHa#szCEA-!f;mMd8bxDR7b~>A(Xn{iKMv;ALwHz>=}IwXrf^c`L6kT&;yV)zM9vQn#`Em`kW3>#qTM= zjBx|~BmC~`tFd;dWNFX}K4|V07tmxsI6P-d-B+B6RV*{RNdOZ3{fcWpo+NT!L6%F% zP5Q-^#=JnaQW1yAOc^IXhRV-!@E(+S=eH^pa|EjV5-W%qIoPa01JDS<0aNih>Xau7 zWvX12e=|TUaaII)KxY^klvaRatwy`fBZ~0Fd@WB~n9GQav=bNDWx&O-i)5tHeB2dH zKn10#1iKU_mj!PPv(!f{if_jr*>fs*g4lklA12k4yLlry6R za8`#l-1eL0A=4QV0+6XN(G8V(=6c}T=nRuv_`F%f6Ys|`iY*O$oTeI@$Uuz<$$?B> zER3C?Cwi7>u#&ep9(PnU99N;`11NQvLdN=;JSvd6e zF2p6dfS(830_5YX)+Od33X^zqm^ZdFRx>|-LTrU?3TJcE9WD6|t>umV_LHqX+Jp}} zd^q5L!UjZDxspLX^u7E5d99%MD1Tl3B}PLOvjNB{0;iQl;~o%K*Y15uRk|Xb3>nW3 zCv4|CbBV7@$8fyUPpoS#l`HXX!L;)!)3XRGI(` zvtOgiCj-{8IqBr|b;7WFo)38U!hEQ%|f}GA2 z(vMN(%BC$EtCjxpcrtF$wmDkG%!U8Lq+wmSP}3HgX;IeQB4*_4&x8EJR9Y#?cjQe# zRCq*lOlx}U&=(t+d64SpSp4b-5oSueEnfN{h3Id~sFgc5fo++kA;0l{;WaDaNXW(M z(-fN)JUURsO)W*DW8;+Hr!W9P0YxNwcqj~rul!8}3^3L%4eNkWq%>p$2{i#t$mB*9 z;@~1H`J@qT_iqUkou^%ZM2>h_tMBTfCjpx&N+f*S1U1xB8iT0_RwpuuNdT$g?=$v= z>fOAhBQv%LkKku;FIU(GnTH8MAO#=aW}^1~WA#}c)Mr9y|6xwrr&J8aQbhhwIIVKt z^s3JO|5YGnrXJ)&5j~+Wbj3nT+Zk{)Pex1F(PGX z$Wa}(O&e$**|KD(cgP06COcXfF>9V;#K|XnI!3hwR|{s+93P?7&Av{S#;Xq#7#sI1 zX`vXbw3sC-N%ZDcbhYXo2M{nnY?m%W+3Flnm_5tBzQv@|RoY8zIyG~v6E~wxO7Qsl zD13|Dbjmfb5Y6nzqrqOH?mxc)O%(cQBbck!W&{cRk^5##<|f=T_Avqy^j?P_d^(LS zSA_c{kma?uL4}_y@_Wu_?GrdjDV7xWmckq$K1Dy{^zeKlb&c@W z5;prO=yDS;`I%(%P?s_a!F1}6CJlZE5jxLg# zI0)sb4IEFZK_lgBW>&WLw|PbaC713kRGZ1JoB?+Vn}aBcTchosn$C6fkDy8Nwq@jO zHNZY-Sy3HLr4VQ$TJHPLGAy;|Ag?)!&&ISaOg^g4B$7;YJ`R{ZOHd9;^xj_`78uh7 zVn9PHL+rt4n`(5`{s-)PVf0{5!pm%ubW7==+HWi-Mzmr<9hAqQ`p1a1+nuD=wG~Q{>~N z4P#BXQI$R^J@=uz*39yi>=u`clDC|n=FeqGgJf&e!_%h)TiTo)QbI+Qm@Du|@0r#N zMwsWHA#pFJ^P0>oxBH&S(0xs}Ru-_CsyQX9^HNW9B#RVYv{Ip2h8wsKb>8!Y*clz! zi#l*XBMWkGuq7znV-t3%I?`f5Tei7V^t}S&(f=GVbwt_T?91D&)V$ctBWP&VQ=Xfc z&<*I~e2@oW>HI%^$HZqhvI%YcY~h5u@cmnq_=h@m(eBdQmq45rA9geF;=$YnIC+K= zVmvjQAX?)?{o@D_!y3ksWcW)!^tD61Q3t~OoT$9-wjdz4W6?JnM&b?Ut12-6SjFtk z$zIoq@*DPfw{nzmitm6qlh z_`Qz+a6Wsb%pLN6P$WVC? zd}(f=Xd6LAa^SxPLLm?wusx-H0~7&MPS2^NE%t6}59w8qKQCRZU8qTY`I0s)4%KJB zmq>!gmuL@Pk?SAu<-%c>2z>KIz;{nVwKW%CJRCE3o}-r zrpK&S#~F$cNB~uJJ1CzZwz%+491-y`wS9e}otF^bnZyH+0RGm^KiS1oQv9`=cLM59 zV-W(1dCcTAB7FfM&_$TqnmL~(Y7LVGL#&Y-q%D(3ZVYcU(EPS>DMD1Y(DEHu0%%-6 z$Bh3xnDSrq;sa)G=<9FS+Zkf`6n8C-*5bK`jizCe|65 zDAqTNZsUz!#j`OTuLeXI3_YH*e(U$QGKGd?Dv}88%hY(AwFygmRVJ5T#9P{9ZGS9$ zDhtYhT7Gl06l#m+eNN2ej-haKPxr zXe)AGoYxf67NGv+^Ll*BOGJJ`mnK_Eptf~a@-m9#uO1Ep(!7|EVHj+!;*d}13Bwt- zvj2N_y$Q~GSJ|>m4eiyn*qgK>4*QEl_hb_!I3VKaUa#@m9nMbGI@aOqrX<+L&o(UV6FlG#OA;gX1xwpm-cWS4IHCkFT5NiEaQkk8nFI=0tD>5{vUV zyQzO{|?l&2`9dfCkKXhNkJ=c$PMfNtPJRVeOdidAZGR){%Hf#`&~{ zY5H$%j=%P(>=T@ssfBptSrQ%+w`0vdPd-~Cu8Zv>kD^|DmO{tEuoG_zP$Zm$&wsIS zV%$0hU_8{{XYcP6vu6lrfNm~zUq5xDVeDo^z@bD_yszh=h5`woKP0oQzbh9C;p56^ zW~BU()SRGiwuydQQlnM1WB)n%pt)(Qw8p3t5|lvU66xFwx#A2w`SI;jY67ZU{#AjU zYtiY1dW1EX6eb8X<~~7=j!Rd`xDZyP2*<*y@$}>0e4=U|MTfoP=i`H+C)u{&cCtND zx4q`}b=5Lf1bJ~+s=?Vwm>R0@X*A#%&Bcr#1QJgLO)cWA*T1p}M@s@#lUj`XBvZCd zyp7FsJclE>c+_tVQI@VYc3JGBuG_#O>uypd)wO3GccI%TlA~H0a z>O%1~xSqAybnCV)bRIaRhyoHONQblj;CD1t}tib+IJvsDQKmY*^pdHw|njl3qk8P1Oo1lo*?m5qdsvz?vU!3tU1##wB_pw0S!y`<}=@6#w05)0$NGX=Vy+eWr|q?yac=9oNKDpRH6A0O@ty-PNx0M-(=QG^IcHS&vLFrVzylY*AkHq1SrmGC88PV%4aZjE#m&vI4>>o0) zTe%vv`GZx6R?DbQT><~*H@jnh<5_dGHpW9^X2KEbtGQ$8uzr1Fdb*W&narMF&<5-s z2PMPV6uj8p?%&mr`E~@A=ewR55jfAougFHM;Y6;*NHobjHTF4jgMR>`SXM+f|29X^ zx8Zmec7KTKP5+nW2d;Whm-)c}Y3uy()s1-Ua5q}?ATx{mn;>5w1~l^o0!K7TTCop^bnev?+qUY|Z%(U0zJdwR6kgWl`) z3-aq&Ar#2T{ejW?>Gg>)q!|$l2Z}|K_rD(7NB5CcpEybVWP%d5^Oj+gvBA*x7ETW_ zlh|%`vrU9Rn(WZndDi2hNu_xx@QF7MFK_z8vy;*53XQ?CJ4K=AL zBdwFKFdwS$^-Z|HI@pFr4=z}^E|yr{@W#&6!KZRkLo-dkjfiO9UhmyeXorPuj48Y35Qj!tKTKCA{c; zS2PqG)5Node@JN>6RKlrczxU~RbSRi2VoSt%=}Lkm;fb z4vZGV==Fsm?2!=bJXo8v%)K^F*tALPvIGk>Qn2U*M*Yw~YOJWUiALjqdN8$nri8Ei z&Wr=v>X}#z6?3qK{`k39=W0(-G5yPHXw@_<@ILNK-MwKWny^MFBrzHUGHU4Or zAhs()RF6Ud<24UO*bts>c}|nWSXCMbFk6pC!VRgMO!R|n6jy{5GXG?;wH9cxk*64dtVZ>`EHYsFA>YbdOxLpj*fWQcFMsdGr%qIHg;wAtYDX9aLmGbE4PBQ9-IZ$fw@0_dE)jW`(2eZ7T{*^`&MnNQ4y6obFR#(Lhj%|m zB?Edzs1(7hv2zExMY6)lBY^;Xf)$iTVgf5)oEHYu;LeH7>+=;ov1azritrE?PA}85 zR-QA_`U5DzM2zde90`-U!V`BA!`bGqXYC5TKccl%k}=O;f4p9j@aPlN zY-FUa9AA@HXAc-z?9M@cGs0q>%zDq)L27` z^7t3mXgx8jnriPd-O}7F5n|AFdKd{O8c+2xsx5P((y7cS*ZNZWx4whHx$m{i#_ee? zkv|spZDT0~2Q>$Y4R76=jg@>i5S_>4HvNVDo-dm0p&8D(71lh2Bi#Z`$BeJ_djkdH zoCy5vF}}a!;YjVB_Rg97)z{CYZvSJ6^?OiF`=z?Q43WH4C;5ZZ+YW-9y;G9U;?$XE zLwNIG>b^$u$6&Dv&08er46<4*sW~#S$4~x|Wzpvy@G6$UWuDU}kaMP40%Yhmt^OZ@ z!_izq82ELno*<;k`j+%I8ZNRqVGIi}lL}uDjiL7KGb@G_YxSEO|F%bt+ZsgzB*bfb zpqkUKEASRaIwcf_-_<6F2s(?~2=ri}Iia5sRrGXi-~aFtV<9AbgS0eBuRh34XVO0t zK5jIwQo#erGD|aVRjJGWlJjPw6yvBJ2(pjo4qIaKi@pt3w`2C(q0#82R&cqe8;VZw z=Y{`hj4j~K!{ra#iGO)ZkMaK*p>04Gq%(z4daXDFX~Kj-I?72^t8S^BpygBo=BBr2Z4L!{SBfLj7Wg9YA&`Fn-cY}y&A#x0DHb_CGX(#Jvl)f z#e{H3Lkt0oC=Ueh`biIFoshH$f+-SQl(!k@W42qb{vrxf-iZhf@iR(ZWquNvk;GPw zZ+{4a+tv$knidhT8rE1ksfR%#1 z>K|FpO-vA=#jZwk{ZuY|+cJ7bCu-j{lpH48{C_8h1V9CWqLRX9C2+3ed`FD4lKfn( zX7&s4_bta;p54|CtC(ApX(o#3a1KROjVUi+Kku?T)Lk~`G$J&uy=`YNSjls=ZI?`G)ApR(^J>h#&4hMsyMY?|a{-D=uTYfHhN1K(5M zD|?WqN;h-w8ktVf%<HcPueW)!hUjlFp}mwlb>%hPy_K4hgpCagaVoC6PoQjKMT41?7sr z@>5T{5u=Qxgt#zTRPeLb;9x}vjp*ZKwzPI3V*=Yt2P$w9AmQc<%Y0ZK>1qJSe5BV! zw?=4`v^><=_;Sj$at#S*_CvBQPNpa_-*3vGu2hsFZe44eS-xi~Kdkk7%F2`(~YYteMzP^0gUG9#HEj*f1Bm$G3GvlN? z@SU4GbRtY7^LVUqw^c%9o#KVkQ0JHO&x)d&u)z0VUv|hW}erp6+lVNlz*Xt>8swfq6$GqE-Jbg z1@(SL>MMQxG3RD{D>K}Q@3sz?4Z?bgEj5@P-RhITOw#9UX)U@jprU1Q)&WI|Deje$ z0+-(Ii6dZ4r)mrbBfJU@k3np)rzBq!aPae6 zmXYFlolDQ^691PrQ=Ipt@~S#_9Hy^-LQ7H?DW$I$x9UvTtzy;d05+9Y`)eiC!CF2=ZoY1g<%&OWJl!9dE&4k z4y=@d@_LcE^V#kKaFh48VdQWL-higof`Y=p2p>Mt3m*+kC@WOB9Y})5|9xNY9xl7p zvd-c@!H=9Wr?9+i*|V5QbOFaY6FdyRvNxyT+RYg;q|QFl;`P=KB^Uu^?SkG-nf(d; z){E2o4`eO)Jae4pcjNWs9wQf9#)Cr3>&eySZye*Aqf|LmYqfEdD6Cl^?c)4Ymtepw z@O#AvFJY%MpPkf(J}0aza`JCpnntfx7VFGd*#^q|zhk`O>6#wV9%_S=2rmg+n%dzR z>Ck?lcQ!e02q=$xEO0S5>>+9mIH0K(jo68p-g%K)d9Ezxtcvhpp{Nr)&M+aBlYA1I z&T1noJ@ij1YMZTSCu3#*(IUR7iJ6EEYc=jwCERw!pqd zr%3L_@WhLuZ2fQQ=R?&??ByHbOTT~`BIKe+C-+*@y7OZ@80~#r74$J9%v=ZPs7<^g zq8#`ssMDFH;HC zyrQEWf@Ss6?DSR=^CuIy)15g>pUkdu?c1JP$ht0Zm(KtssuQ%L{#F)=7s}`AsIihu z&-M>^{P)*k!=1^3Qgr>>jy082EyX99!DC|)L(H;bFyV-GgJZAasRMu1)226iuU62q#7Yy+zFD!p>{o9h)E<>Qb`Ud~i zcQn81*%F$tZ$5W`;*u@yCe3*${o17>$%CR67T3H>Y-+UA=~+9FdI+d*p5uMgqiXXX z6w_RocEJMhGjL@rx7Y>Ezs6A&Do!h~Ip#N-jVHMP^Ae-XLVm z*5qzj@`sZdchFSb6!`M%mZ_HXsC_GOwj3m?B8Q5&thchp_}{r2^FdN89Ba8Q`(e>C&Bl9^w1J?$17XfKlE zccZ2wPndTY2dgx{QSh;9FpI@NTu>)ybXG9X`b1?)Abxd$Xjtu?sxs zV=UYw<0QLdWsr)FoF{~YHY;z`tB~csMQQ{K9U-uOVuZi^P ziOVMK1H(5p6V1rKz!!19Lul`Ka+jtrWU}$eOL~SvHabOuHTtQFH}$asTnf(3%2b8i zRKoVKS`FF$gu2WYLD$P{YV_+MytVS|(SI-IIJ`kLP}Jy1VZp|~fkrJGwJEI`|Lhpn z1*Irc)Yssyg3zmGKK-Hu1lyGF8*_nD`-e@}O09B<((+;nkxk`F(Wnje>6`3ta>LCY zf`{sZF%IKgX=@~y$j?Fb(Ow53A@dfIR^X$;oX}Y$@Ah6ad+y_%j6nQ~oFF|?E;UIx zUh8hr&wjOLsEySc;%ov%Pbd$Tn9r^ocC|G{jfA0v>Nmk2I0hw_Sn(Mq32qcs(`o6@y1%P&jhiq0*cw5 z1S$&}i{UpC4dJ6A9Sg*UydR8$=J4gqpqi&f-?#-RRRS6_0!>mHecL(V+txcGl5Re< ze1V4hr^tZX7Fs;wXyyqQX+mNB>VeY@q)+md*a~0U7WoOzI<*TA_+Df5$uB^nxX>sQ z@awc;#07453gjXUn~}D#AwVop4-`?niC5QH$K_8#J9O_*0iU0{iUlkrCKm7JZ*+WB z^qD6B80)tGcBTbB?2-pnoVa+f{Bzf4V6qRMD5eU1YYI6j&M$xQ{v%)M$N}V}T_&Y$ z!n(&D@~9b01KfD=BgmMNY9Q8t?gwHW6`sABrW2;DNpS`V2SA{#Q;|GjLO4h{c8)1_ ze>xLIxIpZl)XcV-CaCSxCLW;N9JtcwR32n7g?AJ$sOlCY`#6W2>2Q<@REj{|loxRF zo;3?9wm=*Ahfo;@WRj$puHE)=x+97=@uWQmK(#wN6{gy1sB8o$!{LmW6$6SZhvCJ< zOZZIB>x{Pen9uj%C-C5hLD@-gPZEmjhoCQZijCiQLaQN&JKVqXUFF{qG-=yy3cIY^ zV{=bS!tS@AmZ^8N>vioEDXi{y;<5Ul$%Zl)=fxHYC{s44kMddiaboYqKCGQO1ubag z7tyr&=P0K^0?VyRo6mbkS<B$5Fz)2%ga8ojO~E@nEm5mMqOfAd6>&ttoZMnYia1 zjbe==T_XuX+=+CsNYJa`&^)GYJemp(F`Z4o0tcy{A)+4Nlf4%>D<%BYy88|oQQn1*NBOa+6#wl}URXq{DIHY+X0B$~<4 z?_*a62K<5+jx$@tso}yKf!jafN&cKpN?JXmSuLb)6`U#QYA@``KrD&dUI~6ITI$dH-ensby$Dq#V^>+(s>00r=QXh=TJ2 z%G`-asj|4vq-tPvKLsN}9GHBr9Hz%V+UU1;V7yU$I9?36rzG7n*yv=G-rSi+Gt(Li z;5ZQ?xmVQsiL41HQ`7$r5->(zsVMYolcv6>wGR-mqaymF1`6+44hY3a>Bj#+$VQRU zacHM@V@7p3;Hq$3#1|K2y^JShXk*ER`aTreAqH%D0XH|u$jy%T9m8~d5vrYfT3YLd zvk;f;?hqUCX8%xoVgwN~_J@b|Q)pkq*O$d7e=kxR3tuQq7i_$6ORcx7ol*^8<(B0- zMeiYx2Gri&hP)|?D|zMhTIg8g5h?-w0sxRl57qkC~hzK_FZP&M3 zRvZdr8%RbX8^0_I`+tUP2Q#{5+c4L?#NC@RI^HMj_PPS@i&mW4stV5FPh&7cw}3It zkPE2_S{3qn_d!GA!j#E}O47F5{d$E11mCu%ym>3ctK{!0Fa&@4^69Y=v?1AHCoxhq zxa-)K3r@Ygg)>&ie$iQ^5@nJ7pfs;VYe_)W|Pq08v~Gp27segL?9hmci5wEeHIKB5zuDv zM&^?d3KF^>wqgbJ`^2{d(5D|Nrll3vwp?EnpWAxliUyfRHZ`8D+o7UBoB2KZ0=*y% zVb>UJu7S>UHlB=^VBzW2`J)t85BgwBOl&rn5105>wQFv^6p&GsqQIl?W8b(-m5t zvV|S(=xq}1`kum(6*yP;t{*Dt`%k3vWAUVI!||?yS9hl4dxRq}oyE@#rYl{mJN4^& zCyfFg++}P`N(6wja&JTE%lVVFzz-gr(bUzW=g}B4NtjEPXvK^Dim%4{&G}JCNm0y< z1OF{;HE%Fgj1de&P`*wwF=)L3n~FWY%C!gj*m)5RBOju?PrgaXuuQd;JZ1YcF&W{f z%0VaErC%HCezFn?HWch%5palD2a??J0*^UjWT3gfCrCb7=aZeSo0k~$zMzKJ=(6Rk zgemIm=01-3h;CiDgYgL+(Q0yxiD*v{{7a}cdmzlUk_{7rloet8Ul=~7_wvsP@C{de z{{1;SJ5s=q&z006?QS%Np8Zf!?@`@h_q6Shm2d1vy>uj&tpD3t3}1l)fotQwF4aAg znDHy=%_&;5%-i+pqF#wx%rpEgfCCl6aoH_pkk^!cH0pgTKj*Oaj*zJ~&9Y$+5=7(T z?$t0o?fT4QE9Bmi#|M#kk=aQamHNP)!OX*L!tI;m*@orX1?vrkKTH758K1_7AH`QJ z9&5^x?s+y?Cs{q$Dpwz}rQ8$%7ZsS)nkV82$IY4vrZ*obt3gd}hp1!eq&i#-UnF9V zW{j}XS1aEhS{>%4vA`hOmdm9#6H=tmE;DKlCB)0YFDsZgKbi?j@FuwE^u>;p2izHG z$r29$%u-)8K0>=C{l66%jkvgudA!NpeQ;FhtNgS4sj%fq^XuaK%}xqyT&a|3c2KJ= znft|UyeFWNsKHDRI#3Sfs|=P~%spxGpT@=pW_2YzJ)>ounogp)uLQ>WiJsP-H@+ha zWZcf$dsZ9KHn2^!1zQ!9c-m_6)f+xOf!)`jp>+*D4BQV>zW|IE3sgj?CiZ(U-%k-G{0?bAvYJKHZaf9v`14;yww;YWps8R- z2SAWS6!ErrXEt7>+6n%uYev}di)y;P#MU28E;0)U_Ty~8?t&V4y;>z5=SZ$8mNOf*?*3)r6(c$O_h7bG(1dM8ey9 zbZ6Uo18UbxR$|_kr}89#i91=&bTz(xf$&OxVaLkktM5A^g~#@en8Y7i$KLIFR$F!z zvX5l9-@-KK%74B5rKy@UjtM7Jaf9GHdRSK|xfWhaM1v+)4e(=(62*u>x+ljBXQ0JA zl$MS+;9&lQRmcvQ&&|eP72#R16GGm53UsUG^OS(sc26R|HWZ7HxVIOni(o@fq<`dd z1aNHZCVhzffg9Ill~pNOl?c6d3w}!P@rX^7u zYko)xLGmH%*nfC0pc5^)JCCulF!>OH9RHT(7STCL0=_j7sU|dre-WYDl)Wu`+p~<4 zp(2!O15vrfa){a5#c8E?O0y3wp?bx1{@D&J{&+c}j1MEK>dVdKT6bdh<@dNKPR0R~ zM?Os_3RA9{-M5u;YN5%L1*6l5MC7E0dn|+Adcn7~ ziFbfo&$E^_nn#WBUujICj~*G6oVqD``QrG-nkGX5Nd?T~a3eX@1a5;j!mD{IC1Uor?Ci zaiBGZK53ijT@il84Tx$)s)+?MeEpHeK-Lsa-`!*y6`43r1VeWG1^RS#rbgqBW2#Zx%yYbwJ%F25FMORUU%zc(+>mY~ep$_mj=CmRD4i(9G@= zVa34Bn8iB4C2mK+P{Y<2CXI|p24)CYx{PeGL6%6XxR9y~xWsGC`T!PS^H*@5fmv{$ zM=Lr#Z4tTDdcxq(o)Ww(P=_>BqUDlk-GUXVjp^m!3o62<0|e#@+kY+9o9vusSx>Lw z=j=z@B%8tY>Mo@T#6jFM6Z^63%p&nw*Vrd|rV(%OV4*Quv$u0mI^QA4wgXg#b5_a- zoX<3v!^r4qi`ntlibZaCF$1s&pEr9ekGaK458Kir6zn8#TjAdgJLwVU9Btq$k^1fd zRy3uaecf9?F8WSf@5tRUcy})}bg<9{$Tjy<7)E`)P%RAC_#N)-k|`lesy3dOIIVI&6qvz z!8@7xB#GPTgC@ewfIcr)pqfy7>NF1s8MPI72j{1nr-eAdtxO>iWut#yl?~4}n}eR5 zCa_}0N~dH-=3cs7?=z~!hNM8RJ|Zs|p2m#B zL+&=D8*K#o*4znfh-R}pe3?UfI^57N7bxVW$sA{eWy-x9%FvCpacokSg?<_FMWMaI z84ltaZcVRpZM+9wA0`sh?h(k1K=e)?89!u?lT!`o;UBLWuqLPNNT2`Uv6ZPxG#>S< zmR?WA*%K8zp9cC$T<;v$C(&Lb1N{@ZL0ffybJiabe!ntg1dHaH z(|+%PYWqaXd!L2<;DYM1bDh*z^o;VU2$b{bUUxV{+Rs*u&H>k77l1i=>CLng369a( zB7y6!25I5H%7|d3&;(Sjog_C_pYH56!8CwX+D{wo$aW|>`aR4lduS^IH^%4ObD^JZ zMPuJ{5#OWcT6+EI2OL>>37t!osE`hCRrmN{METH}mpw#GaPUaqs1pIIttOlY1tKP* z6~3pvC|^r9kH2vVIxiD)ZbU{CwWbrs-}0gT>}?*{xFk({$y`tBT_4zAva@uEJG+B| zU#yAjqB_`1EXG~7)<_3a$Eh`$Q=_7Z_%*fuj;wjY$qazRf>ZIVrd@--JLw6T=~|_6 z)0y-==g29x9Y`+H1UFBFZESI*j_|cd`kTmSSLe~a=$B-<_<=qip7UYZ-1$$CT6tU* z%;6YS6YFpZ!5fP5XE%0A{Lq0$Ibf>iF>2*aUy=KtjE{Tsd-ens*;h<243wkWB zAMRf~>JjWVUwI>3aBoDdP;ZZ3}` z9y2A`UbPIj--dV4ctP``n{oEh?6V`**-_lReEuM~L>$}3;OL?@UHB}uQd~@sw6|n& z)#w;;4J=sj5mvS864LAR7ry~~Mq8SHO%Rdn%aOh~^M_<=F*Nx`H$>>Lc*iCk&wU*O zx%{9sCpyK2ttp>)TGI>z^MxfMv(oSIETviM^7|eoNxm_ZV$fy-G5DpDi&5Z}9)Yr^ zi^a>0(%0YF;ZhEI*qw|BFvP%sV85w+6+h88srN^}fSvd{_`x-C$v)+t1;nk!BazmL z)LWe6u_O!I<(XnZ*+00<5+42lEv~|8;Q+h|rA;y#C+qxKv<;@vnvopsxk(EGG1Qm! z(`UjGBDgpd&?@S$$KFJa8+c#<5V2dO;ztHx0k8&f|E4DdbXz!p!)?-*EWyVI;#h|e z&kXQR8rGCDo#-@=8*zD**Omq!Sw0jLCcSL!YZ1awM=mJPx0mF7Xi`GEF%~GA_so6& zM%anBLZ}HCL)SQ!+>LeVgrAmg+A|@IC25dWs3Yk4!bf(=2;D&-q<6}DXH2N_&nnZD zEM?P7Iud{u| zQoDgk`FQa(Q?u4%!JtK`MC!2zEMnopMd18!?O^k+?Isa!)$94maD~b2R_J2w?}3q~ zg5j{{TqBMn{7e&ppY1yuV23vt(#tE}NQl_nUh7Z%VR2-9kQ&-sv_AMisO1@5Tj#mS23$c( zQiHJ=Xz|h#-c45l&Y4f@`U3?{ANYo+)y0|c7W-s(x3kblCs8UwkDFZ8Nr%P7a>!m~ zShxz#GNm8u;Z*J-eV<;O+;~!3iK2^Jz$TQVy|E7PWbN*v?=k6K`L1+5{eTdx<~2Vz zCUs!oF~YUL=*x0WnzYTi#0XHd*QE2PpJHMW3`gEMj|qhtojgbYL7~ED`Wbap4`{Ja zwY?vYiv32v;y?me0x!z#wwz2sJeIe?r9!kcSfHzSAd9M70Lb&0{%H)iDhvT6FaB5E0jmDS z@L;+Qe@<9KXkJK)lzW$~XpDS|`}pb~CfBv*#AGF3YFRWJ=9e66yqux$q5E87_BxVI z=R5R>Q=pLdYqp6tN`%x=Sphf|?2xe{;rs$i2tGW1O7qt_$<<%!i-}oHhj8^P(-;Po z^I+oi66wx$Cw618m)QP~^J?lPX8?K=;P}qQbsf2<9#tUrX*I`*$SGpW^Vul@RKcrj z@w`!ARFnHy0LK(E>9yxvd}oSQd-z;h-*8y0XP@t8LRgn@Hoef1VAfe%2F;Oxlf&Hd`#Qa?ifMk_mhSo44u4o7YzIng+_cYTX)!8?N!eXJ0VOl_Eu3lq^ zL372>2$%#p0}aK!ji3vd%xaLXb;AW6GXPkgaf(Q@xnu{-jNugHxP3UOx5)H|@_Bgh z3rX;45<<^{=I9ITmEpdQ@g6>8KG>w(WRlBm{dSnxT-OeOL8HEto@>RU_VYPm<5GSK z6rK+hS%=w)hl0S2bAPO)({NbBqm6d6lYS$eXk*FqCo|ZbJ|sqw$`?FgM~kbl$U?B9 zu>GraJycak4?u-G#))Vu!{&Ol7Rjy-mB43!Bl{2b@jYZ}NO6Ggq))nqv*-YgLAXHT z5x)5Nc2fJAi1u`!Qb1Y^gU7c#7t<$&;nhz|q3r3jO-oC}bHYSEm2Fs2&ZY2!K-~Kr zL06=bAgs)VA?31^Jom>A*akKzwRm&X5HWvHx zP+2~&nIoC`s0_{)-7k^W;>Aa9!wu_D{!NI(zcS=MUdWx=$ProUfl#uZb4ria0kzep zjbw^PW#hSPVsNJvyZX7kBc z057{D14Sbgw+2GU84MH97+ZkAtDFkYM=f+{Ll8jHCZy2zX%eP?hLTAklj=DDAw-;H z`RTbijNFz8TPc|y4b(kd7W%T1ckq2iRJ5xNxH!F zygjy-kFn5;^JNPpB!8{Y*f-u7G9%M1VMVm_r`+Ks>W>ZvWu-dHZ^N$f^-u~B>8O7T zMG27Dltildw&XN}+=@DcoTk%Q&{Ss0t6cV~^aE-KEIpPkwFr`ckDsq7)CPaPFl@Ki z8$qSK!-@+#pj^)S*s0YXQSh-NKH42ECj>VlA}~iX13MuAy0Cmox_a5@9Ht9Pr!Bdq zS@rM3T54o>yckzpTRq}@EX<5Vk zvws}g_%ymtYV8Jh4x3wDtK}g5)pnr zb>b==CaZ!?&7QxAGe7|fA(w*oEe1$-9vpcAll@;_j+@tzCtT)teB8Ms{~)`o0ky`E z$}2%k!fB z;Qg_&qzR9*S=Jy{Nb5Gj`P6_x83Ix1s}n5L3i;6J8mbcV5*e zju;qux+HdTa9xcz&~=WT_Tv7X|4&GYl>p~iT)^t7y}R3pxN;-Z0`8tdd379KwbRpR z$*AOMYg9>D%QoMC#+b*1W{6+y+Tde(TX;z+cLe4m&$e0jL?4a`(wg$_Xc+kXKd`!fNPH6v_QNwZ4d?n58KHje`W;U zTzxH%fq5Cwn!ED1nd=@lpf%si3G&YJQrny(rVji@f$Z*o(#fVgzv_3A-x}LW3So;- z7HdAJ6S6!@OCM4=`;Q*Ax$E1uVlzy^G_l&oB{tu$w(5&PY75U(nvf7ReM^BYP)zuWPO9M=`!9X| z{2Py>v2}=uKkOZkVam^YDz$hZ1B)5mue&1f`ASf0<5tEHB!`p+s&iW4_4C`6rG%DIlT9j;5e5H~h> z91r+`&koMCupEA4hkA36car6Vi|xOkV)RnwDGsV4r-0qNa#Q^d7@zh5!q4 z%3MG88jOH|M=SQz_6UKM=Ay(c%3C+yCZIbR4AS%~p(Tgs<074;{1^Yjt@<68?h<+^ z0f^EXdvK4m-RWX;f02T{6YNm%2KlU0u(!_E>Ymrcs?uACG%-yx-?B6kiDfJuhtc2` z(6jrzl*SScM5CKjfE>?98H?k}*_a2x9^^t+r^zO=xpf0lZlZFqVjpwer;@8M{rk9% z>Ly)Z2@sIPknXoaz(SXFiu+jeaF0Vr6SH;u#%QFCJXc>t_a8$Mqt)0x_A!L2Jz>m@ z^9YDZV}+Agrdw>yj!*^r-fgQp>f&)owY*)v8;vn5W#9NvkuzP_bLbj+PFoMtM_uVo z*~{=ynqq%^=@7sIyO)%YABBTHN4(@G{`g@Da4uvP6wvTMD6lg~L$*2pu`zh20n8SX z_=OX;$~tSf4g|Cg#TRA7z}>5Z%5Js`ynv^NW6q2C6Eh_7{!GuU*J^aeqjH8R9AT(9 z=oI{7v7#$J+|k!GB4DTcq53I1mIE^+*{s1oACBsKklJjkeAh)eur1%GOu6yk6R*s@ z%bAq%wEB8*XcwbZPIUjPqln&IhGQ=pWvZse}XC!QJ1L4@hL_ zpTEuP;JEKxwDVmzrk`Qrf$O&|n9Os+IuYohHKq<9uuQ&kf84)LK+%6`C-twkSL^#E zZ7bfpiUr(b%gpy&I<2t25iPB(+3$Opn`8`~nGziB#{iZTEBU6}65z$qsDCP_mckD@ z)&CBhEnXkr?;#6+7!FCB12M|>H}Jblq~R1oD_u9*zV4%|7(~>=u2Dm?`rgEjocMZ$ zA@@`w6i?Pd>X1`m2wiwzn-4BWK6v((+F{Mw5Z<=k-bD|`;#9J*B-*>|_wh?`LAa}o z&F?|{P&Juh{EnN0#_5)wlgx8lC99N6QatuM^TlkE6OViO?_76wlQD!ms#RTRRP1OH zKGE;-Z1;uMtr5^kiIUafZ`3JY;SueChg`$M3OlhW*08!si@{pP*hikb!|h@=9uY+Z zV%qxynw=JY5~Lm(fk~kPiAotW?VUaMIrFN+(LfG(txoh2vGww8{Ht0T4uotjtZxxn zv2>-*6%51M9f@orNXcH}Y34MB8nb7`OX-`php9by@n>#7%zHEP-cO&X<==g_lvU-s z2(l}fgfmbvo-Nu){ltPz+D?x?5#A`otAg1vb9~A5{<9_sT8_mp>8@d5OW7B$JY5*4EpJk7ukvb71fO$KL1s8V1ya-uO;hWGn|A2EwkA6R9%{nc`uL1`_X|F6xkP5z)S1z2-R4W1$dg z$=3B7DyD~?{wwgYS0R!5X57VgsG|199tt_Uk}QX{#e3Ot#);4PWPUYOGi(v7;g@!2 zEEVrTL+vt}4s`4oX`b>R_W_x>eOd*zZ>wFkQYKf7GjYO@RlBuuUE zO~J<+>7Yn|$O+87n9&Wx(*=+aN$o-%ZYfY?FK+)HAANpSgv4*ZW_6A3EzJdkESM8$ zxz<7T{%9|m2A%1Ea$+Q)Th@r1)VHAA<6G;kp$hhK2pUEUXmoKV3=TZ^4I;n@yOzw; zF|h4++Df27k2PXn8hHqRTIth;$<@jl6ThQ!%G1TGkJ@0eyCSD~Aq z=r66hZcPB!hlMn;c?eWepbdOdf<%p<@MzvD$T7$B5^(IuWy}s;DBSn3k{^Pvp-(pa z;z@bhVMB7j&-`(En+?O4D(5BV0BM-j?!tKc0P+}#8*S>q`vaK*B!WTtNXRWkJl7}J zO$_13S58zwu>NlOb~31$p9|c|Q&Ns(>-W^9x|XSIUQ1e^v(B^YoMLy~sF94*B^4X) zbJ@|YLXE$PfJo&!Q16Zsz==E4HLGE?NYHWSmxZ3fuQ4U%V4Vd#qT}$aX`5Z9Cda_X z@UN3?CUK%(nEi%&+~q37xGP}V1p8pKB67Z!D&L_4%{$g>uG+WjsVAtwOD^mn%k$Fm zO=s&o>UHn+i*tRyll}{hTh>SesD4g{mKGMG6=Qb3apeX zDai9n)FH()Ik=$q$eZ$+AlSTrsUw*#ji|H+<7sc*x?JBQOvgG=5|=R?X5cP!(CiRM z7@^u8Nvy6BJp3EkWL}Kj-`^`PSwqTi3cx|K0GUOw$XtE4qpiNmXFmxGTVI*Pi^Umie-uTrn6>bq)X8;vB*DcZq#OwN?D3?-2npu{K`Mw) zk(JS~l{Gec=^L6c_5Fa1obvw9`?=`AM%%-$Xb&J?`6lH{LvApMl)q7Sd3vA+Fc|!o z0x}sX^>VGL)uo};K9&tK@PDEUveFwzl&sq_e3<|mch$Ox67keV%pp7;GkaoOutMQg z*Z=}Ibl#N)@60YoSQy*JfnhyhEWj7|j?M|gcq3^;RGvFh;*S4es&1QH1>-0h-)CxS zT{6h0DsYGTV$y509x(+8nig1%nkJ-mVmQWK?cf5Cb4=gG=z|k5pNUSQs!*LwlxzZN zS%EG&@#&F8otYr{5Fmw!z|9jlj;FCQypmgZYrAfd;}o!a<#k|uO3}jUe_)&!yzcS5 z^Lwe^%G8(;UPZ~e2s-Ibgxw5nBq_rfsf?coy=C0&(BR3$#0#Zm>E3S0B(L8O3~4$t z=6orMEb*wJQ$1JxMw3RobAL!z8L2WiW?GYD6^6ElL$zvI>YkJRL_^W`H#9yhb@V{) z#AhSj@#5`?q92M2PQ~FaGH#bsN0lA1#AeYEr1q;^jgvR|gtd9y-qzf9BqyD<2dxyt z{U?$xm;%y^IHyx)BT!pY+SGfVRdDbKE6z}5F!+9GZZs`IBTKo(*r{m_jfEA2f|T1= zKr#`&TI9!iHRLBbp-fAuRXsp3wut0$UF!`%N3BH)%w-NcLy)5MdPsM8WL-SzXq!e> zP%UBrBye2mtIdfy0!)90#?`(y&@ez3Y_jh=jAY0c!HdD1@ThQT=Bn^NbSdbSZjb0V zKMrwPPoY7U`%=-r-?b<_HIho+G)>czid`p{SnNF(iFIABzJPFWfGH?g+^vcOsO29M zULRF@*tlicGcvltV2infCRFa)95JBIUF0)r2^UW=7LyESLQN5!5xNhF!dgNu@NzZV zGXq)}Cm(hJo2bXVsbrrb(@uRR(z74MPZ!cgvQL=gu;Y2G5;tx=9KU5CFG-b^=p)wY z#n}_OrF>k9COOWJQYDM(^*N38OyEG2A22&BIVmR@b>=! zZyBe{#@z1ju}ua$QknvdH6QFqdZATzA-04v=e#&)J^1x{waM46I z+$Qa@?TQgrSH`WA?*zD=mcJYwexdBLcqL-zekVtFo0{1V);8W}|4HgH-qKWD1<6yy zDrB|4m~*T5v*NI}f>Rl|a|i>J;-?l%%YGmpIQ&B6s^nuc)lN#L_i zy0$n$srm47$3)-@WYtTy>t=zY*MlR0l`wj70+x*nE{u6zJ_P>Vck8WbHU4p)a*j>t z_8#3`PN?~vqMC?f#R_T)YV2E2LaC(izRq~^RV?4qM=ZpH^XC-1JYGYiYJq#Sg_mRf zV<}$gEVVb&Czfy~>lU&_)%hFzsoLT1Jt-GHQR|LiZ!!jMIOk77l%%Kr`(1AnGcwub zQs$s{Yk4c7g$wP{;iG#gf^HM)CN_ASS=xbnDXG#TTl;tE0e#t#&hQ|;Ky*$70mI=ov>)JAaWWrps zJQpsDuV1>4|GEz1szzBQ3WMq`gb$s9dF}G4;;P0R<_uNHH2}D{hQ8e`H8dii0IUjj znJ_9i<=LNik^n*>`}dFAOv8_jcVc;4Q!Xf?HpLJ{w#b09^73250ZFrPuOuM_3LVf9O7i~ zeOH|T%+A_(IxvMD0UKZl=lm6UHBDz=pPsugK=ON`U0+BO>_e#`om8HjLV;=?ag-z< zuUc7*Y6U^K|F8wm9gPAeGy}C!_qCq_dZYU19ApJ2Q$rNxVgrI|Z&-V)LfApZ3C^2L zmc-;!xrt)Kfz^Y-8!Ypi89ffoB2F?u81i5K@-igQA- zROL;@65tMGVo_)>xo{0d>OE3 zSrHJ04`e!CSzeIzgASu<7Erch4nT~MIAA8X#sVS zxOw8IX@GBV#RW>wf`LB81Ols0;_nOnv&xmU!V=w56co5^*#iz3epQpzx~OFIK1-l@ zlI{Xe1YFZM@(|NNKWqs4w0atEOp*pf?v!x*LD^|k<_Ag=qwJ$k9?eprAf~4o>Jd2>@w59aa3wm1~th32)p1fxqeAU+xpL*q;39-t7#eb zA=q{OPTV$WECyko?tg~5mD^feWSe=t*U9x2vxfnN&w$XAAKV<$+?Wqd8OHKc>qiJ} z@)ho&xvk)bB0a2TFjm^jQTgsHPZ=AO(~J^02fO!9(& zWG{@Nt%^e!Z$E`qAdtV<2+?;Z>BUKtQRIn@7G-{1i0XQK@3^-^KO2kW*WKB_&VOK>u^sAqd2uw9B@M zr<8x_TqhT5%LdItQr%mtJxry{yG+m(SH6Mty@^+$q*nKgZ%>_e-8FQNvzyN zJV?~6HzDB~?k}vAS6{Z1ts^8C&^%{{+Tbn^b-W5fgdcOupDuV)fa{k#Ulxt3`9B%O zh}}YE)OsbEua3ZF;yj-Q0(fuKKiU`AO^Jp(rhJ>8yM6hF8oKVyl|JNaTs|2zj%$!M zGJ#i{`B3Nl8pS>KIX)p47E z;)@e4yk9DM&Lfv}(zf6)HseI*?hgnOsVEO_ArM^}IDgk~Y7!g2+f<2nG^sd@@8*&I zk2O~kNd&Kt%SlPVCzX(bBW)7?ho{oH;#uA&tZF#-LQNm!$Op(pfgWZ;8c{p^l%(Mm zZ>HlUxS_A7A*R{imm&O6og_I!S@KPIQrJKpXhZJxOYcVSGv)(SofO?}+&bpDk|YdT z6s=ua28y8@#oz$m@6^`>2uB#$MDr>d#ei3wJcE}v*Dm>|_eEnP#RKC6E-Kc(B`PL|z3(J>q~m=?SQX9YiH znC=2=Uh+y8W!HzYN>Juf661M4%_HC?EChD?-U8@46!77qMz6sTzP82+&aU*==C#%O z4XlK+YJqfg#Jc!X3evOxs`~RBq9LCV$SY0Di2h{(^-AKIY+7oEzFK);`h^GBc$tJX z-XckCPyt$}ARM$_8R}svJ=D%2&Knwb7L>Re1_t)?eF25(-0>?)-Z8B6)D)af5EzuJ zkGDCu{!eIa0~43cDy5^IhS>GF zjbr;on4Z6&kNpMUJylFp_{)-7S?lzYKDN4}%*F1AsdBw{^t*kP#1s8D7t;(!$X?C! zcNni`-60(w&H@Rg^J`s!^Y+aBmak#T7{jJPzf`oA01;41^u+5gLhPy`TIw7bx^D-Q zs3cg#MR^N`o-6DKTt|#gi-a3vQ6=+UXqA~m(cI15Qok&aoKKcB7fL7n+$UxBnFM#jf z0(#6MG}c@|>^vI-Zs^3e`&Phh1d47*B&6euNkHC=>8JT%AIgA%jvdsgBm@c7BzBD% zBmrk~DJt;guf%{tMNMwQFqdOVa511#>i>6+A~d!Zvu;ohiw$zdW~d!`257YRmD-cx z*JXf@SRw^-m+T9JqQ#A}$k07ZmT?ZuLnJS9ogYqA#X;AprVDPSC(~Yr`KVsvZz%>W zE;?9)mc`tj^^6wW4|G?u3=&hxPjoA8%DoVm=pW)F)lLbK3Y#7=d+}e?0(#};{AYk^ zrnF)TAnEz$G1orMfD_qr3n?*(d?l?V(&TECe*X5j@8!WD(Q1S|fLRBrKajS}o~=OA fsDiubD>^YS$qu9N$SlpCCC`e_3y2ro(F~RFP literal 0 HcmV?d00001 diff --git a/frontend-web/Frontend/src/index.html b/frontend-web/Frontend/src/index.html new file mode 100644 index 000000000..3af61ec9b --- /dev/null +++ b/frontend-web/Frontend/src/index.html @@ -0,0 +1,13 @@ + + + + + Frontend + + + + + + + + diff --git a/frontend-web/Frontend/src/main.ts b/frontend-web/Frontend/src/main.ts new file mode 100644 index 000000000..35b00f346 --- /dev/null +++ b/frontend-web/Frontend/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig) + .catch((err) => console.error(err)); diff --git a/frontend-web/Frontend/src/styles.css b/frontend-web/Frontend/src/styles.css new file mode 100644 index 000000000..98f285d8d --- /dev/null +++ b/frontend-web/Frontend/src/styles.css @@ -0,0 +1,8 @@ +/* You can add global styles to this file, and also import other style files */ +@tailwind base; +@tailwind components; +@tailwind utilities; + +body{ + background-color: #111827; +} diff --git a/frontend-web/Frontend/tailwind.config.js b/frontend-web/Frontend/tailwind.config.js new file mode 100644 index 000000000..c9b8b4b2a --- /dev/null +++ b/frontend-web/Frontend/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./src/**/*.{html,js,ts,jsx,tsx}", + "./components/**/*.{html,js}", + ], + theme: { + extend: {}, + }, + plugins: [], +} + diff --git a/frontend-web/Frontend/tsconfig.app.json b/frontend-web/Frontend/tsconfig.app.json new file mode 100644 index 000000000..3775b37e3 --- /dev/null +++ b/frontend-web/Frontend/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/frontend-web/Frontend/tsconfig.json b/frontend-web/Frontend/tsconfig.json new file mode 100644 index 000000000..5525117c6 --- /dev/null +++ b/frontend-web/Frontend/tsconfig.json @@ -0,0 +1,27 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/frontend-web/Frontend/tsconfig.spec.json b/frontend-web/Frontend/tsconfig.spec.json new file mode 100644 index 000000000..5fb748d92 --- /dev/null +++ b/frontend-web/Frontend/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/logs/comments.log b/logs/comments.log new file mode 100644 index 000000000..e69de29bb diff --git a/logs/posts.log b/logs/posts.log new file mode 100644 index 000000000..e69de29bb diff --git a/logs/reviews.log b/logs/reviews.log new file mode 100644 index 000000000..e69de29bb